Merge branch 'next' of gitorious.org:fg/flightgear into next
This commit is contained in:
commit
9fa790bcac
201 changed files with 8647 additions and 4454 deletions
|
@ -151,11 +151,13 @@ if (MSVC AND MSVC_3RDPARTY_ROOT)
|
||||||
if (CMAKE_CL_64)
|
if (CMAKE_CL_64)
|
||||||
set( OSG_MSVC ${OSG_MSVC}-64 )
|
set( OSG_MSVC ${OSG_MSVC}-64 )
|
||||||
set( MSVC_3RDPARTY_DIR 3rdParty.x64 )
|
set( MSVC_3RDPARTY_DIR 3rdParty.x64 )
|
||||||
|
set( BOOST_LIB lib64 )
|
||||||
else (CMAKE_CL_64)
|
else (CMAKE_CL_64)
|
||||||
set( MSVC_3RDPARTY_DIR 3rdParty )
|
set( MSVC_3RDPARTY_DIR 3rdParty )
|
||||||
|
set( BOOST_LIB lib )
|
||||||
endif (CMAKE_CL_64)
|
endif (CMAKE_CL_64)
|
||||||
|
|
||||||
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}/SimGear/lib )
|
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}/SimGear/lib $(BOOST_ROOT)/$(BOOST_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}/SimGear/include)
|
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}/SimGear/include)
|
||||||
set (BOOST_ROOT ${MSVC_3RDPARTY_ROOT}/boost_1_44_0)
|
set (BOOST_ROOT ${MSVC_3RDPARTY_ROOT}/boost_1_44_0)
|
||||||
set (OPENAL_INCLUDE_DIR ${MSVC_3RDPARTY_ROOT}/${MSVC_3RDPARTY_DIR}/include)
|
set (OPENAL_INCLUDE_DIR ${MSVC_3RDPARTY_ROOT}/${MSVC_3RDPARTY_DIR}/include)
|
||||||
|
@ -252,19 +254,6 @@ check_include_file(unistd.h HAVE_UNISTD_H)
|
||||||
check_include_file(sys/time.h HAVE_SYS_TIME_H)
|
check_include_file(sys/time.h HAVE_SYS_TIME_H)
|
||||||
check_include_file(windows.h HAVE_WINDOWS_H)
|
check_include_file(windows.h HAVE_WINDOWS_H)
|
||||||
|
|
||||||
# definition depends on OSG version
|
|
||||||
set(CMAKE_REQUIRED_INCLUDES ${OPENSCENEGRAPH_INCLUDE_DIRS})
|
|
||||||
|
|
||||||
check_cxx_source_compiles(
|
|
||||||
"#include <osg/CullSettings>
|
|
||||||
int main()
|
|
||||||
{
|
|
||||||
osg::CullSettings::VariablesMask mask = osg::CullSettings::CLEAR_MASK;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
"
|
|
||||||
HAVE_CULLSETTINGS_CLEAR_MASK)
|
|
||||||
|
|
||||||
if(ENABLE_RTI)
|
if(ENABLE_RTI)
|
||||||
find_package(RTI)
|
find_package(RTI)
|
||||||
if(RTI_FOUND)
|
if(RTI_FOUND)
|
||||||
|
@ -273,11 +262,13 @@ if(ENABLE_RTI)
|
||||||
endif(ENABLE_RTI)
|
endif(ENABLE_RTI)
|
||||||
|
|
||||||
if(CMAKE_COMPILER_IS_GNUCXX)
|
if(CMAKE_COMPILER_IS_GNUCXX)
|
||||||
set(WARNING_FLAGS -Wall)
|
set(WARNING_FLAGS_CXX "-Wall")
|
||||||
|
set(WARNING_FLAGS_C "-Wall")
|
||||||
endif(CMAKE_COMPILER_IS_GNUCXX)
|
endif(CMAKE_COMPILER_IS_GNUCXX)
|
||||||
|
|
||||||
if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
|
if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
|
||||||
set (WARNING_FLAGS "-Wall -Wno-overloaded-virtual")
|
set (WARNING_FLAGS_CXX "-Wall -Wno-overloaded-virtual")
|
||||||
|
set (WARNING_FLAGS_C "-Wall")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
|
@ -297,8 +288,10 @@ if(WIN32)
|
||||||
set(NOMINMAX 1)
|
set(NOMINMAX 1)
|
||||||
endif(WIN32)
|
endif(WIN32)
|
||||||
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${WARNING_FLAGS} ${MSVC_FLAGS} -D_REENTRANT")
|
set (BOOST_CXX_FLAGS "-DBOOST_MULTI_INDEX_DISABLE_SERIALIZATION -DBOOST_BIMAP_DISABLE_SERIALIZATION")
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${WARNING_FLAGS} ${MSVC_FLAGS} -D_REENTRANT")
|
|
||||||
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${WARNING_FLAGS_C} ${MSVC_FLAGS} -D_REENTRANT")
|
||||||
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${WARNING_FLAGS_CXX} ${MSVC_FLAGS} -D_REENTRANT ${BOOST_CXX_FLAGS}")
|
||||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${MSVC_LD_FLAGS}")
|
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${MSVC_LD_FLAGS}")
|
||||||
|
|
||||||
include_directories(${OPENSCENEGRAPH_INCLUDE_DIRS}
|
include_directories(${OPENSCENEGRAPH_INCLUDE_DIRS}
|
||||||
|
|
|
@ -152,7 +152,6 @@ else(SIMGEAR_SHARED)
|
||||||
nasal
|
nasal
|
||||||
tsync
|
tsync
|
||||||
bucket
|
bucket
|
||||||
route
|
|
||||||
io
|
io
|
||||||
serial
|
serial
|
||||||
math
|
math
|
||||||
|
|
|
@ -285,12 +285,12 @@
|
||||||
</b>
|
</b>
|
||||||
<div class="indent">
|
<div class="indent">
|
||||||
<p>The latest development code is available for everyone through our
|
<p>The latest development code is available for everyone through our
|
||||||
CVS repository. See
|
git repository. See
|
||||||
<a href="http://flightgear.org/cvsResources/">http://flightgear.org/cvsResources/</a> for details.
|
<a href="http://wiki.flightgear.org/FlightGear_and_Git">http://wiki.flightgear.org/FlightGear_and_Git</a> for details.
|
||||||
</p>
|
</p>
|
||||||
<p>Otherwise, you can get relatively up-to-date snapshots of the
|
<p>Otherwise, you can get relatively up-to-date snapshots of the
|
||||||
development tree at
|
development tree at
|
||||||
<a href="ftp://flightgear.sourceforge.net/pub/flightgear/Devel/Snapshots/">ftp://flightgear.sourceforge.net/pub/flightgear/Devel/Snapshots/</a>.
|
<a href="http://flightgear.simpits.org:8080/">http://flightgear.simpits.org:8080/</a>, which are recompiled at every git commit.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
157
docs-mini/README.canvas
Normal file
157
docs-mini/README.canvas
Normal file
|
@ -0,0 +1,157 @@
|
||||||
|
Canvas - A 2D Drawing API
|
||||||
|
=========================
|
||||||
|
|
||||||
|
Author: Thomas Geymayer <admin@tomprogs.at>
|
||||||
|
Revision: 2012/05/04
|
||||||
|
|
||||||
|
Introduction
|
||||||
|
------------
|
||||||
|
|
||||||
|
With the increasing complexity of (glass) cockpits the need for a simple API to
|
||||||
|
draw on a 2D surface without modifying the C++ core increased heavily in the
|
||||||
|
last time. The 2D canvas is an effort to satisfy this needs. It is now possible
|
||||||
|
to create offscreen rendertargets only by using the property tree and placing
|
||||||
|
them on any 3D object on the aircraft by using certain filter criteria.
|
||||||
|
|
||||||
|
Currently it is only possible to place text on the canvas but 2d shapes (using
|
||||||
|
OpenVG) are going to follow.
|
||||||
|
|
||||||
|
Creating a canvas
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
A new canvas can be instantiated by creating a node /canvas/texture[<INDEX>]
|
||||||
|
with at least the following children:
|
||||||
|
|
||||||
|
<size-x type="int"> The width of the underlying texture
|
||||||
|
<size-y type="int"> The height of the underlying texture
|
||||||
|
|
||||||
|
<view-width type="int"> The width of the canvas
|
||||||
|
<view-height type="int"> The height of the canvas
|
||||||
|
|
||||||
|
The dimensions of the canvas are needed to be able to use textures with
|
||||||
|
different resolutions but use the same units for rendering to the canvas.
|
||||||
|
Therefore you can choose any texture size with the same canvas size and always
|
||||||
|
get the same results (apart from resolution dependent artifacts).
|
||||||
|
|
||||||
|
* Filtering:
|
||||||
|
|
||||||
|
Optionally you can enable mipmapping and/or multisampling (Coverage Sampling
|
||||||
|
Antialiasing):
|
||||||
|
|
||||||
|
<mipmapping type="bool"> Use mipmapping (default: false)
|
||||||
|
<coverage-samples type="int"> Coverage Samples (default: 0)
|
||||||
|
<color-samples type="int"> Color Samples (default: 0, always
|
||||||
|
have to be <= coverage-samples)
|
||||||
|
Drawing
|
||||||
|
-------
|
||||||
|
|
||||||
|
Drawing to the canvas is accomplished by creating nodes as childs of the
|
||||||
|
canvas root node. Every shape has to be a child of a <group> node. Currently
|
||||||
|
only drawing Text is possible:
|
||||||
|
|
||||||
|
* General:
|
||||||
|
The following parameters are used by multiple elements:
|
||||||
|
|
||||||
|
Color:
|
||||||
|
A color can be specified by the following subtree (NAME is replaced by
|
||||||
|
another name depending on the usage of the color)
|
||||||
|
|
||||||
|
<NAME>
|
||||||
|
<red type="float">
|
||||||
|
<green type="float">
|
||||||
|
<blue type="float">
|
||||||
|
</NAME>
|
||||||
|
|
||||||
|
* Text:
|
||||||
|
Create a <text> node and configure with the following properties:
|
||||||
|
|
||||||
|
<text type="string"> The text to be displayed
|
||||||
|
<font type="string"> The font to be used (Searched in
|
||||||
|
1. aircraft-dir/Fonts
|
||||||
|
2. aircraft-dir
|
||||||
|
3. $FG_DATA/Fonts
|
||||||
|
4. Default osg font paths
|
||||||
|
<size type="float"> The font size (default: 32)
|
||||||
|
<tf> A 3x3 transformation matrix specified by 6 values
|
||||||
|
(child elements <a>, ..., <f>) See
|
||||||
|
http://www.w3.org/TR/SVG/coords.html#TransformMatrixDefined
|
||||||
|
for details.
|
||||||
|
You can also use shortcuts and use an alternative to
|
||||||
|
specifying six values:
|
||||||
|
- Translation: <tx>, <ty> (ty, ty default to 0)
|
||||||
|
- Totation: <rot>
|
||||||
|
- Scale: <sx>, <sy> (sx is required, sy defaults to sx)
|
||||||
|
<alginment type="string"> Text alignment (default: "left-baseline") One of:
|
||||||
|
|
||||||
|
"left-top"
|
||||||
|
"left-center"
|
||||||
|
"left-bottom"
|
||||||
|
|
||||||
|
"center-top"
|
||||||
|
"center-center"
|
||||||
|
"center-bottom"
|
||||||
|
|
||||||
|
"right-top"
|
||||||
|
"right-center"
|
||||||
|
"right-bottom"
|
||||||
|
|
||||||
|
"left-baseline"
|
||||||
|
"center-baseline"
|
||||||
|
"right-baseline"
|
||||||
|
|
||||||
|
"left-bottom-baseline"
|
||||||
|
"center-bottom-baseline"
|
||||||
|
"right-bottom-baseline"
|
||||||
|
<draw-mode type="int"> A bitwise combination of the following values
|
||||||
|
1 (Text - default)
|
||||||
|
2 (Boundingbox)
|
||||||
|
4 (Filled boundingbox)
|
||||||
|
8 (Alignment -> Draw a cross at the position
|
||||||
|
of the text)
|
||||||
|
<padding type="float"> Padding between for the boundingbox (default: 0)
|
||||||
|
<color> Text color
|
||||||
|
<color-fill> Fill color (for the bounding box)
|
||||||
|
|
||||||
|
Placement
|
||||||
|
---------
|
||||||
|
|
||||||
|
To place the canvas into the scene one ore more <placement> elements can be
|
||||||
|
added to the texture node. By setting at least on of the following nodes
|
||||||
|
the objects where the canvas texture should be placed on are selected:
|
||||||
|
|
||||||
|
<texture type="string"> Match objects with the given texture assigned
|
||||||
|
<node type="string"> Match objects with the given name
|
||||||
|
<parent type="string"> Match objects with a parent matching the given name
|
||||||
|
(Not necessarily the direct parent)
|
||||||
|
|
||||||
|
Example
|
||||||
|
-------
|
||||||
|
|
||||||
|
<canvas>
|
||||||
|
<texture>
|
||||||
|
<size-x type="int">384</size-x>
|
||||||
|
<size-y type="int">512</size-y>
|
||||||
|
<view-width type="int">768</view-width>
|
||||||
|
<view-height type="int">1024</view-height>
|
||||||
|
<mipmapping type="bool">false</mipmapping>
|
||||||
|
<coverage-samples type="int">0</coverage-samples>
|
||||||
|
<color-samples type="int">0</color-samples>
|
||||||
|
<group>
|
||||||
|
<text>
|
||||||
|
<text type="string">TEST MESSAGE</text>
|
||||||
|
<font type="string">helvetica_bold.txf</font>
|
||||||
|
<tf>
|
||||||
|
<!-- Translate (18|50) -->
|
||||||
|
<tx>18</tx>
|
||||||
|
<ty>50</ty>
|
||||||
|
</tf>
|
||||||
|
</text>
|
||||||
|
</group>
|
||||||
|
<placement>
|
||||||
|
<!-- Place on objects with the texture EICAS.png
|
||||||
|
and a parent called HDD 1 -->
|
||||||
|
<texture type="string">EICAS.png</texture>
|
||||||
|
<parent type="string">HDD 1</parent>
|
||||||
|
</placement>
|
||||||
|
</texture>
|
||||||
|
</canvas>
|
|
@ -11,7 +11,7 @@ fi
|
||||||
if [ "x$2" != "x" ]; then
|
if [ "x$2" != "x" ]; then
|
||||||
VERSION="$2"
|
VERSION="$2"
|
||||||
else
|
else
|
||||||
VERSION="2.5"
|
VERSION="2.7"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo base dir = $BASE, version = $VERSION
|
echo base dir = $BASE, version = $VERSION
|
||||||
|
@ -41,6 +41,7 @@ tar \
|
||||||
data/Aircraft/Instruments-3d \
|
data/Aircraft/Instruments-3d \
|
||||||
data/Aircraft/UIUC \
|
data/Aircraft/UIUC \
|
||||||
data/Aircraft/777 \
|
data/Aircraft/777 \
|
||||||
|
data/Aircraft/777-200 \
|
||||||
data/Aircraft/A6M2 \
|
data/Aircraft/A6M2 \
|
||||||
data/Aircraft/ASK13 \
|
data/Aircraft/ASK13 \
|
||||||
data/Aircraft/b1900d \
|
data/Aircraft/b1900d \
|
||||||
|
|
|
@ -22,7 +22,6 @@
|
||||||
# include <config.h>
|
# include <config.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <simgear/route/waypoint.hxx>
|
|
||||||
#include <Main/fg_props.hxx>
|
#include <Main/fg_props.hxx>
|
||||||
#include <Main/globals.hxx>
|
#include <Main/globals.hxx>
|
||||||
#include <Viewer/viewer.hxx>
|
#include <Viewer/viewer.hxx>
|
||||||
|
|
|
@ -34,7 +34,6 @@
|
||||||
#include <osg/Node>
|
#include <osg/Node>
|
||||||
#include <osgDB/FileUtils>
|
#include <osgDB/FileUtils>
|
||||||
|
|
||||||
#include <simgear/math/SGMath.hxx>
|
|
||||||
#include <simgear/misc/sg_path.hxx>
|
#include <simgear/misc/sg_path.hxx>
|
||||||
#include <simgear/scene/model/modellib.hxx>
|
#include <simgear/scene/model/modellib.hxx>
|
||||||
#include <simgear/scene/util/SGNodeMasks.hxx>
|
#include <simgear/scene/util/SGNodeMasks.hxx>
|
||||||
|
|
|
@ -23,7 +23,6 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include <simgear/constants.h>
|
#include <simgear/constants.h>
|
||||||
#include <simgear/math/SGMath.hxx>
|
|
||||||
#include <simgear/scene/model/placement.hxx>
|
#include <simgear/scene/model/placement.hxx>
|
||||||
#include <simgear/scene/model/modellib.hxx>
|
#include <simgear/scene/model/modellib.hxx>
|
||||||
#include <simgear/misc/sg_path.hxx>
|
#include <simgear/misc/sg_path.hxx>
|
||||||
|
|
|
@ -26,7 +26,6 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include <simgear/sg_inlines.h>
|
#include <simgear/sg_inlines.h>
|
||||||
#include <simgear/math/SGMath.hxx>
|
|
||||||
#include <simgear/math/sg_geodesy.hxx>
|
#include <simgear/math/sg_geodesy.hxx>
|
||||||
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
|
@ -27,7 +27,6 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include <simgear/sg_inlines.h>
|
#include <simgear/sg_inlines.h>
|
||||||
#include <simgear/math/SGMath.hxx>
|
|
||||||
#include <simgear/math/sg_geodesy.hxx>
|
#include <simgear/math/sg_geodesy.hxx>
|
||||||
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
|
@ -24,7 +24,6 @@
|
||||||
|
|
||||||
#include <simgear/misc/sg_path.hxx>
|
#include <simgear/misc/sg_path.hxx>
|
||||||
#include <simgear/debug/logstream.hxx>
|
#include <simgear/debug/logstream.hxx>
|
||||||
#include <simgear/route/waypoint.hxx>
|
|
||||||
#include <simgear/math/sg_geodesy.hxx>
|
#include <simgear/math/sg_geodesy.hxx>
|
||||||
#include <simgear/structure/exception.hxx>
|
#include <simgear/structure/exception.hxx>
|
||||||
#include <simgear/constants.h>
|
#include <simgear/constants.h>
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
//
|
//
|
||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with this program; if not, write to the Free Software
|
// along with this program; if not, write to the Free Software
|
||||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
#ifndef _FG_AIFLIGHTPLAN_HXX
|
#ifndef _FG_AIFLIGHTPLAN_HXX
|
||||||
#define _FG_AIFLIGHTPLAN_HXX
|
#define _FG_AIFLIGHTPLAN_HXX
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
# include <config.h>
|
# include <config.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <cstdlib>
|
||||||
|
|
||||||
#include "AIFlightPlan.hxx"
|
#include "AIFlightPlan.hxx"
|
||||||
#include <simgear/math/sg_geodesy.hxx>
|
#include <simgear/math/sg_geodesy.hxx>
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
@ -25,7 +25,6 @@
|
||||||
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <simgear/route/waypoint.hxx>
|
|
||||||
|
|
||||||
#include <Airports/simple.hxx>
|
#include <Airports/simple.hxx>
|
||||||
#include <Airports/runways.hxx>
|
#include <Airports/runways.hxx>
|
||||||
|
|
|
@ -22,6 +22,8 @@
|
||||||
# include <config.h>
|
# include <config.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <cstdlib>
|
||||||
|
|
||||||
#include <simgear/math/sg_geodesy.hxx>
|
#include <simgear/math/sg_geodesy.hxx>
|
||||||
|
|
||||||
#include <Airports/simple.hxx>
|
#include <Airports/simple.hxx>
|
||||||
|
|
|
@ -69,10 +69,7 @@ void
|
||||||
FGAIManager::init() {
|
FGAIManager::init() {
|
||||||
root = fgGetNode("sim/ai", true);
|
root = fgGetNode("sim/ai", true);
|
||||||
|
|
||||||
enabled = root->getNode("enabled", true)->getBoolValue();
|
enabled = root->getNode("enabled", true);
|
||||||
|
|
||||||
if (!enabled)
|
|
||||||
return;
|
|
||||||
|
|
||||||
thermal_lift_node = fgGetNode("/environment/thermal-lift-fps", true);
|
thermal_lift_node = fgGetNode("/environment/thermal-lift-fps", true);
|
||||||
wind_from_east_node = fgGetNode("/environment/wind-from-east-fps",true);
|
wind_from_east_node = fgGetNode("/environment/wind-from-east-fps",true);
|
||||||
|
@ -92,6 +89,15 @@ FGAIManager::init() {
|
||||||
void
|
void
|
||||||
FGAIManager::postinit() {
|
FGAIManager::postinit() {
|
||||||
// postinit, so that it can access the Nasal subsystem
|
// postinit, so that it can access the Nasal subsystem
|
||||||
|
|
||||||
|
if (!root->getBoolValue("scenarios-enabled", true))
|
||||||
|
return;
|
||||||
|
|
||||||
|
// scenarios enabled, AI subsystem required
|
||||||
|
if (!enabled->getBoolValue())
|
||||||
|
enabled->setBoolValue(true);
|
||||||
|
|
||||||
|
// process all scenarios
|
||||||
map<string, bool> scenarios;
|
map<string, bool> scenarios;
|
||||||
for (int i = 0 ; i < root->nChildren() ; i++) {
|
for (int i = 0 ; i < root->nChildren() ; i++) {
|
||||||
SGPropertyNode *n = root->getChild(i);
|
SGPropertyNode *n = root->getChild(i);
|
||||||
|
@ -143,7 +149,7 @@ FGAIManager::update(double dt) {
|
||||||
range_nearest = 10000.0;
|
range_nearest = 10000.0;
|
||||||
strength = 0.0;
|
strength = 0.0;
|
||||||
|
|
||||||
if (!enabled)
|
if (!enabled->getBoolValue())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
FGTrafficManager *tmgr = (FGTrafficManager*) globals->get_subsystem("traffic-manager");
|
FGTrafficManager *tmgr = (FGTrafficManager*) globals->get_subsystem("traffic-manager");
|
||||||
|
|
|
@ -96,13 +96,13 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
bool enabled;
|
|
||||||
int mNumAiTypeModels[FGAIBase::MAX_OBJECTS];
|
int mNumAiTypeModels[FGAIBase::MAX_OBJECTS];
|
||||||
int mNumAiModels;
|
int mNumAiModels;
|
||||||
|
|
||||||
double calcRange(double lat, double lon, double lat2, double lon2)const;
|
double calcRange(double lat, double lon, double lat2, double lon2)const;
|
||||||
|
|
||||||
SGPropertyNode_ptr root;
|
SGPropertyNode_ptr root;
|
||||||
|
SGPropertyNode_ptr enabled;
|
||||||
SGPropertyNode_ptr thermal_lift_node;
|
SGPropertyNode_ptr thermal_lift_node;
|
||||||
SGPropertyNode_ptr user_latitude_node;
|
SGPropertyNode_ptr user_latitude_node;
|
||||||
SGPropertyNode_ptr user_longitude_node;
|
SGPropertyNode_ptr user_longitude_node;
|
||||||
|
|
|
@ -22,7 +22,6 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <simgear/sg_inlines.h>
|
#include <simgear/sg_inlines.h>
|
||||||
#include <simgear/math/SGMath.hxx>
|
|
||||||
|
|
||||||
|
|
||||||
#include "AIWingman.hxx"
|
#include "AIWingman.hxx"
|
||||||
|
|
|
@ -26,7 +26,6 @@
|
||||||
#include "AIBase.hxx"
|
#include "AIBase.hxx"
|
||||||
|
|
||||||
#include <simgear/sg_inlines.h>
|
#include <simgear/sg_inlines.h>
|
||||||
#include <simgear/math/SGMath.hxx>
|
|
||||||
|
|
||||||
|
|
||||||
class FGAIWingman : public FGAIBallistic {
|
class FGAIWingman : public FGAIBallistic {
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
#include <simgear/math/SGMath.hxx>
|
|
||||||
#include <simgear/misc/sg_path.hxx>
|
#include <simgear/misc/sg_path.hxx>
|
||||||
#include <simgear/props/props.hxx>
|
#include <simgear/props/props.hxx>
|
||||||
#include <simgear/props/props_io.hxx>
|
#include <simgear/props/props_io.hxx>
|
||||||
|
|
|
@ -26,7 +26,6 @@
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
#include <simgear/math/SGMath.hxx>
|
|
||||||
#include <Airports/dynamics.hxx>
|
#include <Airports/dynamics.hxx>
|
||||||
#include <Airports/simple.hxx>
|
#include <Airports/simple.hxx>
|
||||||
#include <Scenery/scenery.hxx>
|
#include <Scenery/scenery.hxx>
|
||||||
|
|
|
@ -45,8 +45,6 @@
|
||||||
#include <ATC/CommStation.hxx>
|
#include <ATC/CommStation.hxx>
|
||||||
|
|
||||||
|
|
||||||
FGATCDialogNew *currentATCDialog;
|
|
||||||
|
|
||||||
static SGPropertyNode *getNamedNode(SGPropertyNode *prop, const char *name)
|
static SGPropertyNode *getNamedNode(SGPropertyNode *prop, const char *name)
|
||||||
{
|
{
|
||||||
SGPropertyNode* p;
|
SGPropertyNode* p;
|
||||||
|
|
|
@ -273,8 +273,8 @@ int FGTrafficRecord::crosses(FGGroundNetwork * net,
|
||||||
if (intentions.size()) {
|
if (intentions.size()) {
|
||||||
for (i = intentions.begin(); i != intentions.end(); i++) {
|
for (i = intentions.begin(); i != intentions.end(); i++) {
|
||||||
if ((*i) > 0) {
|
if ((*i) > 0) {
|
||||||
if ((currentTargetNode ==
|
if (currentTargetNode ==
|
||||||
net->findSegment(*i)->getEnd()->getIndex())) {
|
net->findSegment(*i)->getEnd()->getIndex()) {
|
||||||
//cerr << "Current crosses at " << currentTargetNode <<endl;
|
//cerr << "Current crosses at " << currentTargetNode <<endl;
|
||||||
return currentTargetNode;
|
return currentTargetNode;
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,166 +35,101 @@
|
||||||
#include <Airports/simple.hxx>
|
#include <Airports/simple.hxx>
|
||||||
|
|
||||||
FGATC::FGATC() :
|
FGATC::FGATC() :
|
||||||
_playing(false),
|
freq(0),
|
||||||
_voiceOK(false),
|
_currentStation(NULL),
|
||||||
_sgr(NULL),
|
range(0),
|
||||||
freqClear(true),
|
_voice(true),
|
||||||
receiving(false),
|
_playing(false),
|
||||||
respond(false),
|
_sgr(NULL),
|
||||||
responseID(""),
|
_type(INVALID),
|
||||||
runResponseCounter(false),
|
_display(false)
|
||||||
_runReleaseCounter(false),
|
#ifdef OLD_ATC_MGR
|
||||||
responseReqd(false),
|
,freqClear(true),
|
||||||
_type(INVALID),
|
receiving(false),
|
||||||
_display(false),
|
respond(false),
|
||||||
// Transmission timing stuff
|
responseID(""),
|
||||||
pending_transmission(""),
|
runResponseCounter(false),
|
||||||
_timeout(0),
|
_runReleaseCounter(false),
|
||||||
_pending(false),
|
responseReqd(false),
|
||||||
_transmit(false),
|
// Transmission timing stuff
|
||||||
_transmitting(false),
|
pending_transmission(""),
|
||||||
_counter(0.0),
|
_timeout(0),
|
||||||
_max_count(5.0)
|
_pending(false),
|
||||||
|
_transmit(false),
|
||||||
|
_transmitting(false),
|
||||||
|
_counter(0.0),
|
||||||
|
_max_count(5.0)
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
SGSoundMgr *smgr = globals->get_soundmgr();
|
SGSoundMgr *smgr = globals->get_soundmgr();
|
||||||
_sgr = smgr->find("atc", true);
|
_sgr = smgr->find("atc", true);
|
||||||
_sgr->tie_to_listener();
|
_sgr->tie_to_listener();
|
||||||
|
|
||||||
_volume = fgGetNode("/sim/sound/atc/volume", true);
|
_masterVolume = fgGetNode("/sim/sound/atc/volume", true);
|
||||||
_enabled = fgGetNode("/sim/sound/atc/enabled", true);
|
_enabled = fgGetNode("/sim/sound/atc/enabled", true);
|
||||||
_atc_external = fgGetNode("/sim/sound/atc/external-view", true);
|
_atc_external = fgGetNode("/sim/sound/atc/external-view", true);
|
||||||
_internal = fgGetNode("/sim/current-view/internal", true);
|
_internal = fgGetNode("/sim/current-view/internal", true);
|
||||||
}
|
}
|
||||||
|
|
||||||
FGATC::~FGATC() {
|
FGATC::~FGATC() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef OLD_ATC_MGR
|
||||||
// Derived classes wishing to use the response counter should
|
// Derived classes wishing to use the response counter should
|
||||||
// call this from their own Update(...).
|
// call this from their own Update(...).
|
||||||
void FGATC::Update(double dt) {
|
void FGATC::Update(double dt) {
|
||||||
if(runResponseCounter) {
|
|
||||||
//cout << responseCounter << '\t' << responseTime << '\n';
|
|
||||||
if(responseCounter >= responseTime) {
|
|
||||||
runResponseCounter = false;
|
|
||||||
respond = true;
|
|
||||||
//cout << "RESPOND\n";
|
|
||||||
} else {
|
|
||||||
responseCounter += dt;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(_runReleaseCounter) {
|
|
||||||
if(_releaseCounter >= _releaseTime) {
|
|
||||||
freqClear = true;
|
|
||||||
_runReleaseCounter = false;
|
|
||||||
} else {
|
|
||||||
_releaseCounter += dt;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Transmission stuff cribbed from AIPlane.cxx
|
|
||||||
if(_pending) {
|
|
||||||
if(GetFreqClear()) {
|
|
||||||
//cout << "TUNED STATION FREQ CLEAR\n";
|
|
||||||
SetFreqInUse();
|
|
||||||
_pending = false;
|
|
||||||
_transmit = true;
|
|
||||||
_transmitting = false;
|
|
||||||
} else {
|
|
||||||
if(_timeout > 0.0) { // allows count down to be avoided by initially setting it to zero
|
|
||||||
_timeout -= dt;
|
|
||||||
if(_timeout <= 0.0) {
|
|
||||||
_timeout = 0.0;
|
|
||||||
_pending = false;
|
|
||||||
// timed out - don't render.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef ENABLE_AUDIO_SUPPORT
|
#ifdef ENABLE_AUDIO_SUPPORT
|
||||||
bool active = _atc_external->getBoolValue() ||
|
bool active = _atc_external->getBoolValue() ||
|
||||||
_internal->getBoolValue();
|
_internal->getBoolValue();
|
||||||
|
|
||||||
if ( active && _enabled->getBoolValue() ) {
|
if ( active && _enabled->getBoolValue() ) {
|
||||||
_sgr->set_volume( _volume->getFloatValue() );
|
_sgr->set_volume( _masterVolume->getFloatValue() );
|
||||||
_sgr->resume(); // no-op if already in resumed state
|
_sgr->resume(); // no-op if already in resumed state
|
||||||
} else {
|
} else {
|
||||||
_sgr->suspend();
|
_sgr->suspend();
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if(_transmit) {
|
|
||||||
_counter = 0.0;
|
|
||||||
_max_count = 5.0; // FIXME - hardwired length of message - need to calculate it!
|
|
||||||
|
|
||||||
//cout << "Transmission = " << pending_transmission << '\n';
|
|
||||||
if(_display) {
|
|
||||||
//Render(pending_transmission, ident, false);
|
|
||||||
Render(pending_transmission);
|
|
||||||
}
|
|
||||||
_transmit = false;
|
|
||||||
_transmitting = true;
|
|
||||||
} else if(_transmitting) {
|
|
||||||
if(_counter >= _max_count) {
|
|
||||||
//NoRender(plane.callsign); commented out since at the moment NoRender is designed just to stop repeating messages,
|
|
||||||
// and this will be primarily used on single messages.
|
|
||||||
_transmitting = false;
|
|
||||||
//if(tuned_station) tuned_station->NotifyTransmissionFinished(plane.callsign);
|
|
||||||
// TODO - need to let the plane the transmission is aimed at that it's finished.
|
|
||||||
// However, for now we'll just release the frequency since if we don't it all goes pear-shaped
|
|
||||||
_releaseCounter = 0.0;
|
|
||||||
_releaseTime = 0.9;
|
|
||||||
_runReleaseCounter = true;
|
|
||||||
}
|
|
||||||
_counter += dt;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void FGATC::ReceiveUserCallback(int code) {
|
|
||||||
SG_LOG(SG_ATC, SG_WARN, "WARNING - whichever ATC class was intended to receive callback code " << code << " didn't get it!!!");
|
|
||||||
}
|
|
||||||
|
|
||||||
void FGATC::SetResponseReqd(const string& rid) {
|
|
||||||
receiving = false;
|
|
||||||
responseReqd = true;
|
|
||||||
respond = false; // TODO - this ignores the fact that more than one plane could call this before response
|
|
||||||
// Shouldn't happen with AI only, but user could confuse things??
|
|
||||||
responseID = rid;
|
|
||||||
runResponseCounter = true;
|
|
||||||
responseCounter = 0.0;
|
|
||||||
responseTime = 1.8; // TODO - randomize this slightly.
|
|
||||||
}
|
|
||||||
|
|
||||||
void FGATC::NotifyTransmissionFinished(const string& rid) {
|
|
||||||
//cout << "Transmission finished, callsign = " << rid << '\n';
|
|
||||||
receiving = false;
|
|
||||||
responseID = rid;
|
|
||||||
if(responseReqd) {
|
|
||||||
runResponseCounter = true;
|
|
||||||
responseCounter = 0.0;
|
|
||||||
responseTime = 1.2; // TODO - randomize this slightly, and allow it to be dependent on the transmission and how busy the ATC is.
|
|
||||||
respond = false; // TODO - this ignores the fact that more than one plane could call this before response
|
|
||||||
// Shouldn't happen with AI only, but user could confuse things??
|
|
||||||
} else {
|
|
||||||
freqClear = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void FGATC::SetStation(flightgear::CommStation* sta) {
|
void FGATC::SetStation(flightgear::CommStation* sta) {
|
||||||
switch (sta->type()) {
|
if (_currentStation == sta)
|
||||||
case FGPositioned::FREQ_ATIS: _type = ATIS; break;
|
return;
|
||||||
case FGPositioned::FREQ_AWOS: _type = AWOS; break;
|
_currentStation = sta;
|
||||||
default:
|
|
||||||
throw sg_exception("unsupported comm station type");
|
if (sta)
|
||||||
|
{
|
||||||
|
switch (sta->type()) {
|
||||||
|
case FGPositioned::FREQ_ATIS: _type = ATIS; break;
|
||||||
|
case FGPositioned::FREQ_AWOS: _type = AWOS; break;
|
||||||
|
default:
|
||||||
|
sta = NULL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_geod = sta->geod();
|
if (sta == NULL)
|
||||||
_cart = sta->cart();
|
{
|
||||||
range = sta->rangeNm();
|
range = 0;
|
||||||
ident = sta->airport()->ident();
|
ident = "";
|
||||||
name = sta->airport()->name();
|
name = "";
|
||||||
freq = sta->freqKHz();
|
freq = 0;
|
||||||
|
|
||||||
|
SetNoDisplay();
|
||||||
|
Update(0); // one last update
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_geod = sta->geod();
|
||||||
|
_cart = sta->cart();
|
||||||
|
|
||||||
|
range = sta->rangeNm();
|
||||||
|
ident = sta->airport()->ident();
|
||||||
|
name = sta->airport()->name();
|
||||||
|
freq = sta->freqKHz();
|
||||||
|
SetDisplay();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Render a transmission
|
// Render a transmission
|
||||||
|
@ -202,134 +137,272 @@ void FGATC::SetStation(flightgear::CommStation* sta) {
|
||||||
// The refname is a string to identify this sample to the sound manager
|
// The refname is a string to identify this sample to the sound manager
|
||||||
// The repeating flag indicates whether the message should be repeated continuously or played once.
|
// The repeating flag indicates whether the message should be repeated continuously or played once.
|
||||||
void FGATC::Render(string& msg, const float volume,
|
void FGATC::Render(string& msg, const float volume,
|
||||||
const string& refname, const bool repeating) {
|
const string& refname, const bool repeating) {
|
||||||
if (volume < 0.05) return;
|
if ((!_display) ||(volume < 0.05))
|
||||||
|
{
|
||||||
|
NoRender(refname);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (repeating)
|
if (repeating)
|
||||||
fgSetString("/sim/messages/atis", msg.c_str());
|
fgSetString("/sim/messages/atis", msg.c_str());
|
||||||
else
|
else
|
||||||
fgSetString("/sim/messages/atc", msg.c_str());
|
fgSetString("/sim/messages/atc", msg.c_str());
|
||||||
|
|
||||||
#ifdef ENABLE_AUDIO_SUPPORT
|
#ifdef ENABLE_AUDIO_SUPPORT
|
||||||
_voice = (_voiceOK && fgGetBool("/sim/sound/voice"));
|
bool useVoice = _voice && fgGetBool("/sim/sound/voice") && fgGetBool("/sim/sound/atc/enabled");
|
||||||
if(_voice) {
|
SGSoundSample *simple = _sgr->find(refname);
|
||||||
size_t len;
|
if(useVoice) {
|
||||||
void* buf = _vPtr->WriteMessage((char*)msg.c_str(), &len);
|
if (simple && (_currentMsg == msg))
|
||||||
if(buf) {
|
{
|
||||||
NoRender(refname);
|
simple->set_volume(volume);
|
||||||
try {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_currentMsg = msg;
|
||||||
|
size_t len;
|
||||||
|
void* buf = NULL;
|
||||||
|
if (!_vPtr)
|
||||||
|
_vPtr = GetVoicePointer();
|
||||||
|
if (_vPtr)
|
||||||
|
buf = _vPtr->WriteMessage((char*)msg.c_str(), &len);
|
||||||
|
NoRender(refname);
|
||||||
|
if(buf) {
|
||||||
|
try {
|
||||||
// >>> Beware: must pass a (new) object to the (add) method,
|
// >>> Beware: must pass a (new) object to the (add) method,
|
||||||
// >>> because the (remove) method is going to do a (delete)
|
// >>> because the (remove) method is going to do a (delete)
|
||||||
// >>> whether that's what you want or not.
|
// >>> whether that's what you want or not.
|
||||||
SGSoundSample *simple = new SGSoundSample(&buf, len, 8000);
|
simple = new SGSoundSample(&buf, len, 8000);
|
||||||
simple->set_volume(volume);
|
simple->set_volume(volume);
|
||||||
_sgr->add(simple, refname);
|
_sgr->add(simple, refname);
|
||||||
_sgr->play(refname, repeating);
|
_sgr->play(refname, repeating);
|
||||||
} catch ( sg_io_exception &e ) {
|
} catch ( sg_io_exception &e ) {
|
||||||
SG_LOG(SG_ATC, SG_ALERT, e.getFormattedMessage());
|
SG_LOG(SG_ATC, SG_ALERT, e.getFormattedMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif // ENABLE_AUDIO_SUPPORT
|
}
|
||||||
if(!_voice) {
|
else
|
||||||
// first rip the underscores and the pause hints out of the string - these are for the convienience of the voice parser
|
if (simple)
|
||||||
for(unsigned int i = 0; i < msg.length(); ++i) {
|
{
|
||||||
if((msg.substr(i,1) == "_") || (msg.substr(i,1) == "/")) {
|
NoRender(refname);
|
||||||
msg[i] = ' ';
|
}
|
||||||
}
|
#endif // ENABLE_AUDIO_SUPPORT
|
||||||
}
|
|
||||||
}
|
if (!useVoice)
|
||||||
_playing = true;
|
{
|
||||||
|
// first rip the underscores and the pause hints out of the string - these are for the convenience of the voice parser
|
||||||
|
for(unsigned int i = 0; i < msg.length(); ++i) {
|
||||||
|
if((msg.substr(i,1) == "_") || (msg.substr(i,1) == "/")) {
|
||||||
|
msg[i] = ' ';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_playing = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Cease rendering a transmission.
|
// Cease rendering a transmission.
|
||||||
void FGATC::NoRender(const string& refname) {
|
void FGATC::NoRender(const string& refname) {
|
||||||
if(_playing) {
|
if(_playing) {
|
||||||
if(_voice) {
|
if(_voice) {
|
||||||
#ifdef ENABLE_AUDIO_SUPPORT
|
#ifdef ENABLE_AUDIO_SUPPORT
|
||||||
_sgr->stop(refname);
|
_sgr->stop(refname);
|
||||||
_sgr->remove(refname);
|
_sgr->remove(refname);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
_playing = false;
|
_playing = false;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef OLD_ATC_MGR
|
||||||
|
// Derived classes wishing to use the response counter should
|
||||||
|
// call this from their own Update(...).
|
||||||
|
void FGATC::Update(double dt) {
|
||||||
|
|
||||||
|
#ifdef ENABLE_AUDIO_SUPPORT
|
||||||
|
bool active = _atc_external->getBoolValue() ||
|
||||||
|
_internal->getBoolValue();
|
||||||
|
|
||||||
|
if ( active && _enabled->getBoolValue() ) {
|
||||||
|
_sgr->set_volume( _masterVolume->getFloatValue() );
|
||||||
|
_sgr->resume(); // no-op if already in resumed state
|
||||||
|
} else {
|
||||||
|
_sgr->suspend();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if(runResponseCounter) {
|
||||||
|
//cout << responseCounter << '\t' << responseTime << '\n';
|
||||||
|
if(responseCounter >= responseTime) {
|
||||||
|
runResponseCounter = false;
|
||||||
|
respond = true;
|
||||||
|
//cout << "RESPOND\n";
|
||||||
|
} else {
|
||||||
|
responseCounter += dt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(_runReleaseCounter) {
|
||||||
|
if(_releaseCounter >= _releaseTime) {
|
||||||
|
freqClear = true;
|
||||||
|
_runReleaseCounter = false;
|
||||||
|
} else {
|
||||||
|
_releaseCounter += dt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Transmission stuff cribbed from AIPlane.cxx
|
||||||
|
if(_pending) {
|
||||||
|
if(GetFreqClear()) {
|
||||||
|
//cout << "TUNED STATION FREQ CLEAR\n";
|
||||||
|
SetFreqInUse();
|
||||||
|
_pending = false;
|
||||||
|
_transmit = true;
|
||||||
|
_transmitting = false;
|
||||||
|
} else {
|
||||||
|
if(_timeout > 0.0) { // allows count down to be avoided by initially setting it to zero
|
||||||
|
_timeout -= dt;
|
||||||
|
if(_timeout <= 0.0) {
|
||||||
|
_timeout = 0.0;
|
||||||
|
_pending = false;
|
||||||
|
// timed out - don't render.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(_transmit) {
|
||||||
|
_counter = 0.0;
|
||||||
|
_max_count = 5.0; // FIXME - hardwired length of message - need to calculate it!
|
||||||
|
|
||||||
|
//cout << "Transmission = " << pending_transmission << '\n';
|
||||||
|
if(_display) {
|
||||||
|
//Render(pending_transmission, ident, false);
|
||||||
|
Render(pending_transmission);
|
||||||
|
}
|
||||||
|
_transmit = false;
|
||||||
|
_transmitting = true;
|
||||||
|
} else if(_transmitting) {
|
||||||
|
if(_counter >= _max_count) {
|
||||||
|
//NoRender(plane.callsign); commented out since at the moment NoRender is designed just to stop repeating messages,
|
||||||
|
// and this will be primarily used on single messages.
|
||||||
|
_transmitting = false;
|
||||||
|
//if(tuned_station) tuned_station->NotifyTransmissionFinished(plane.callsign);
|
||||||
|
// TODO - need to let the plane the transmission is aimed at that it's finished.
|
||||||
|
// However, for now we'll just release the frequency since if we don't it all goes pear-shaped
|
||||||
|
_releaseCounter = 0.0;
|
||||||
|
_releaseTime = 0.9;
|
||||||
|
_runReleaseCounter = true;
|
||||||
|
}
|
||||||
|
_counter += dt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FGATC::ReceiveUserCallback(int code) {
|
||||||
|
SG_LOG(SG_ATC, SG_WARN, "WARNING - whichever ATC class was intended to receive callback code " << code << " didn't get it!!!");
|
||||||
|
}
|
||||||
|
|
||||||
|
void FGATC::SetResponseReqd(const string& rid) {
|
||||||
|
receiving = false;
|
||||||
|
responseReqd = true;
|
||||||
|
respond = false; // TODO - this ignores the fact that more than one plane could call this before response
|
||||||
|
// Shouldn't happen with AI only, but user could confuse things??
|
||||||
|
responseID = rid;
|
||||||
|
runResponseCounter = true;
|
||||||
|
responseCounter = 0.0;
|
||||||
|
responseTime = 1.8; // TODO - randomize this slightly.
|
||||||
|
}
|
||||||
|
|
||||||
|
void FGATC::NotifyTransmissionFinished(const string& rid) {
|
||||||
|
//cout << "Transmission finished, callsign = " << rid << '\n';
|
||||||
|
receiving = false;
|
||||||
|
responseID = rid;
|
||||||
|
if(responseReqd) {
|
||||||
|
runResponseCounter = true;
|
||||||
|
responseCounter = 0.0;
|
||||||
|
responseTime = 1.2; // TODO - randomize this slightly, and allow it to be dependent on the transmission and how busy the ATC is.
|
||||||
|
respond = false; // TODO - this ignores the fact that more than one plane could call this before response
|
||||||
|
// Shouldn't happen with AI only, but user could confuse things??
|
||||||
|
} else {
|
||||||
|
freqClear = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate the text of a message from its parameters and the current context.
|
// Generate the text of a message from its parameters and the current context.
|
||||||
string FGATC::GenText(const string& m, int c) {
|
string FGATC::GenText(const string& m, int c) {
|
||||||
return("");
|
return("");
|
||||||
}
|
}
|
||||||
|
|
||||||
ostream& operator << (ostream& os, atc_type atc) {
|
ostream& operator << (ostream& os, atc_type atc) {
|
||||||
switch(atc) {
|
switch(atc) {
|
||||||
case(AWOS): return(os << "AWOS");
|
case(AWOS): return(os << "AWOS");
|
||||||
case(ATIS): return(os << "ATIS");
|
case(ATIS): return(os << "ATIS");
|
||||||
case(GROUND): return(os << "GROUND");
|
case(GROUND): return(os << "GROUND");
|
||||||
case(TOWER): return(os << "TOWER");
|
case(TOWER): return(os << "TOWER");
|
||||||
case(APPROACH): return(os << "APPROACH");
|
case(APPROACH): return(os << "APPROACH");
|
||||||
case(DEPARTURE): return(os << "DEPARTURE");
|
case(DEPARTURE): return(os << "DEPARTURE");
|
||||||
case(ENROUTE): return(os << "ENROUTE");
|
case(ENROUTE): return(os << "ENROUTE");
|
||||||
case(INVALID): return(os << "INVALID");
|
case(INVALID): return(os << "INVALID");
|
||||||
}
|
}
|
||||||
return(os << "ERROR - Unknown switch in atc_type operator << ");
|
return(os << "ERROR - Unknown switch in atc_type operator << ");
|
||||||
}
|
}
|
||||||
|
|
||||||
std::istream& operator >> ( std::istream& fin, ATCData& a )
|
std::istream& operator >> ( std::istream& fin, ATCData& a )
|
||||||
{
|
{
|
||||||
double f;
|
double f;
|
||||||
char ch;
|
char ch;
|
||||||
char tp;
|
char tp;
|
||||||
|
|
||||||
fin >> tp;
|
fin >> tp;
|
||||||
|
|
||||||
switch(tp) {
|
switch(tp) {
|
||||||
case 'I':
|
case 'I':
|
||||||
a.type = ATIS;
|
a.type = ATIS;
|
||||||
break;
|
break;
|
||||||
case 'T':
|
case 'T':
|
||||||
a.type = TOWER;
|
a.type = TOWER;
|
||||||
break;
|
break;
|
||||||
case 'G':
|
case 'G':
|
||||||
a.type = GROUND;
|
a.type = GROUND;
|
||||||
break;
|
break;
|
||||||
case 'A':
|
case 'A':
|
||||||
a.type = APPROACH;
|
a.type = APPROACH;
|
||||||
break;
|
break;
|
||||||
case '[':
|
case '[':
|
||||||
a.type = INVALID;
|
a.type = INVALID;
|
||||||
return fin >> skipeol;
|
return fin >> skipeol;
|
||||||
default:
|
default:
|
||||||
SG_LOG(SG_ATC, SG_ALERT, "Warning - unknown type \'" << tp << "\' found whilst reading ATC frequency data!\n");
|
SG_LOG(SG_ATC, SG_ALERT, "Warning - unknown type \'" << tp << "\' found whilst reading ATC frequency data!\n");
|
||||||
a.type = INVALID;
|
a.type = INVALID;
|
||||||
return fin >> skipeol;
|
return fin >> skipeol;
|
||||||
}
|
}
|
||||||
|
|
||||||
double lat, lon, elev;
|
double lat, lon, elev;
|
||||||
|
|
||||||
fin >> lat >> lon >> elev >> f >> a.range >> a.ident;
|
fin >> lat >> lon >> elev >> f >> a.range >> a.ident;
|
||||||
a.geod = SGGeod::fromDegM(lon, lat, elev);
|
a.geod = SGGeod::fromDegM(lon, lat, elev);
|
||||||
a.name = "";
|
a.name = "";
|
||||||
fin >> ch;
|
fin >> ch;
|
||||||
if(ch != '"') a.name += ch;
|
if(ch != '"') a.name += ch;
|
||||||
while(1) {
|
while(1) {
|
||||||
//in >> noskipws
|
//in >> noskipws
|
||||||
fin.unsetf(std::ios::skipws);
|
fin.unsetf(std::ios::skipws);
|
||||||
fin >> ch;
|
fin >> ch;
|
||||||
if((ch == '"') || (ch == 0x0A)) {
|
if((ch == '"') || (ch == 0x0A)) {
|
||||||
break;
|
break;
|
||||||
} // we shouldn't need the 0x0A but it makes a nice safely in case someone leaves off the "
|
} // we shouldn't need the 0x0A but it makes a nice safely in case someone leaves off the "
|
||||||
a.name += ch;
|
a.name += ch;
|
||||||
}
|
}
|
||||||
fin.setf(std::ios::skipws);
|
fin.setf(std::ios::skipws);
|
||||||
//cout << "Comm name = " << a.name << '\n';
|
//cout << "Comm name = " << a.name << '\n';
|
||||||
|
|
||||||
a.freq = (int)(f*100.0 + 0.5);
|
a.freq = (int)(f*100.0 + 0.5);
|
||||||
|
|
||||||
// cout << a.ident << endl;
|
// cout << a.ident << endl;
|
||||||
|
|
||||||
// generate cartesian coordinates
|
// generate cartesian coordinates
|
||||||
a.cart = SGVec3d::fromGeod(a.geod);
|
a.cart = SGVec3d::fromGeod(a.geod);
|
||||||
return fin >> skipeol;
|
return fin >> skipeol;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
|
@ -42,20 +42,6 @@ namespace flightgear
|
||||||
class CommStation;
|
class CommStation;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert a frequency in MHz to tens of kHz
|
|
||||||
// so we can use it e.g. as an index into commlist_freq
|
|
||||||
//
|
|
||||||
// If freq > 1000 assume it's already in tens of KHz;
|
|
||||||
// otherwise assume MHz.
|
|
||||||
//
|
|
||||||
// Note: 122.375 must be rounded DOWN to 12237
|
|
||||||
// in order to be consistent with apt.dat et cetera.
|
|
||||||
inline int kHz10(double freq)
|
|
||||||
{
|
|
||||||
if (freq > 1000.) return int(freq);
|
|
||||||
return int(freq*100.0 + 0.25);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Possible types of ATC type that the radios may be tuned to.
|
// Possible types of ATC type that the radios may be tuned to.
|
||||||
// INVALID implies not tuned in to anything.
|
// INVALID implies not tuned in to anything.
|
||||||
enum atc_type {
|
enum atc_type {
|
||||||
|
@ -69,6 +55,7 @@ enum atc_type {
|
||||||
INVALID /* must be last element; see ATC_NUM_TYPES */
|
INVALID /* must be last element; see ATC_NUM_TYPES */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifdef OLD_ATC_MGR
|
||||||
const int ATC_NUM_TYPES = 1 + INVALID;
|
const int ATC_NUM_TYPES = 1 + INVALID;
|
||||||
|
|
||||||
// DCL - new experimental ATC data store
|
// DCL - new experimental ATC data store
|
||||||
|
@ -98,9 +85,10 @@ struct RunwayDetails {
|
||||||
};
|
};
|
||||||
|
|
||||||
std::ostream& operator << (std::ostream& os, atc_type atc);
|
std::ostream& operator << (std::ostream& os, atc_type atc);
|
||||||
|
#endif
|
||||||
|
|
||||||
class FGATC {
|
class FGATC {
|
||||||
friend class FGATCMgr;
|
friend class FGATISMgr;
|
||||||
public:
|
public:
|
||||||
|
|
||||||
FGATC();
|
FGATC();
|
||||||
|
@ -113,15 +101,16 @@ public:
|
||||||
// wish to use the response timer functionality.
|
// wish to use the response timer functionality.
|
||||||
virtual void Update(double dt);
|
virtual void Update(double dt);
|
||||||
|
|
||||||
// Recieve a coded callback from the ATC menu system based on the user's selection
|
|
||||||
virtual void ReceiveUserCallback(int code);
|
|
||||||
|
|
||||||
// Indicate that this instance should output to the display if appropriate
|
// Indicate that this instance should output to the display if appropriate
|
||||||
inline void SetDisplay() { _display = true; }
|
inline void SetDisplay() { _display = true; }
|
||||||
|
|
||||||
// Indicate that this instance should not output to the display
|
// Indicate that this instance should not output to the display
|
||||||
inline void SetNoDisplay() { _display = false; }
|
inline void SetNoDisplay() { _display = false; }
|
||||||
|
|
||||||
|
#ifdef OLD_ATC_MGR
|
||||||
|
// Receive a coded callback from the ATC menu system based on the user's selection
|
||||||
|
virtual void ReceiveUserCallback(int code);
|
||||||
|
|
||||||
// Generate the text of a message from its parameters and the current context.
|
// Generate the text of a message from its parameters and the current context.
|
||||||
virtual std::string GenText(const std::string& m, int c);
|
virtual std::string GenText(const std::string& m, int c);
|
||||||
|
|
||||||
|
@ -141,16 +130,19 @@ public:
|
||||||
// AI traffic should check FreqClear() is true prior to transmitting.
|
// AI traffic should check FreqClear() is true prior to transmitting.
|
||||||
// The user will just have to wait for a gap in dialog as in real life.
|
// The user will just have to wait for a gap in dialog as in real life.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
inline int get_freq() const { return freq; }
|
||||||
|
inline void set_freq(const int fq) {freq = fq;}
|
||||||
|
inline int get_range() const { return range; }
|
||||||
|
inline void set_range(const int rg) {range = rg;}
|
||||||
|
#endif
|
||||||
// Return the type of ATC station that the class represents
|
// Return the type of ATC station that the class represents
|
||||||
inline atc_type GetType() { return _type; }
|
inline atc_type GetType() { return _type; }
|
||||||
|
|
||||||
// Set the core ATC data
|
// Set the core ATC data
|
||||||
void SetStation(flightgear::CommStation* sta);
|
void SetStation(flightgear::CommStation* sta);
|
||||||
|
|
||||||
inline int get_freq() const { return freq; }
|
|
||||||
inline void set_freq(const int fq) {freq = fq;}
|
|
||||||
inline int get_range() const { return range; }
|
|
||||||
inline void set_range(const int rg) {range = rg;}
|
|
||||||
inline const std::string& get_ident() { return ident; }
|
inline const std::string& get_ident() { return ident; }
|
||||||
inline void set_ident(const std::string& id) { ident = id; }
|
inline void set_ident(const std::string& id) { ident = id; }
|
||||||
inline const std::string& get_name() { return name; }
|
inline const std::string& get_name() { return name; }
|
||||||
|
@ -169,25 +161,26 @@ protected:
|
||||||
// Requires the sound manager refname if audio, else "".
|
// Requires the sound manager refname if audio, else "".
|
||||||
void NoRender(const std::string& refname);
|
void NoRender(const std::string& refname);
|
||||||
|
|
||||||
|
virtual FGATCVoice* GetVoicePointer() = 0;
|
||||||
|
|
||||||
SGGeod _geod;
|
SGGeod _geod;
|
||||||
SGVec3d _cart;
|
SGVec3d _cart;
|
||||||
int freq;
|
int freq;
|
||||||
std::map<std::string,int> active_on;
|
flightgear::CommStation* _currentStation;
|
||||||
|
|
||||||
int range;
|
int range;
|
||||||
std::string ident; // Code of the airport its at.
|
std::string ident; // Code of the airport its at.
|
||||||
std::string name; // Name transmitted in the broadcast.
|
std::string name; // Name transmitted in the broadcast.
|
||||||
|
std::string _currentMsg; // Current message being transmitted
|
||||||
|
|
||||||
// Rendering related stuff
|
// Rendering related stuff
|
||||||
bool _voice; // Flag - true if we are using voice
|
bool _voice; // Flag - true if we are using voice
|
||||||
bool _playing; // Indicates a message in progress
|
bool _playing; // Indicates a message in progress
|
||||||
bool _voiceOK; // Flag - true if at least one voice has loaded OK
|
|
||||||
FGATCVoice* _vPtr;
|
FGATCVoice* _vPtr;
|
||||||
|
|
||||||
SGSharedPtr<SGSampleGroup> _sgr; // default sample group;
|
SGSharedPtr<SGSampleGroup> _sgr; // default sample group;
|
||||||
|
|
||||||
|
#ifdef OLD_ATC_MGR
|
||||||
bool freqClear; // Flag to indicate if the frequency is clear of ongoing dialog
|
bool freqClear; // Flag to indicate if the frequency is clear of ongoing dialog
|
||||||
bool receiving; // Flag to indicate we are receiving a transmission
|
bool receiving; // Flag to indicate we are receiving a transmission
|
||||||
|
|
||||||
|
@ -204,11 +197,14 @@ protected:
|
||||||
bool responseReqd; // Flag to indicate we should be responding to a request/report
|
bool responseReqd; // Flag to indicate we should be responding to a request/report
|
||||||
double _releaseTime;
|
double _releaseTime;
|
||||||
double _releaseCounter;
|
double _releaseCounter;
|
||||||
|
std::string pending_transmission; // derived classes set this string before calling Transmit(...)
|
||||||
|
#endif
|
||||||
atc_type _type;
|
atc_type _type;
|
||||||
bool _display; // Flag to indicate whether we should be outputting to the ATC display.
|
bool _display; // Flag to indicate whether we should be outputting to the ATC display.
|
||||||
std::string pending_transmission; // derived classes set this string before calling Transmit(...)
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
#ifdef OLD_ATC_MGR
|
||||||
// Transmission timing stuff.
|
// Transmission timing stuff.
|
||||||
double _timeout;
|
double _timeout;
|
||||||
bool _pending;
|
bool _pending;
|
||||||
|
@ -216,13 +212,16 @@ private:
|
||||||
bool _transmitting; // we are transmitting
|
bool _transmitting; // we are transmitting
|
||||||
double _counter;
|
double _counter;
|
||||||
double _max_count;
|
double _max_count;
|
||||||
|
#endif
|
||||||
|
|
||||||
SGPropertyNode_ptr _volume;
|
SGPropertyNode_ptr _masterVolume;
|
||||||
SGPropertyNode_ptr _enabled;
|
SGPropertyNode_ptr _enabled;
|
||||||
SGPropertyNode_ptr _atc_external;
|
SGPropertyNode_ptr _atc_external;
|
||||||
SGPropertyNode_ptr _internal;
|
SGPropertyNode_ptr _internal;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifdef OLD_ATC_MGR
|
||||||
std::istream& operator>> ( std::istream& fin, ATCData& a );
|
std::istream& operator>> ( std::istream& fin, ATCData& a );
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif // _FG_ATC_HXX
|
#endif // _FG_ATC_HXX
|
||||||
|
|
|
@ -1,308 +0,0 @@
|
||||||
// ATCDialog.cxx - Functions and classes to handle the pop-up ATC dialog
|
|
||||||
//
|
|
||||||
// Written by Alexander Kappes and David Luff, started February 2003.
|
|
||||||
//
|
|
||||||
// Copyright (C) 2003 Alexander Kappes and David Luff
|
|
||||||
//
|
|
||||||
// This program is free software; you can redistribute it and/or
|
|
||||||
// modify it under the terms of the GNU General Public License as
|
|
||||||
// published by the Free Software Foundation; either version 2 of the
|
|
||||||
// License, or (at your option) any later version.
|
|
||||||
//
|
|
||||||
// This program is distributed in the hope that it will be useful, but
|
|
||||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
// General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with this program; if not, write to the Free Software
|
|
||||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
# include "config.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <simgear/compiler.h>
|
|
||||||
|
|
||||||
#include <simgear/structure/commands.hxx>
|
|
||||||
#include <simgear/props/props_io.hxx>
|
|
||||||
|
|
||||||
#include <Main/globals.hxx>
|
|
||||||
#include <GUI/gui.h> // mkDialog
|
|
||||||
#include <GUI/new_gui.hxx>
|
|
||||||
#include <Main/fg_props.hxx>
|
|
||||||
|
|
||||||
#include "ATCDialogOld.hxx"
|
|
||||||
#include "ATC.hxx"
|
|
||||||
#include "ATCmgr.hxx"
|
|
||||||
#include "ATCutils.hxx"
|
|
||||||
#include <Airports/simple.hxx>
|
|
||||||
#include <ATC/CommStation.hxx>
|
|
||||||
|
|
||||||
#include <sstream>
|
|
||||||
|
|
||||||
using std::ostringstream;
|
|
||||||
using std::cerr;
|
|
||||||
using std::endl;
|
|
||||||
|
|
||||||
FGATCDialog *current_atcdialog;
|
|
||||||
|
|
||||||
// For the command manager - maybe eventually this should go in the built in command list
|
|
||||||
#if 0
|
|
||||||
static bool do_ATC_dialog(const SGPropertyNode* arg) {
|
|
||||||
cerr << "Running ATCDCL do_ATC_dialog" << endl;
|
|
||||||
current_atcdialog->PopupDialog();
|
|
||||||
return(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool do_ATC_freq_search(const SGPropertyNode* arg) {
|
|
||||||
current_atcdialog->FreqDialog();
|
|
||||||
return(true);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
ATCMenuEntry::ATCMenuEntry() {
|
|
||||||
stationid = "";
|
|
||||||
//stationfr = 0;
|
|
||||||
transmission = "";
|
|
||||||
menuentry = "";
|
|
||||||
callback_code = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
ATCMenuEntry::~ATCMenuEntry() {
|
|
||||||
}
|
|
||||||
|
|
||||||
void atcUppercase(string &s) {
|
|
||||||
for(unsigned int i=0; i<s.size(); ++i) {
|
|
||||||
s[i] = toupper(s[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// find child whose <name>...</name> entry matches 'name'
|
|
||||||
static SGPropertyNode *getNamedNode(SGPropertyNode *prop, const char *name) {
|
|
||||||
SGPropertyNode* p;
|
|
||||||
|
|
||||||
for (int i = 0; i < prop->nChildren(); i++)
|
|
||||||
if ((p = getNamedNode(prop->getChild(i), name)))
|
|
||||||
return p;
|
|
||||||
|
|
||||||
if (!strcmp(prop->getStringValue("name"), name))
|
|
||||||
return prop;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
FGATCDialog::FGATCDialog() {
|
|
||||||
_callbackPending = false;
|
|
||||||
_callbackTimer = 0.0;
|
|
||||||
_callbackWait = 0.0;
|
|
||||||
_callbackPtr = NULL;
|
|
||||||
_callbackCode = 0;
|
|
||||||
_gui = (NewGUI *)globals->get_subsystem("gui");
|
|
||||||
}
|
|
||||||
|
|
||||||
FGATCDialog::~FGATCDialog() {
|
|
||||||
}
|
|
||||||
|
|
||||||
void FGATCDialog::Init() {
|
|
||||||
// Add ATC-dialog to the command list
|
|
||||||
//globals->get_commands()->addCommand("ATC-dialog", do_ATC_dialog);
|
|
||||||
// Add ATC-freq-search to the command list
|
|
||||||
//globals->get_commands()->addCommand("ATC-freq-search", do_ATC_freq_search);
|
|
||||||
|
|
||||||
// initialize properties polled in Update()
|
|
||||||
//globals->get_props()->setStringValue("/sim/atc/freq-airport", "");
|
|
||||||
//globals->get_props()->setIntValue("/sim/atc/transmission-num", -1);
|
|
||||||
}
|
|
||||||
|
|
||||||
void FGATCDialog::Update(double dt) {
|
|
||||||
//static SGPropertyNode_ptr airport = globals->get_props()->getNode("/sim/atc/freq-airport", true);
|
|
||||||
//string s = airport->getStringValue();
|
|
||||||
//if (!s.empty()) {
|
|
||||||
// airport->setStringValue("");
|
|
||||||
// FreqDisplay(s);
|
|
||||||
//}
|
|
||||||
|
|
||||||
//static SGPropertyNode_ptr trans_num = globals->get_props()->getNode("/sim/atc/transmission-num", true);
|
|
||||||
//int n = trans_num->getIntValue();
|
|
||||||
//if (n >= 0) {
|
|
||||||
// trans_num->setIntValue(-1);
|
|
||||||
// PopupCallback(n);
|
|
||||||
//}
|
|
||||||
|
|
||||||
//if(_callbackPending) {
|
|
||||||
// if(_callbackTimer > _callbackWait) {
|
|
||||||
// _callbackPtr->ReceiveUserCallback(_callbackCode);
|
|
||||||
// _callbackPtr->NotifyTransmissionFinished(fgGetString("/sim/user/callsign"));
|
|
||||||
// _callbackPending = false;
|
|
||||||
// } else {
|
|
||||||
// _callbackTimer += dt;
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add an entry
|
|
||||||
void FGATCDialog::add_entry(const string& station, const string& transmission, const string& menutext, atc_type type, int code) {
|
|
||||||
|
|
||||||
ATCMenuEntry a;
|
|
||||||
|
|
||||||
a.stationid = station;
|
|
||||||
a.transmission = transmission;
|
|
||||||
a.menuentry = menutext;
|
|
||||||
a.callback_code = code;
|
|
||||||
|
|
||||||
(available_dialog[type])[station.c_str()].push_back(a);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void FGATCDialog::remove_entry( const string &station, const string &trans, atc_type type ) {
|
|
||||||
atcmentry_vec_type* p = &((available_dialog[type])[station]);
|
|
||||||
atcmentry_vec_iterator current = p->begin();
|
|
||||||
while(current != p->end()) {
|
|
||||||
if(current->transmission == trans) current = p->erase(current);
|
|
||||||
else ++current;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void FGATCDialog::remove_entry( const string &station, int code, atc_type type ) {
|
|
||||||
atcmentry_vec_type* p = &((available_dialog[type])[station]);
|
|
||||||
atcmentry_vec_iterator current = p->begin();
|
|
||||||
while(current != p->end()) {
|
|
||||||
if(current->callback_code == code) current = p->erase(current);
|
|
||||||
else ++current;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// query the database whether the transmission is already registered;
|
|
||||||
bool FGATCDialog::trans_reg( const string &station, const string &trans, atc_type type ) {
|
|
||||||
atcmentry_vec_type* p = &((available_dialog[type])[station]);
|
|
||||||
atcmentry_vec_iterator current = p->begin();
|
|
||||||
for ( ; current != p->end() ; ++current ) {
|
|
||||||
if ( current->transmission == trans ) return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// query the database whether the transmission is already registered;
|
|
||||||
bool FGATCDialog::trans_reg( const string &station, int code, atc_type type ) {
|
|
||||||
atcmentry_vec_type* p = &((available_dialog[type])[station]);
|
|
||||||
atcmentry_vec_iterator current = p->begin();
|
|
||||||
for ( ; current != p->end() ; ++current ) {
|
|
||||||
if ( current->callback_code == code ) return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Display the ATC popup dialog box with options relevant to the users current situation.
|
|
||||||
void FGATCDialog::PopupDialog() {
|
|
||||||
const char *dialog_name = "atc-dialog";
|
|
||||||
SGPropertyNode_ptr dlg = _gui->getDialogProperties(dialog_name);
|
|
||||||
if (!dlg)
|
|
||||||
return;
|
|
||||||
|
|
||||||
_gui->closeDialog(dialog_name);
|
|
||||||
|
|
||||||
SGPropertyNode_ptr button_group = getNamedNode(dlg, "transmission-choice");
|
|
||||||
// remove all transmission buttons
|
|
||||||
button_group->removeChildren("button", false);
|
|
||||||
|
|
||||||
string label;
|
|
||||||
FGATCMgr* pAtcMgr = globals->get_ATC_mgr();
|
|
||||||
if (!pAtcMgr)
|
|
||||||
{
|
|
||||||
SG_LOG(SG_ATC, SG_ALERT, "ERROR! No ATC manager! Oops...");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
FGATC* atcptr = pAtcMgr->GetComm1ATCPointer(); // Hardwired to comm1 at the moment
|
|
||||||
|
|
||||||
if (!atcptr) {
|
|
||||||
label = "Not currently tuned to any ATC service";
|
|
||||||
mkDialog(label.c_str());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(atcptr->GetType() == ATIS) {
|
|
||||||
label = "Tuned to ATIS - no communication possible";
|
|
||||||
mkDialog(label.c_str());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
atcmentry_vec_type atcmlist = (available_dialog[atcptr->GetType()])[atcptr->get_ident()];
|
|
||||||
atcmentry_vec_iterator current = atcmlist.begin();
|
|
||||||
atcmentry_vec_iterator last = atcmlist.end();
|
|
||||||
|
|
||||||
if(!atcmlist.size()) {
|
|
||||||
label = "No transmission available";
|
|
||||||
mkDialog(label.c_str());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const int bufsize = 32;
|
|
||||||
char buf[bufsize];
|
|
||||||
// loop over all entries in atcmentrylist
|
|
||||||
for (int n = 0; n < 10; ++n) {
|
|
||||||
snprintf(buf, bufsize, "/sim/atc/opt[%d]", n);
|
|
||||||
fgSetBool(buf, false);
|
|
||||||
|
|
||||||
if (current == last)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// add transmission button (modified copy of <button-template>)
|
|
||||||
SGPropertyNode *entry = button_group->getNode("button", n, true);
|
|
||||||
copyProperties(button_group->getNode("button-template", true), entry);
|
|
||||||
entry->removeChildren("enabled", true);
|
|
||||||
entry->setStringValue("property", buf);
|
|
||||||
entry->setIntValue("keynum", '1' + n);
|
|
||||||
if (n == 0)
|
|
||||||
entry->setBoolValue("default", true);
|
|
||||||
|
|
||||||
snprintf(buf, bufsize, "%d", n + 1);
|
|
||||||
string legend = string(buf) + ". " + current->menuentry;
|
|
||||||
entry->setStringValue("legend", legend.c_str());
|
|
||||||
entry->setIntValue("binding/value", n);
|
|
||||||
current++;
|
|
||||||
}
|
|
||||||
|
|
||||||
_gui->showDialog(dialog_name);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
void FGATCDialog::PopupCallback(int num) {
|
|
||||||
FGATCMgr* pAtcMgr = globals->get_ATC_mgr();
|
|
||||||
if (!pAtcMgr)
|
|
||||||
{
|
|
||||||
SG_LOG(SG_ATC, SG_ALERT, "ERROR! No ATC manager! Oops...");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
FGATC* atcptr = pAtcMgr->GetComm1ATCPointer(); // FIXME - Hardwired to comm1 at the moment
|
|
||||||
|
|
||||||
if (!atcptr)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (atcptr->GetType() == TOWER) {
|
|
||||||
//cout << "TOWER " << endl;
|
|
||||||
//cout << "ident is " << atcptr->get_ident() << endl;
|
|
||||||
atcmentry_vec_type atcmlist = (available_dialog[TOWER])[atcptr->get_ident()];
|
|
||||||
int size = atcmlist.size();
|
|
||||||
if(size && num < size) {
|
|
||||||
//cout << "Doing callback...\n";
|
|
||||||
ATCMenuEntry a = atcmlist[num];
|
|
||||||
atcptr->SetFreqInUse();
|
|
||||||
string pilot = atcptr->GenText(a.transmission, a.callback_code);
|
|
||||||
fgSetString("/sim/messages/pilot", pilot.c_str());
|
|
||||||
// This is the user's speech getting displayed.
|
|
||||||
_callbackPending = true;
|
|
||||||
_callbackTimer = 0.0;
|
|
||||||
_callbackWait = 5.0;
|
|
||||||
_callbackPtr = atcptr;
|
|
||||||
_callbackCode = a.callback_code;
|
|
||||||
} else {
|
|
||||||
//cout << "No options available...\n";
|
|
||||||
}
|
|
||||||
//cout << "Donded" << endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,116 +0,0 @@
|
||||||
// ATCDialog.hxx - Functions and classes to handle the pop-up ATC dialog
|
|
||||||
//
|
|
||||||
// Written by Alexander Kappes and David Luff, started February 2003.
|
|
||||||
//
|
|
||||||
// Copyright (C) 2003 Alexander Kappes and David Luff
|
|
||||||
//
|
|
||||||
// This program is free software; you can redistribute it and/or
|
|
||||||
// modify it under the terms of the GNU General Public License as
|
|
||||||
// published by the Free Software Foundation; either version 2 of the
|
|
||||||
// License, or (at your option) any later version.
|
|
||||||
//
|
|
||||||
// This program is distributed in the hope that it will be useful, but
|
|
||||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
// General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with this program; if not, write to the Free Software
|
|
||||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
||||||
|
|
||||||
#ifndef ATC_DIALOG_HXX
|
|
||||||
#define ATC_DIALOG_HXX
|
|
||||||
|
|
||||||
#include <simgear/compiler.h>
|
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
#include <map>
|
|
||||||
|
|
||||||
#include "ATC.hxx"
|
|
||||||
|
|
||||||
using std::vector;
|
|
||||||
using std::map;
|
|
||||||
|
|
||||||
class NewGUI;
|
|
||||||
|
|
||||||
// ATCMenuEntry - an encapsulation of an entry in the ATC dialog
|
|
||||||
struct ATCMenuEntry {
|
|
||||||
|
|
||||||
string stationid; // ID of transmitting station
|
|
||||||
//int stationfr; // ?
|
|
||||||
string transmission; // Actual speech of transmission
|
|
||||||
string menuentry; // Shortened version for display in the dialog
|
|
||||||
int callback_code; // This code is supplied by the registering station, and then
|
|
||||||
// returned to the registering station if that option is chosen.
|
|
||||||
// The actual value is only understood by the registering station -
|
|
||||||
// FGATCDialog only stores it and returns it if appropriate.
|
|
||||||
|
|
||||||
ATCMenuEntry();
|
|
||||||
~ATCMenuEntry();
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef vector < ATCMenuEntry > atcmentry_vec_type;
|
|
||||||
typedef atcmentry_vec_type::iterator atcmentry_vec_iterator;
|
|
||||||
|
|
||||||
typedef map < string, atcmentry_vec_type > atcmentry_map_type;
|
|
||||||
typedef atcmentry_map_type::iterator atcmentry_map_iterator;
|
|
||||||
|
|
||||||
void atcUppercase(string &s);
|
|
||||||
|
|
||||||
//void ATCDialogInit();
|
|
||||||
//void ATCDoDialog(atc_type type);
|
|
||||||
|
|
||||||
class FGATCDialog {
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
FGATCDialog();
|
|
||||||
~FGATCDialog();
|
|
||||||
|
|
||||||
void Init();
|
|
||||||
|
|
||||||
void Update(double dt);
|
|
||||||
|
|
||||||
void PopupDialog();
|
|
||||||
|
|
||||||
void PopupCallback(int);
|
|
||||||
|
|
||||||
void add_entry( const string& station, const string& transmission, const string& menutext, atc_type type, int code);
|
|
||||||
|
|
||||||
void remove_entry( const string &station, const string &trans, atc_type type );
|
|
||||||
|
|
||||||
void remove_entry( const string &station, int code, atc_type type );
|
|
||||||
|
|
||||||
// query the database whether the transmission is already registered;
|
|
||||||
bool trans_reg( const string &station, const string &trans, atc_type type );
|
|
||||||
|
|
||||||
// query the database whether the transmission is already registered;
|
|
||||||
bool trans_reg( const string &station, int code, atc_type type );
|
|
||||||
|
|
||||||
// Display a frequency search dialog for nearby stations
|
|
||||||
void FreqDialog();
|
|
||||||
|
|
||||||
// Display the comm ATC frequencies for airport ident
|
|
||||||
// where ident is a valid ICAO code.
|
|
||||||
void FreqDisplay(string& ident);
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
atcmentry_map_type available_dialog[ATC_NUM_TYPES];
|
|
||||||
|
|
||||||
int freq;
|
|
||||||
bool reset;
|
|
||||||
|
|
||||||
bool _callbackPending;
|
|
||||||
double _callbackTimer;
|
|
||||||
double _callbackWait;
|
|
||||||
FGATC* _callbackPtr;
|
|
||||||
int _callbackCode;
|
|
||||||
|
|
||||||
NewGUI *_gui;
|
|
||||||
};
|
|
||||||
|
|
||||||
extern FGATCDialog *current_atcdialog;
|
|
||||||
|
|
||||||
#endif // ATC_DIALOG_HXX
|
|
||||||
|
|
|
@ -1,316 +0,0 @@
|
||||||
// ATCmgr.cxx - Implementation of FGATCMgr - a global Flightgear ATC manager.
|
|
||||||
//
|
|
||||||
// Written by David Luff, started February 2002.
|
|
||||||
//
|
|
||||||
// Copyright (C) 2002 David C Luff - david.luff@nottingham.ac.uk
|
|
||||||
//
|
|
||||||
// This program is free software; you can redistribute it and/or
|
|
||||||
// modify it under the terms of the GNU General Public License as
|
|
||||||
// published by the Free Software Foundation; either version 2 of the
|
|
||||||
// License, or (at your option) any later version.
|
|
||||||
//
|
|
||||||
// This program is distributed in the hope that it will be useful, but
|
|
||||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
// General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with this program; if not, write to the Free Software
|
|
||||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
# include <config.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <simgear/misc/sg_path.hxx>
|
|
||||||
#include <simgear/debug/logstream.hxx>
|
|
||||||
#include <simgear/structure/exception.hxx>
|
|
||||||
|
|
||||||
#include <Airports/simple.hxx>
|
|
||||||
#include <ATC/CommStation.hxx>
|
|
||||||
#include <Main/fg_props.hxx>
|
|
||||||
|
|
||||||
#include "ATCmgr.hxx"
|
|
||||||
#include "ATCDialogOld.hxx"
|
|
||||||
#include "ATCutils.hxx"
|
|
||||||
#include "atis.hxx"
|
|
||||||
|
|
||||||
using flightgear::CommStation;
|
|
||||||
|
|
||||||
FGATCMgr::FGATCMgr() :
|
|
||||||
initDone(false),
|
|
||||||
atc_list(new atc_list_type),
|
|
||||||
#ifdef ENABLE_AUDIO_SUPPORT
|
|
||||||
voice(true),
|
|
||||||
voiceOK(false),
|
|
||||||
v1(0)
|
|
||||||
#else
|
|
||||||
voice(false),
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
globals->set_ATC_mgr(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
FGATCMgr::~FGATCMgr() {
|
|
||||||
globals->set_ATC_mgr(NULL);
|
|
||||||
delete v1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void FGATCMgr::bind() {
|
|
||||||
}
|
|
||||||
|
|
||||||
void FGATCMgr::unbind() {
|
|
||||||
}
|
|
||||||
|
|
||||||
void FGATCMgr::init() {
|
|
||||||
//cout << "ATCMgr::init called..." << endl;
|
|
||||||
|
|
||||||
lon_node = fgGetNode("/position/longitude-deg", true);
|
|
||||||
lat_node = fgGetNode("/position/latitude-deg", true);
|
|
||||||
elev_node = fgGetNode("/position/altitude-ft", true);
|
|
||||||
atc_list_itr = atc_list->begin();
|
|
||||||
|
|
||||||
// Search for connected ATC stations once per 0.8 seconds or so
|
|
||||||
// globals->get_event_mgr()->add( "fgATCSearch()", fgATCSearch,
|
|
||||||
// FGEvent::FG_EVENT_READY, 800);
|
|
||||||
//
|
|
||||||
// For some reason the above doesn't compile - including Time/event.hxx stops compilation.
|
|
||||||
// Is this still true after the reorganization of the event managar??
|
|
||||||
// -EMH-
|
|
||||||
|
|
||||||
// Initialise the ATC Dialogs
|
|
||||||
SG_LOG(SG_ATC, SG_INFO, " ATC Dialog System");
|
|
||||||
current_atcdialog = new FGATCDialog;
|
|
||||||
current_atcdialog->Init();
|
|
||||||
|
|
||||||
initDone = true;
|
|
||||||
//cout << "ATCmgr::init done!" << endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
void FGATCMgr::update(double dt) {
|
|
||||||
if(!initDone) {
|
|
||||||
init();
|
|
||||||
SG_LOG(SG_ATC, SG_WARN, "Warning - ATCMgr::update(...) called before ATCMgr::init()");
|
|
||||||
}
|
|
||||||
|
|
||||||
current_atcdialog->Update(dt);
|
|
||||||
|
|
||||||
//cout << "Entering update..." << endl;
|
|
||||||
//Traverse the list of active stations.
|
|
||||||
//Only update one class per update step to avoid the whole ATC system having to calculate between frames.
|
|
||||||
//Eventually we should only update every so many steps.
|
|
||||||
//cout << "In FGATCMgr::update - atc_list.size = " << atc_list->size() << endl;
|
|
||||||
if(atc_list->size()) {
|
|
||||||
if(atc_list_itr == atc_list->end()) {
|
|
||||||
atc_list_itr = atc_list->begin();
|
|
||||||
}
|
|
||||||
//cout << "Updating " << (*atc_list_itr)->get_ident() << ' ' << (*atc_list_itr)->GetType() << '\n';
|
|
||||||
//cout << "Freq = " << (*atc_list_itr)->get_freq() << '\n';
|
|
||||||
//cout << "Updating...\n";
|
|
||||||
(*atc_list_itr).second->Update(dt * atc_list->size());
|
|
||||||
//cout << "Done ATC update..." << endl;
|
|
||||||
++atc_list_itr;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef ATC_TEST
|
|
||||||
//cout << "ATC_LIST: " << atc_list->size() << ' ';
|
|
||||||
for(atc_list_iterator it = atc_list->begin(); it != atc_list->end(); it++) {
|
|
||||||
cout << (*it)->get_ident() << ' ';
|
|
||||||
}
|
|
||||||
//cout << '\n';
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Search the tuned frequencies every now and then - this should be done with the event scheduler
|
|
||||||
static int i = 0; // Very ugly - but there should only ever be one instance of FGATCMgr.
|
|
||||||
if(i == 15) {
|
|
||||||
//cout << "About to search navcomm1" << endl;
|
|
||||||
FreqSearch("comm", 0);
|
|
||||||
FreqSearch("nav", 0);
|
|
||||||
}
|
|
||||||
if(i == 30) {
|
|
||||||
//cout << "About to search navcomm2" << endl;
|
|
||||||
FreqSearch("comm", 1);
|
|
||||||
FreqSearch("nav", 1);
|
|
||||||
i = 0;
|
|
||||||
}
|
|
||||||
++i;
|
|
||||||
|
|
||||||
//cout << "comm1 type = " << comm_type[0] << '\n';
|
|
||||||
//cout << "Leaving update..." << endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef map<string,int> MSI;
|
|
||||||
|
|
||||||
void FGATCMgr::ZapOtherService(const string ncunit, const string svc_name){
|
|
||||||
for (atc_list_iterator svc = atc_list->begin(); svc != atc_list->end(); svc++) {
|
|
||||||
|
|
||||||
if (svc->first != svc_name) {
|
|
||||||
MSI &actv = svc->second->active_on;
|
|
||||||
// OK, we have found some OTHER service;
|
|
||||||
// see if it is (was) active on our unit:
|
|
||||||
if (!actv.count(ncunit)) continue;
|
|
||||||
//cout << "Eradicating '" << svc->first << "' from: " << ncunit << endl;
|
|
||||||
actv.erase(ncunit);
|
|
||||||
if (!actv.size()) {
|
|
||||||
//cout << "Eradicating service: '" << svc->first << "'" << endl;
|
|
||||||
svc->second->SetNoDisplay();
|
|
||||||
svc->second->Update(0); // one last update
|
|
||||||
SG_LOG(SG_ATC, SG_INFO, "would have erased ATC service:" << svc->second->get_name()<< "/"
|
|
||||||
<< svc->second->get_ident());
|
|
||||||
// delete svc->second;
|
|
||||||
atc_list->erase(svc);
|
|
||||||
// ALL pointers into the ATC list are now invalid,
|
|
||||||
// so let's reset them:
|
|
||||||
atc_list_itr = atc_list->begin();
|
|
||||||
}
|
|
||||||
break; // cannot be duplicates in the active list
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Find in list - return a currently active ATC pointer given ICAO code and type
|
|
||||||
// Return NULL if the given service is not in the list
|
|
||||||
// - *** THE CALLING FUNCTION MUST CHECK FOR THIS ***
|
|
||||||
FGATC* FGATCMgr::FindInList(const string& id, const atc_type& tp) {
|
|
||||||
string ndx = id + decimalNumeral(tp);
|
|
||||||
if (!atc_list->count(ndx)) return 0;
|
|
||||||
return (*atc_list)[ndx];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return a pointer to an appropriate voice for a given type of ATC
|
|
||||||
// creating the voice if necessary - ie. make sure exactly one copy
|
|
||||||
// of every voice in use exists in memory.
|
|
||||||
//
|
|
||||||
// TODO - in the future this will get more complex and dole out country/airport
|
|
||||||
// specific voices, and possible make sure that the same voice doesn't get used
|
|
||||||
// at different airports in quick succession if a large enough selection are available.
|
|
||||||
FGATCVoice* FGATCMgr::GetVoicePointer(const atc_type& type) {
|
|
||||||
// TODO - implement me better - maintain a list of loaded voices and other voices!!
|
|
||||||
if(voice) {
|
|
||||||
switch(type) {
|
|
||||||
case ATIS: case AWOS:
|
|
||||||
#ifdef ENABLE_AUDIO_SUPPORT
|
|
||||||
// Delayed loading fo all available voices, needed because the
|
|
||||||
// soundmanager might not be initialized (at all) at this point.
|
|
||||||
// For now we'll do one hardwired one
|
|
||||||
|
|
||||||
/* I've loaded the voice even if /sim/sound/pause is true
|
|
||||||
* since I know no way of forcing load of the voice if the user
|
|
||||||
* subsequently switches /sim/sound/audible to true.
|
|
||||||
* (which is the right thing to do -- CLO) :-)
|
|
||||||
*/
|
|
||||||
if (!voiceOK && fgGetBool("/sim/sound/working")) {
|
|
||||||
v1 = new FGATCVoice;
|
|
||||||
try {
|
|
||||||
voiceOK = v1->LoadVoice("default");
|
|
||||||
voice = voiceOK;
|
|
||||||
} catch ( sg_io_exception & e) {
|
|
||||||
voiceOK = false;
|
|
||||||
SG_LOG(SG_ATC, SG_ALERT, "Unable to load default voice : "
|
|
||||||
<< e.getFormattedMessage().c_str());
|
|
||||||
voice = false;
|
|
||||||
delete v1;
|
|
||||||
v1 = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
if(voiceOK) {
|
|
||||||
return(v1);
|
|
||||||
}
|
|
||||||
case TOWER:
|
|
||||||
return(NULL);
|
|
||||||
case APPROACH:
|
|
||||||
return(NULL);
|
|
||||||
case GROUND:
|
|
||||||
return(NULL);
|
|
||||||
default:
|
|
||||||
return(NULL);
|
|
||||||
}
|
|
||||||
return(NULL);
|
|
||||||
} else {
|
|
||||||
return(NULL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Search for ATC stations by frequency
|
|
||||||
void FGATCMgr::FreqSearch(const string navcomm, const int unit) {
|
|
||||||
|
|
||||||
|
|
||||||
string ncunit = navcomm + "[" + decimalNumeral(unit) + "]";
|
|
||||||
string commbase = "/instrumentation/" + ncunit;
|
|
||||||
string commfreq = commbase + "/frequencies/selected-mhz";
|
|
||||||
SGPropertyNode_ptr comm_node = fgGetNode(commfreq.c_str(), false);
|
|
||||||
|
|
||||||
//cout << "FreqSearch: " << ncunit
|
|
||||||
// << " node: " << comm_node << endl;
|
|
||||||
if (!comm_node) return; // no such radio unit
|
|
||||||
|
|
||||||
ATCData data;
|
|
||||||
// Note: 122.375 must be rounded DOWN to 12237
|
|
||||||
// in order to be consistent with apt.dat et cetera.
|
|
||||||
int freqKhz = static_cast<int>(comm_node->getDoubleValue() * 100.0 + 0.25);
|
|
||||||
|
|
||||||
_aircraftPos = SGGeod::fromDegFt(lon_node->getDoubleValue(),
|
|
||||||
lat_node->getDoubleValue(), elev_node->getDoubleValue());
|
|
||||||
|
|
||||||
class RangeFilter : public CommStation::Filter {
|
|
||||||
public:
|
|
||||||
RangeFilter( const SGGeod & pos ) :
|
|
||||||
CommStation::Filter(),
|
|
||||||
_cart(SGVec3d::fromGeod(pos)),
|
|
||||||
_pos(pos)
|
|
||||||
{}
|
|
||||||
|
|
||||||
virtual bool pass(FGPositioned* aPos) const
|
|
||||||
{
|
|
||||||
flightgear::CommStation * stn = dynamic_cast<flightgear::CommStation*>(aPos);
|
|
||||||
if( NULL == stn ) return false;
|
|
||||||
// do the range check in cartesian space, since the distances are potentially
|
|
||||||
// large enough that the geodetic functions become unstable
|
|
||||||
// (eg, station on opposite side of the planet)
|
|
||||||
double rangeM = SGMiscd::max( stn->rangeNm(), 10.0 ) * SG_NM_TO_METER;
|
|
||||||
double d2 = distSqr( aPos->cart(), _cart);
|
|
||||||
|
|
||||||
return d2 <= (rangeM * rangeM);
|
|
||||||
}
|
|
||||||
private:
|
|
||||||
SGVec3d _cart;
|
|
||||||
SGGeod _pos;
|
|
||||||
};
|
|
||||||
|
|
||||||
RangeFilter rangeFilter(_aircraftPos );
|
|
||||||
|
|
||||||
CommStation* sta = CommStation::findByFreq(freqKhz, _aircraftPos, &rangeFilter );
|
|
||||||
if (!sta) {
|
|
||||||
ZapOtherService(ncunit, "x x x");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get rid of any *other* service that was on this radio unit:
|
|
||||||
FGPositioned::Type ty = sta->type();
|
|
||||||
string svc_name = sta->ident() + FGPositioned::nameForType(ty);
|
|
||||||
ZapOtherService(ncunit, svc_name);
|
|
||||||
// See if the service already exists, possibly connected to
|
|
||||||
// some other radio unit:
|
|
||||||
if (atc_list->count(svc_name)) {
|
|
||||||
// make sure the service knows it's tuned on this radio:
|
|
||||||
FGATC* svc = (*atc_list)[svc_name];
|
|
||||||
svc->active_on[ncunit] = 1;
|
|
||||||
svc->SetDisplay();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// This was a switch-case statement but the compiler didn't like
|
|
||||||
// the new variable creation with it.
|
|
||||||
if(ty == FGPositioned::FREQ_ATIS || ty == FGPositioned::FREQ_AWOS) {
|
|
||||||
(*atc_list)[svc_name] = new FGATIS;
|
|
||||||
FGATC* svc = (*atc_list)[svc_name];
|
|
||||||
if(svc != NULL) {
|
|
||||||
svc->SetStation(sta);
|
|
||||||
svc->active_on[ncunit] = 1;
|
|
||||||
svc->SetDisplay();
|
|
||||||
svc->Init();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -23,8 +23,8 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
#include <cstdlib>
|
||||||
|
|
||||||
#include <simgear/math/SGMath.hxx>
|
|
||||||
#include <simgear/constants.h>
|
#include <simgear/constants.h>
|
||||||
#include <simgear/misc/sg_path.hxx>
|
#include <simgear/misc/sg_path.hxx>
|
||||||
#include <simgear/debug/logstream.hxx>
|
#include <simgear/debug/logstream.hxx>
|
||||||
|
|
|
@ -21,7 +21,6 @@
|
||||||
#include <Airports/simple.hxx>
|
#include <Airports/simple.hxx>
|
||||||
#include <Airports/runways.hxx>
|
#include <Airports/runways.hxx>
|
||||||
|
|
||||||
#include <simgear/math/SGMath.hxx>
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
using std::string;
|
using std::string;
|
||||||
|
|
208
src/ATCDCL/ATISmgr.cxx
Normal file
208
src/ATCDCL/ATISmgr.cxx
Normal file
|
@ -0,0 +1,208 @@
|
||||||
|
// ATISmgr.cxx - Implementation of FGATISMgr - a global Flightgear ATIS manager.
|
||||||
|
//
|
||||||
|
// Written by David Luff, started February 2002.
|
||||||
|
//
|
||||||
|
// Copyright (C) 2002 David C Luff - david.luff@nottingham.ac.uk
|
||||||
|
// Copyright (C) 2012 Thorsten Brehm
|
||||||
|
//
|
||||||
|
// This program is free software; you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU General Public License as
|
||||||
|
// published by the Free Software Foundation; either version 2 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful, but
|
||||||
|
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
// General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program; if not, write to the Free Software
|
||||||
|
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
# include <config.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <simgear/misc/sg_path.hxx>
|
||||||
|
#include <simgear/debug/logstream.hxx>
|
||||||
|
#include <simgear/structure/exception.hxx>
|
||||||
|
|
||||||
|
#include <Airports/simple.hxx>
|
||||||
|
#include <ATC/CommStation.hxx>
|
||||||
|
#include <Main/fg_props.hxx>
|
||||||
|
|
||||||
|
#include "ATISmgr.hxx"
|
||||||
|
#include "ATCutils.hxx"
|
||||||
|
#include "atis.hxx"
|
||||||
|
|
||||||
|
using flightgear::CommStation;
|
||||||
|
|
||||||
|
FGATISMgr::FGATISMgr() :
|
||||||
|
_currentUnit(0),
|
||||||
|
_maxCommRadios(2),
|
||||||
|
#ifdef ENABLE_AUDIO_SUPPORT
|
||||||
|
voice(true),
|
||||||
|
voice1(0)
|
||||||
|
#else
|
||||||
|
voice(false)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
globals->set_ATIS_mgr(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
FGATISMgr::~FGATISMgr()
|
||||||
|
{
|
||||||
|
globals->set_ATIS_mgr(NULL);
|
||||||
|
|
||||||
|
for (unsigned int unit = 0;unit < _maxCommRadios; ++unit)
|
||||||
|
{
|
||||||
|
delete radios[unit].station;
|
||||||
|
radios[unit].station = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef ENABLE_AUDIO_SUPPORT
|
||||||
|
delete voice1;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void FGATISMgr::bind()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void FGATISMgr::unbind()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void FGATISMgr::init()
|
||||||
|
{
|
||||||
|
lon_node = fgGetNode("/position/longitude-deg", true);
|
||||||
|
lat_node = fgGetNode("/position/latitude-deg", true);
|
||||||
|
elev_node = fgGetNode("/position/altitude-ft", true);
|
||||||
|
|
||||||
|
for (unsigned int unit = 0;unit < _maxCommRadios; ++unit)
|
||||||
|
{
|
||||||
|
CommRadioData data;
|
||||||
|
string ncunit = "comm[" + decimalNumeral(unit) + "]";
|
||||||
|
string commbase = "/instrumentation/" + ncunit;
|
||||||
|
string commfreq = commbase + "/frequencies/selected-mhz";
|
||||||
|
|
||||||
|
data.freq = fgGetNode(commfreq.c_str(), true);
|
||||||
|
data.station = new FGATIS(commbase);
|
||||||
|
radios.push_back(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FGATISMgr::update(double dt)
|
||||||
|
{
|
||||||
|
// update only runs every now and then (1-2 per second)
|
||||||
|
if (++_currentUnit >= _maxCommRadios)
|
||||||
|
_currentUnit = 0;
|
||||||
|
|
||||||
|
FGATC* pStation = radios[_currentUnit].station;
|
||||||
|
if (pStation)
|
||||||
|
pStation->Update(dt * _maxCommRadios);
|
||||||
|
|
||||||
|
// Search the tuned frequencies
|
||||||
|
FreqSearch(_currentUnit);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return a pointer to an appropriate voice for a given type of ATC
|
||||||
|
// creating the voice if necessary - i.e. make sure exactly one copy
|
||||||
|
// of every voice in use exists in memory.
|
||||||
|
//
|
||||||
|
// TODO - in the future this will get more complex and dole out country/airport
|
||||||
|
// specific voices, and possible make sure that the same voice doesn't get used
|
||||||
|
// at different airports in quick succession if a large enough selection are available.
|
||||||
|
FGATCVoice* FGATISMgr::GetVoicePointer(const atc_type& type)
|
||||||
|
{
|
||||||
|
// TODO - implement me better - maintain a list of loaded voices and other voices!!
|
||||||
|
if(voice)
|
||||||
|
{
|
||||||
|
switch(type)
|
||||||
|
{
|
||||||
|
case ATIS: case AWOS:
|
||||||
|
#ifdef ENABLE_AUDIO_SUPPORT
|
||||||
|
// Delayed loading for all available voices, needed because the
|
||||||
|
// sound manager might not be initialized (at all) at this point.
|
||||||
|
// For now we'll do one hard-wired one
|
||||||
|
|
||||||
|
/* I've loaded the voice even if /sim/sound/pause is true
|
||||||
|
* since I know no way of forcing load of the voice if the user
|
||||||
|
* subsequently switches /sim/sound/audible to true.
|
||||||
|
* (which is the right thing to do -- CLO) :-)
|
||||||
|
*/
|
||||||
|
if (!voice1 && fgGetBool("/sim/sound/working")) {
|
||||||
|
voice1 = new FGATCVoice;
|
||||||
|
try {
|
||||||
|
voice = voice1->LoadVoice("default");
|
||||||
|
} catch ( sg_io_exception & e) {
|
||||||
|
SG_LOG(SG_ATC, SG_ALERT, "Unable to load default voice : "
|
||||||
|
<< e.getFormattedMessage().c_str());
|
||||||
|
voice = false;
|
||||||
|
delete voice1;
|
||||||
|
voice1 = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (voice)
|
||||||
|
return voice1;
|
||||||
|
#endif
|
||||||
|
return NULL;
|
||||||
|
case TOWER:
|
||||||
|
return NULL;
|
||||||
|
case APPROACH:
|
||||||
|
return NULL;
|
||||||
|
case GROUND:
|
||||||
|
return NULL;
|
||||||
|
default:
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
class RangeFilter : public CommStation::Filter
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
RangeFilter( const SGGeod & pos ) :
|
||||||
|
CommStation::Filter(),
|
||||||
|
_cart(SGVec3d::fromGeod(pos)),
|
||||||
|
_pos(pos)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool pass(FGPositioned* aPos) const
|
||||||
|
{
|
||||||
|
flightgear::CommStation * stn = dynamic_cast<flightgear::CommStation*>(aPos);
|
||||||
|
if( NULL == stn )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// do the range check in cartesian space, since the distances are potentially
|
||||||
|
// large enough that the geodetic functions become unstable
|
||||||
|
// (eg, station on opposite side of the planet)
|
||||||
|
double rangeM = SGMiscd::max( stn->rangeNm(), 10.0 ) * SG_NM_TO_METER;
|
||||||
|
double d2 = distSqr( aPos->cart(), _cart);
|
||||||
|
|
||||||
|
return d2 <= (rangeM * rangeM);
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
SGVec3d _cart;
|
||||||
|
SGGeod _pos;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Search for ATC stations by frequency
|
||||||
|
void FGATISMgr::FreqSearch(const unsigned int unit)
|
||||||
|
{
|
||||||
|
double frequency = radios[unit].freq->getDoubleValue();
|
||||||
|
|
||||||
|
// Note: 122.375 must be rounded DOWN to 12237
|
||||||
|
// in order to be consistent with apt.dat et cetera.
|
||||||
|
int freqKhz = static_cast<int>(frequency * 100.0 + 0.25);
|
||||||
|
|
||||||
|
_aircraftPos = SGGeod::fromDegFt(lon_node->getDoubleValue(),
|
||||||
|
lat_node->getDoubleValue(), elev_node->getDoubleValue());
|
||||||
|
|
||||||
|
RangeFilter rangeFilter(_aircraftPos );
|
||||||
|
CommStation* sta = CommStation::findByFreq(freqKhz, _aircraftPos, &rangeFilter );
|
||||||
|
radios[unit].station->SetStation(sta);
|
||||||
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
// ATCMgr.hxx - definition of FGATCMgr
|
// ATISmgr.hxx - definition of FGATISMgr
|
||||||
// - a global management class for FlightGear generated ATC
|
// - a global management class for FlightGear generated ATIS
|
||||||
//
|
//
|
||||||
// Written by David Luff, started February 2002.
|
// Written by David Luff, started February 2002.
|
||||||
//
|
//
|
||||||
|
@ -30,23 +30,26 @@
|
||||||
|
|
||||||
#include "ATC.hxx"
|
#include "ATC.hxx"
|
||||||
|
|
||||||
class FGATCMgr : public SGSubsystem
|
namespace flightgear
|
||||||
|
{
|
||||||
|
class CommStation;
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
SGPropertyNode_ptr freq;
|
||||||
|
FGATC* station;
|
||||||
|
} CommRadioData;
|
||||||
|
|
||||||
|
class FGATISMgr : public SGSubsystem
|
||||||
{
|
{
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
// A vector containing all comm radios
|
||||||
|
typedef std::vector<CommRadioData> radio_list_type;
|
||||||
|
radio_list_type radios;
|
||||||
|
|
||||||
bool initDone; // Hack - guard against update getting called before init
|
// Any member function of FGATISMgr is permitted to leave this iterator pointing
|
||||||
|
|
||||||
// A list of pointers to all currently active ATC classes
|
|
||||||
typedef std::map<std::string,FGATC*> atc_list_type;
|
|
||||||
typedef atc_list_type::iterator atc_list_iterator;
|
|
||||||
typedef atc_list_type::const_iterator atc_list_const_iterator;
|
|
||||||
|
|
||||||
// Everything put in this list should be created dynamically
|
|
||||||
// on the heap and ***DELETED WHEN REMOVED!!!!!***
|
|
||||||
atc_list_type* atc_list;
|
|
||||||
atc_list_iterator atc_list_itr;
|
|
||||||
// Any member function of FGATCMgr is permitted to leave this iterator pointing
|
|
||||||
// at any point in or at the end of the list.
|
// at any point in or at the end of the list.
|
||||||
// Hence any new access must explicitly first check for atc_list.end() before dereferencing.
|
// Hence any new access must explicitly first check for atc_list.end() before dereferencing.
|
||||||
|
|
||||||
|
@ -58,19 +61,18 @@ private:
|
||||||
SGPropertyNode_ptr lat_node;
|
SGPropertyNode_ptr lat_node;
|
||||||
SGPropertyNode_ptr elev_node;
|
SGPropertyNode_ptr elev_node;
|
||||||
|
|
||||||
//FGATIS atis;
|
unsigned int _currentUnit;
|
||||||
|
unsigned int _maxCommRadios;
|
||||||
|
|
||||||
// Voice related stuff
|
// Voice related stuff
|
||||||
bool voice; // Flag - true if we are using voice
|
bool voice; // Flag - true if we are using voice
|
||||||
#ifdef ENABLE_AUDIO_SUPPORT
|
#ifdef ENABLE_AUDIO_SUPPORT
|
||||||
bool voiceOK; // Flag - true if at least one voice has loaded OK
|
FGATCVoice* voice1;
|
||||||
FGATCVoice* v1;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
FGATISMgr();
|
||||||
FGATCMgr();
|
~FGATISMgr();
|
||||||
~FGATCMgr();
|
|
||||||
|
|
||||||
void init();
|
void init();
|
||||||
|
|
||||||
|
@ -80,9 +82,8 @@ public:
|
||||||
|
|
||||||
void update(double dt);
|
void update(double dt);
|
||||||
|
|
||||||
|
|
||||||
// Return a pointer to an appropriate voice for a given type of ATC
|
// Return a pointer to an appropriate voice for a given type of ATC
|
||||||
// creating the voice if necessary - ie. make sure exactly one copy
|
// creating the voice if necessary - i.e. make sure exactly one copy
|
||||||
// of every voice in use exists in memory.
|
// of every voice in use exists in memory.
|
||||||
//
|
//
|
||||||
// TODO - in the future this will get more complex and dole out country/airport
|
// TODO - in the future this will get more complex and dole out country/airport
|
||||||
|
@ -90,25 +91,9 @@ public:
|
||||||
// at different airports in quick succession if a large enough selection are available.
|
// at different airports in quick succession if a large enough selection are available.
|
||||||
FGATCVoice* GetVoicePointer(const atc_type& type);
|
FGATCVoice* GetVoicePointer(const atc_type& type);
|
||||||
|
|
||||||
atc_type GetComm1ATCType() { return(INVALID/* kludge */); }
|
|
||||||
FGATC* GetComm1ATCPointer() { return(0/* kludge */); }
|
|
||||||
atc_type GetComm2ATCType() { return(INVALID); }
|
|
||||||
FGATC* GetComm2ATCPointer() { return(0/* kludge */); }
|
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
// Remove a class from the atc_list and delete it from memory
|
|
||||||
// *if* no other comm channel or AI plane is using it.
|
|
||||||
void ZapOtherService(const std::string ncunit, const std::string svc_name);
|
|
||||||
|
|
||||||
// Return a pointer to a class in the list given ICAO code and type
|
|
||||||
// Return NULL if the given service is not in the list
|
|
||||||
// - *** THE CALLING FUNCTION MUST CHECK FOR THIS ***
|
|
||||||
FGATC* FindInList(const std::string& id, const atc_type& tp);
|
|
||||||
|
|
||||||
// Search the specified radio for stations on the same frequency and in range.
|
// Search the specified radio for stations on the same frequency and in range.
|
||||||
void FreqSearch(const std::string navcomm, const int unit);
|
void FreqSearch(const unsigned int unit);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // _FG_ATCMGR_HXX
|
#endif // _FG_ATCMGR_HXX
|
|
@ -3,9 +3,8 @@ include(FlightGearComponent)
|
||||||
set(SOURCES
|
set(SOURCES
|
||||||
ATC.cxx
|
ATC.cxx
|
||||||
atis.cxx
|
atis.cxx
|
||||||
ATCDialogOld.cxx
|
|
||||||
ATCVoice.cxx
|
ATCVoice.cxx
|
||||||
ATCmgr.cxx
|
ATISmgr.cxx
|
||||||
ATCutils.cxx
|
ATCutils.cxx
|
||||||
ATCProjection.cxx
|
ATCProjection.cxx
|
||||||
)
|
)
|
||||||
|
@ -13,9 +12,8 @@ set(SOURCES
|
||||||
set(HEADERS
|
set(HEADERS
|
||||||
ATC.hxx
|
ATC.hxx
|
||||||
atis.hxx
|
atis.hxx
|
||||||
ATCDialogOld.hxx
|
|
||||||
ATCVoice.hxx
|
ATCVoice.hxx
|
||||||
ATCmgr.hxx
|
ATISmgr.hxx
|
||||||
ATCutils.hxx
|
ATCutils.hxx
|
||||||
ATCProjection.hxx
|
ATCProjection.hxx
|
||||||
atis_lexicon.hxx
|
atis_lexicon.hxx
|
||||||
|
|
|
@ -57,7 +57,7 @@
|
||||||
|
|
||||||
|
|
||||||
#include "ATCutils.hxx"
|
#include "ATCutils.hxx"
|
||||||
#include "ATCmgr.hxx"
|
#include "ATISmgr.hxx"
|
||||||
|
|
||||||
using std::string;
|
using std::string;
|
||||||
using std::map;
|
using std::map;
|
||||||
|
@ -66,7 +66,7 @@ using std::cout;
|
||||||
using boost::ref;
|
using boost::ref;
|
||||||
using boost::tie;
|
using boost::tie;
|
||||||
|
|
||||||
FGATIS::FGATIS() :
|
FGATIS::FGATIS(const string& commbase) :
|
||||||
transmission(""),
|
transmission(""),
|
||||||
trans_ident(""),
|
trans_ident(""),
|
||||||
old_volume(0),
|
old_volume(0),
|
||||||
|
@ -74,20 +74,8 @@ FGATIS::FGATIS() :
|
||||||
msg_OK(0),
|
msg_OK(0),
|
||||||
attention(0),
|
attention(0),
|
||||||
_prev_display(0),
|
_prev_display(0),
|
||||||
refname("atis")
|
_commbase(commbase)
|
||||||
{
|
{
|
||||||
FGATCMgr* pAtcMgr = globals->get_ATC_mgr();
|
|
||||||
if (!pAtcMgr)
|
|
||||||
{
|
|
||||||
SG_LOG(SG_ATC, SG_ALERT, "ERROR! No ATC manager! Oops...");
|
|
||||||
_vPtr = NULL;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
_vPtr = pAtcMgr->GetVoicePointer(ATIS);
|
|
||||||
_voiceOK = (_vPtr == NULL ? false : true);
|
|
||||||
if (!(_type != ATIS || _type == AWOS)) {
|
|
||||||
SG_LOG(SG_ATC, SG_ALERT, "ERROR - _type not ATIS or AWOS in atis.cxx");
|
|
||||||
}
|
|
||||||
fgTie("/environment/attention", this, (int_getter)0, &FGATIS::attend);
|
fgTie("/environment/attention", this, (int_getter)0, &FGATIS::attend);
|
||||||
|
|
||||||
///////////////
|
///////////////
|
||||||
|
@ -115,6 +103,18 @@ FGATIS::~FGATIS() {
|
||||||
fgUntie("/environment/attention");
|
fgUntie("/environment/attention");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FGATCVoice* FGATIS::GetVoicePointer()
|
||||||
|
{
|
||||||
|
FGATISMgr* pAtisMgr = globals->get_ATIS_mgr();
|
||||||
|
if (!pAtisMgr)
|
||||||
|
{
|
||||||
|
SG_LOG(SG_ATC, SG_ALERT, "ERROR! No ATIS manager! Oops...");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return pAtisMgr->GetVoicePointer(ATIS);
|
||||||
|
}
|
||||||
|
|
||||||
void FGATIS::Init() {
|
void FGATIS::Init() {
|
||||||
// Nothing to see here. Move along.
|
// Nothing to see here. Move along.
|
||||||
}
|
}
|
||||||
|
@ -137,6 +137,7 @@ FGATIS::attend (int attn)
|
||||||
void FGATIS::Update(double dt) {
|
void FGATIS::Update(double dt) {
|
||||||
cur_time = globals->get_time_params()->get_cur_time();
|
cur_time = globals->get_time_params()->get_cur_time();
|
||||||
msg_OK = (msg_time < cur_time);
|
msg_OK = (msg_time < cur_time);
|
||||||
|
|
||||||
#ifdef ATIS_TEST
|
#ifdef ATIS_TEST
|
||||||
if (msg_OK || _display != _prev_display) {
|
if (msg_OK || _display != _prev_display) {
|
||||||
cout << "ATIS Update: " << _display << " " << _prev_display
|
cout << "ATIS Update: " << _display << " " << _prev_display
|
||||||
|
@ -146,29 +147,27 @@ void FGATIS::Update(double dt) {
|
||||||
msg_time = cur_time;
|
msg_time = cur_time;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if(_display) {
|
|
||||||
double volume(0);
|
if(_display)
|
||||||
for (map<string,int>::iterator act = active_on.begin();
|
{
|
||||||
act != active_on.end(); act++) {
|
string prop = _commbase + "/volume";
|
||||||
string prop = "/instrumentation/" + act->first + "/volume";
|
double volume = globals->get_props()->getDoubleValue(prop.c_str());
|
||||||
volume += globals->get_props()->getDoubleValue(prop.c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if we need to update the message
|
// Check if we need to update the message
|
||||||
// - basically every hour and if the weather changes significantly at the station
|
// - basically every hour and if the weather changes significantly at the station
|
||||||
// If !_prev_display, the radio had been detuned for a while and our
|
// If !_prev_display, the radio had been detuned for a while and our
|
||||||
// "transmission" variable was lost when we were de-instantiated.
|
// "transmission" variable was lost when we were de-instantiated.
|
||||||
int rslt = GenTransmission(!_prev_display, attention);
|
int changed = GenTransmission(!_prev_display, attention);
|
||||||
TreeOut(msg_OK);
|
TreeOut(msg_OK);
|
||||||
if (rslt || volume != old_volume) {
|
if (changed || volume != old_volume) {
|
||||||
//cout << "ATIS calling ATC::render volume: " << volume << endl;
|
//cout << "ATIS calling ATC::render volume: " << volume << endl;
|
||||||
Render(transmission, volume, refname, true);
|
Render(transmission, volume, _commbase, true);
|
||||||
old_volume = volume;
|
old_volume = volume;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// We shouldn't be displaying
|
// We shouldn't be displaying
|
||||||
//cout << "ATIS.CXX - calling NoRender()..." << endl;
|
//cout << "ATIS.CXX - calling NoRender()..." << endl;
|
||||||
NoRender(refname);
|
NoRender(_commbase);
|
||||||
}
|
}
|
||||||
_prev_display = _display;
|
_prev_display = _display;
|
||||||
attention = 0;
|
attention = 0;
|
||||||
|
@ -517,26 +516,16 @@ int FGATIS::GenTransmission(const int regen, const int special) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Put the transmission into the property tree,
|
// Put the transmission into the property tree.
|
||||||
// possibly in multiple places if multiple radios
|
|
||||||
// are tuned to the same ATIS.
|
|
||||||
// You can see it by pointing a web browser
|
// You can see it by pointing a web browser
|
||||||
// at the property tree. The second comm radio is:
|
// at the property tree. The second comm radio is:
|
||||||
// http://localhost:5400/instrumentation/comm[1]
|
// http://localhost:5400/instrumentation/comm[1]
|
||||||
//
|
//
|
||||||
// (Also, if in debug mode, dump it to the console.)
|
// (Also, if in debug mode, dump it to the console.)
|
||||||
void FGATIS::TreeOut(int msg_OK){
|
void FGATIS::TreeOut(int msg_OK){
|
||||||
for (map<string,int>::iterator act = active_on.begin();
|
string prop = _commbase + "/atis";
|
||||||
act != active_on.end();
|
|
||||||
act++){
|
|
||||||
string prop = "/instrumentation/" + act->first + "/atis";
|
|
||||||
globals->get_props()->setStringValue(prop.c_str(),
|
globals->get_props()->setStringValue(prop.c_str(),
|
||||||
("<pre>\n" + transmission_readable + "</pre>\n").c_str());
|
("<pre>\n" + transmission_readable + "</pre>\n").c_str());
|
||||||
#ifdef ATIS_TEST
|
SG_LOG(SG_ATC, SG_DEBUG, "**** ATIS active on: " << prop <<
|
||||||
if (msg_OK) cout << "**** ATIS active on: " << prop << endl;
|
"transmission: " << transmission_readable);
|
||||||
#endif
|
|
||||||
}
|
|
||||||
#ifdef ATIS_TEST
|
|
||||||
if (msg_OK) cout << transmission_readable << endl;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,6 +60,8 @@ class FGATIS : public FGATC {
|
||||||
bool _prev_display; // Previous value of _display flag
|
bool _prev_display; // Previous value of _display flag
|
||||||
MSS _remap; // abbreviations to be expanded
|
MSS _remap; // abbreviations to be expanded
|
||||||
|
|
||||||
|
std::string _commbase;
|
||||||
|
|
||||||
// Aircraft position
|
// Aircraft position
|
||||||
// ATIS is actually a special case in that unlike other ATC eg.tower it doesn't actually know about
|
// ATIS is actually a special case in that unlike other ATC eg.tower it doesn't actually know about
|
||||||
// or the whereabouts of the aircraft it is transmitting to. However, to ensure consistancy of
|
// or the whereabouts of the aircraft it is transmitting to. However, to ensure consistancy of
|
||||||
|
@ -69,9 +71,9 @@ class FGATIS : public FGATC {
|
||||||
//SGPropertyNode_ptr airplane_lat_node;
|
//SGPropertyNode_ptr airplane_lat_node;
|
||||||
//SGPropertyNode_ptr airplane_elev_node;
|
//SGPropertyNode_ptr airplane_elev_node;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
FGATIS(void);
|
FGATIS(const std::string& commbase);
|
||||||
~FGATIS(void);
|
~FGATIS(void);
|
||||||
virtual void Init();
|
virtual void Init();
|
||||||
void attend (int);
|
void attend (int);
|
||||||
|
@ -81,11 +83,11 @@ class FGATIS : public FGATC {
|
||||||
|
|
||||||
//inline void set_type(const atc_type tp) {type = tp;}
|
//inline void set_type(const atc_type tp) {type = tp;}
|
||||||
inline const std::string& get_trans_ident() { return trans_ident; }
|
inline const std::string& get_trans_ident() { return trans_ident; }
|
||||||
inline void set_refname(const std::string& r) { refname = r; }
|
|
||||||
|
|
||||||
private:
|
protected:
|
||||||
|
virtual FGATCVoice* GetVoicePointer();
|
||||||
|
|
||||||
std::string refname; // Holds the refname of a transmission in progress
|
private:
|
||||||
|
|
||||||
// Generate the ATIS transmission text:
|
// Generate the ATIS transmission text:
|
||||||
int GenTransmission(const int regen, const int special);
|
int GenTransmission(const int regen, const int special);
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
//
|
//
|
||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with this program; if not, write to the Free Software
|
// along with this program; if not, write to the Free Software
|
||||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
//
|
//
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
@ -33,6 +33,7 @@
|
||||||
#include <simgear/misc/ResourceManager.hxx>
|
#include <simgear/misc/ResourceManager.hxx>
|
||||||
#include <simgear/misc/strutils.hxx>
|
#include <simgear/misc/strutils.hxx>
|
||||||
#include <simgear/structure/exception.hxx>
|
#include <simgear/structure/exception.hxx>
|
||||||
|
#include <simgear/math/SGMath.hxx>
|
||||||
#include <Main/fg_props.hxx>
|
#include <Main/fg_props.hxx>
|
||||||
#include "flightrecorder.hxx"
|
#include "flightrecorder.hxx"
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
//
|
//
|
||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with this program; if not, write to the Free Software
|
// along with this program; if not, write to the Free Software
|
||||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
//
|
//
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
|
@ -32,7 +32,6 @@
|
||||||
#include <simgear/props/props.hxx>
|
#include <simgear/props/props.hxx>
|
||||||
#include <simgear/structure/subsystem_mgr.hxx>
|
#include <simgear/structure/subsystem_mgr.hxx>
|
||||||
#include <simgear/debug/logstream.hxx>
|
#include <simgear/debug/logstream.hxx>
|
||||||
#include <simgear/route/waypoint.hxx>
|
|
||||||
#include <Main/globals.hxx>
|
#include <Main/globals.hxx>
|
||||||
#include <Main/fg_props.hxx>
|
#include <Main/fg_props.hxx>
|
||||||
#include <Airports/runways.hxx>
|
#include <Airports/runways.hxx>
|
||||||
|
|
|
@ -35,7 +35,6 @@
|
||||||
#include <osg/Shape>
|
#include <osg/Shape>
|
||||||
|
|
||||||
#include <simgear/debug/logstream.hxx>
|
#include <simgear/debug/logstream.hxx>
|
||||||
#include <simgear/route/waypoint.hxx>
|
|
||||||
#include <simgear/scene/material/EffectGeode.hxx>
|
#include <simgear/scene/material/EffectGeode.hxx>
|
||||||
#include <simgear/scene/material/matlib.hxx>
|
#include <simgear/scene/material/matlib.hxx>
|
||||||
#include <simgear/scene/material/mat.hxx>
|
#include <simgear/scene/material/mat.hxx>
|
||||||
|
@ -531,7 +530,7 @@ FGTaxiNode *FGGroundNetwork::findNode(unsigned idx)
|
||||||
return itr->getAddress();
|
return itr->getAddress();
|
||||||
} */
|
} */
|
||||||
|
|
||||||
if ((idx >= 0) && (idx < nodes.size()))
|
if (idx < nodes.size())
|
||||||
return nodes[idx]->getAddress();
|
return nodes[idx]->getAddress();
|
||||||
else
|
else
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -31,7 +31,6 @@
|
||||||
|
|
||||||
|
|
||||||
#include <simgear/compiler.h>
|
#include <simgear/compiler.h>
|
||||||
#include <simgear/route/waypoint.hxx>
|
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
#include <cstdlib>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
#include <simgear/compiler.h>
|
#include <simgear/compiler.h>
|
||||||
|
|
|
@ -172,7 +172,7 @@ void FGRunway::setReciprocalRunway(FGRunway* other)
|
||||||
_reciprocal = other;
|
_reciprocal = other;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<flightgear::SID*> FGRunway::getSIDs()
|
std::vector<flightgear::SID*> FGRunway::getSIDs() const
|
||||||
{
|
{
|
||||||
std::vector<flightgear::SID*> result;
|
std::vector<flightgear::SID*> result;
|
||||||
for (unsigned int i=0; i<_airport->numSIDs(); ++i) {
|
for (unsigned int i=0; i<_airport->numSIDs(); ++i) {
|
||||||
|
@ -185,7 +185,7 @@ std::vector<flightgear::SID*> FGRunway::getSIDs()
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<flightgear::STAR*> FGRunway::getSTARs()
|
std::vector<flightgear::STAR*> FGRunway::getSTARs() const
|
||||||
{
|
{
|
||||||
std::vector<flightgear::STAR*> result;
|
std::vector<flightgear::STAR*> result;
|
||||||
for (unsigned int i=0; i<_airport->numSTARs(); ++i) {
|
for (unsigned int i=0; i<_airport->numSTARs(); ++i) {
|
||||||
|
@ -198,3 +198,16 @@ std::vector<flightgear::STAR*> FGRunway::getSTARs()
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<flightgear::Approach*> FGRunway::getApproaches() const
|
||||||
|
{
|
||||||
|
std::vector<flightgear::Approach*> result;
|
||||||
|
for (unsigned int i=0; i<_airport->numApproaches(); ++i) {
|
||||||
|
flightgear::Approach* s = _airport->getApproachByIndex(i);
|
||||||
|
if (s->runway() == this) {
|
||||||
|
result.push_back(s);
|
||||||
|
}
|
||||||
|
} // of approaches at the airport iteration
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -36,6 +36,7 @@ class SGPropertyNode;
|
||||||
namespace flightgear {
|
namespace flightgear {
|
||||||
class SID;
|
class SID;
|
||||||
class STAR;
|
class STAR;
|
||||||
|
class Approach;
|
||||||
}
|
}
|
||||||
|
|
||||||
class FGRunway : public FGRunwayBase
|
class FGRunway : public FGRunwayBase
|
||||||
|
@ -124,12 +125,15 @@ public:
|
||||||
/**
|
/**
|
||||||
* Get SIDs (DPs) associated with this runway
|
* Get SIDs (DPs) associated with this runway
|
||||||
*/
|
*/
|
||||||
std::vector<flightgear::SID*> getSIDs();
|
std::vector<flightgear::SID*> getSIDs() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get STARs associared with this runway
|
* Get STARs associared with this runway
|
||||||
*/
|
*/
|
||||||
std::vector<flightgear::STAR*> getSTARs();
|
std::vector<flightgear::STAR*> getSTARs() const;
|
||||||
|
|
||||||
|
|
||||||
|
std::vector<flightgear::Approach*> getApproaches() const;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -329,6 +329,9 @@ FGAirport* FGAirport::findClosest(const SGGeod& aPos, double aCuttofNm, Filter*
|
||||||
FGAirport::HardSurfaceFilter::HardSurfaceFilter(double minLengthFt) :
|
FGAirport::HardSurfaceFilter::HardSurfaceFilter(double minLengthFt) :
|
||||||
mMinLengthFt(minLengthFt)
|
mMinLengthFt(minLengthFt)
|
||||||
{
|
{
|
||||||
|
if (minLengthFt < 0.0) {
|
||||||
|
mMinLengthFt = fgGetDouble("/sim/navdb/min-runway-length-ft", 0.0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FGAirport::HardSurfaceFilter::passAirport(FGAirport* aApt) const
|
bool FGAirport::HardSurfaceFilter::passAirport(FGAirport* aApt) const
|
||||||
|
@ -406,7 +409,7 @@ void FGAirport::loadProcedures() const
|
||||||
}
|
}
|
||||||
|
|
||||||
SG_LOG(SG_GENERAL, SG_INFO, ident() << ": loading procedures from " << path.str());
|
SG_LOG(SG_GENERAL, SG_INFO, ident() << ": loading procedures from " << path.str());
|
||||||
Route::loadAirportProcedures(path, const_cast<FGAirport*>(this));
|
RouteBase::loadAirportProcedures(path, const_cast<FGAirport*>(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
void FGAirport::loadSceneryDefinitions() const
|
void FGAirport::loadSceneryDefinitions() const
|
||||||
|
@ -469,128 +472,6 @@ void FGAirport::readTowerData(SGPropertyNode* aRoot)
|
||||||
_tower_location = SGGeod::fromDegM(lon, lat, fieldElevationM + elevM);
|
_tower_location = SGGeod::fromDegM(lon, lat, fieldElevationM + elevM);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FGAirport::buildApproach(Waypt* aEnroute, STAR* aSTAR, FGRunway* aRwy, WayptVec& aRoute)
|
|
||||||
{
|
|
||||||
loadProcedures();
|
|
||||||
|
|
||||||
if ((aRwy && (aRwy->airport() != this))) {
|
|
||||||
throw sg_exception("invalid parameters", "FGAirport::buildApproach");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (aSTAR) {
|
|
||||||
bool ok = aSTAR->route(aRwy, aEnroute, aRoute);
|
|
||||||
if (!ok) {
|
|
||||||
SG_LOG(SG_GENERAL, SG_WARN, ident() << ": build approach, STAR " << aSTAR->ident()
|
|
||||||
<< " failed to route from transition " << aEnroute->ident());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} else if (aEnroute) {
|
|
||||||
// no a STAR specified, just use enroute point directly
|
|
||||||
aRoute.push_back(aEnroute);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!aRwy) {
|
|
||||||
// no runway selected yet, but we loaded the STAR, so that's fine, we're done
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// build the approach (possibly including transition), and including the missed segment
|
|
||||||
vector<Approach*> aps;
|
|
||||||
for (unsigned int j=0; j<mApproaches.size();++j) {
|
|
||||||
if (mApproaches[j]->runway() == aRwy) {
|
|
||||||
aps.push_back(mApproaches[j]);
|
|
||||||
}
|
|
||||||
} // of approach filter by runway
|
|
||||||
|
|
||||||
if (aps.empty()) {
|
|
||||||
SG_LOG(SG_GENERAL, SG_INFO, ident() << "; no approaches defined for runway " << aRwy->ident());
|
|
||||||
// could build a fallback approach here
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (unsigned int k=0; k<aps.size(); ++k) {
|
|
||||||
if (aps[k]->route(aRoute.back(), aRoute)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
} // of initial approach iteration
|
|
||||||
|
|
||||||
SG_LOG(SG_GENERAL, SG_INFO, ident() << ": unable to find transition to runway "
|
|
||||||
<< aRwy->ident() << ", assume vectors");
|
|
||||||
|
|
||||||
WayptRef v(new ATCVectors(NULL, this));
|
|
||||||
aRoute.push_back(v);
|
|
||||||
return aps.front()->routeFromVectors(aRoute);
|
|
||||||
}
|
|
||||||
|
|
||||||
pair<flightgear::SID*, WayptRef>
|
|
||||||
FGAirport::selectSID(const SGGeod& aDest, FGRunway* aRwy)
|
|
||||||
{
|
|
||||||
loadProcedures();
|
|
||||||
|
|
||||||
WayptRef enroute;
|
|
||||||
flightgear::SID* sid = NULL;
|
|
||||||
double d = 1e9;
|
|
||||||
|
|
||||||
for (unsigned int i=0; i<mSIDs.size(); ++i) {
|
|
||||||
if (aRwy && !mSIDs[i]->isForRunway(aRwy)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
WayptRef e = mSIDs[i]->findBestTransition(aDest);
|
|
||||||
if (!e) {
|
|
||||||
continue; // strange, but let's not worry about it
|
|
||||||
}
|
|
||||||
|
|
||||||
// assert(e->isFixedPosition());
|
|
||||||
double ed = SGGeodesy::distanceM(aDest, e->position());
|
|
||||||
if (ed < d) { // new best match
|
|
||||||
enroute = e;
|
|
||||||
d = ed;
|
|
||||||
sid = mSIDs[i];
|
|
||||||
}
|
|
||||||
} // of SID iteration
|
|
||||||
|
|
||||||
if (!mSIDs.empty() && !sid) {
|
|
||||||
SG_LOG(SG_GENERAL, SG_INFO, ident() << "selectSID, no SID found (runway="
|
|
||||||
<< (aRwy ? aRwy->ident() : "no runway preference"));
|
|
||||||
}
|
|
||||||
|
|
||||||
return std::make_pair(sid, enroute);
|
|
||||||
}
|
|
||||||
|
|
||||||
pair<STAR*, WayptRef>
|
|
||||||
FGAirport::selectSTAR(const SGGeod& aOrigin, FGRunway* aRwy)
|
|
||||||
{
|
|
||||||
loadProcedures();
|
|
||||||
|
|
||||||
WayptRef enroute;
|
|
||||||
STAR* star = NULL;
|
|
||||||
double d = 1e9;
|
|
||||||
|
|
||||||
for (unsigned int i=0; i<mSTARs.size(); ++i) {
|
|
||||||
if (!mSTARs[i]->isForRunway(aRwy)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
SG_LOG(SG_GENERAL, SG_INFO, "STAR " << mSTARs[i]->ident() << " is valid for runway");
|
|
||||||
WayptRef e = mSTARs[i]->findBestTransition(aOrigin);
|
|
||||||
if (!e) {
|
|
||||||
continue; // strange, but let's not worry about it
|
|
||||||
}
|
|
||||||
|
|
||||||
// assert(e->isFixedPosition());
|
|
||||||
double ed = SGGeodesy::distanceM(aOrigin, e->position());
|
|
||||||
if (ed < d) { // new best match
|
|
||||||
enroute = e;
|
|
||||||
d = ed;
|
|
||||||
star = mSTARs[i];
|
|
||||||
}
|
|
||||||
} // of STAR iteration
|
|
||||||
|
|
||||||
return std::make_pair(star, enroute);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void FGAirport::addSID(flightgear::SID* aSid)
|
void FGAirport::addSID(flightgear::SID* aSid)
|
||||||
{
|
{
|
||||||
mSIDs.push_back(aSid);
|
mSIDs.push_back(aSid);
|
||||||
|
@ -666,6 +547,18 @@ Approach* FGAirport::getApproachByIndex(unsigned int aIndex) const
|
||||||
return mApproaches[aIndex];
|
return mApproaches[aIndex];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Approach* FGAirport::findApproachWithIdent(const std::string& aIdent) const
|
||||||
|
{
|
||||||
|
loadProcedures();
|
||||||
|
for (unsigned int i=0; i<mApproaches.size(); ++i) {
|
||||||
|
if (mApproaches[i]->ident() == aIdent) {
|
||||||
|
return mApproaches[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
void FGAirport::setCommStations(CommStationList& comms)
|
void FGAirport::setCommStations(CommStationList& comms)
|
||||||
{
|
{
|
||||||
mCommStations.swap(comms);
|
mCommStations.swap(comms);
|
||||||
|
|
|
@ -161,7 +161,7 @@ public:
|
||||||
class HardSurfaceFilter : public AirportFilter
|
class HardSurfaceFilter : public AirportFilter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
HardSurfaceFilter(double minLengthFt);
|
HardSurfaceFilter(double minLengthFt = -1);
|
||||||
|
|
||||||
virtual bool passAirport(FGAirport* aApt) const;
|
virtual bool passAirport(FGAirport* aApt) const;
|
||||||
|
|
||||||
|
@ -188,6 +188,7 @@ public:
|
||||||
|
|
||||||
unsigned int numApproaches() const;
|
unsigned int numApproaches() const;
|
||||||
flightgear::Approach* getApproachByIndex(unsigned int aIndex) const;
|
flightgear::Approach* getApproachByIndex(unsigned int aIndex) const;
|
||||||
|
flightgear::Approach* findApproachWithIdent(const std::string& aIdent) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Syntactic wrapper around FGPositioned::findClosest - find the closest
|
* Syntactic wrapper around FGPositioned::findClosest - find the closest
|
||||||
|
@ -216,22 +217,6 @@ public:
|
||||||
*/
|
*/
|
||||||
static char** searchNamesAndIdents(const std::string& aFilter);
|
static char** searchNamesAndIdents(const std::string& aFilter);
|
||||||
|
|
||||||
bool buildApproach(flightgear::Waypt* aEnroute, flightgear::STAR* aSTAR,
|
|
||||||
FGRunway* aRwy, flightgear::WayptVec& aRoute);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Given a destiation point, select the best SID and transition waypt from
|
|
||||||
* this airport. Returns (NULL,NULL) is no SIDs are defined, otherwise the
|
|
||||||
* best SID/transition is that which is closest to the destination point.
|
|
||||||
*/
|
|
||||||
std::pair<flightgear::SID*, flightgear::WayptRef> selectSID(const SGGeod& aDest, FGRunway* aRwy);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Select a STAR and enroute transition waypt, given an origin (departure) position.
|
|
||||||
* returns (NULL, NULL) is no suitable STAR is exists
|
|
||||||
*/
|
|
||||||
std::pair<flightgear::STAR*, flightgear::WayptRef> selectSTAR(const SGGeod& aOrigin, FGRunway* aRwy);
|
|
||||||
|
|
||||||
void setCommStations(flightgear::CommStationList& comms);
|
void setCommStations(flightgear::CommStationList& comms);
|
||||||
|
|
||||||
flightgear::CommStationList commStationsOfType(FGPositioned::Type aTy) const;
|
flightgear::CommStationList commStationsOfType(FGPositioned::Type aTy) const;
|
||||||
|
|
|
@ -18,8 +18,11 @@
|
||||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
#include <cstdlib>
|
||||||
|
|
||||||
#include "inputvalue.hxx"
|
#include "inputvalue.hxx"
|
||||||
#include <Main/fg_props.hxx>
|
#include <Main/fg_props.hxx>
|
||||||
|
|
||||||
using namespace FGXMLAutopilot;
|
using namespace FGXMLAutopilot;
|
||||||
|
|
||||||
PeriodicalValue::PeriodicalValue( SGPropertyNode_ptr root )
|
PeriodicalValue::PeriodicalValue( SGPropertyNode_ptr root )
|
||||||
|
|
|
@ -24,7 +24,6 @@
|
||||||
#ifndef HAVE_CONFIG_H
|
#ifndef HAVE_CONFIG_H
|
||||||
# include <config.h>
|
# include <config.h>
|
||||||
#endif
|
#endif
|
||||||
#include <simgear/math/SGMath.hxx>
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "logic.hxx"
|
#include "logic.hxx"
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -25,26 +25,21 @@
|
||||||
#define _ROUTE_MGR_HXX 1
|
#define _ROUTE_MGR_HXX 1
|
||||||
|
|
||||||
#include <simgear/props/props.hxx>
|
#include <simgear/props/props.hxx>
|
||||||
#include <simgear/route/waypoint.hxx>
|
|
||||||
#include <simgear/structure/subsystem_mgr.hxx>
|
#include <simgear/structure/subsystem_mgr.hxx>
|
||||||
|
|
||||||
#include <Navaids/route.hxx>
|
#include <Navaids/FlightPlan.hxx>
|
||||||
|
|
||||||
// forward decls
|
// forward decls
|
||||||
class SGPath;
|
class SGPath;
|
||||||
class PropertyWatcher;
|
class PropertyWatcher;
|
||||||
|
|
||||||
class FGAirport;
|
|
||||||
class FGRunway;
|
|
||||||
|
|
||||||
typedef SGSharedPtr<FGAirport> FGAirportRef;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Top level route manager class
|
* Top level route manager class
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class FGRouteMgr : public SGSubsystem
|
class FGRouteMgr : public SGSubsystem,
|
||||||
|
public flightgear::FlightPlan::Delegate
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
FGRouteMgr();
|
FGRouteMgr();
|
||||||
|
@ -56,51 +51,29 @@ public:
|
||||||
void unbind ();
|
void unbind ();
|
||||||
void update (double dt);
|
void update (double dt);
|
||||||
|
|
||||||
void insertWayptAtIndex(flightgear::Waypt* aWpt, int aIndex);
|
bool isRouteActive() const;
|
||||||
flightgear::WayptRef removeWayptAtIndex(int index);
|
|
||||||
|
int currentIndex() const;
|
||||||
|
|
||||||
|
void setFlightPlan(flightgear::FlightPlan* plan);
|
||||||
|
flightgear::FlightPlan* flightPlan() const;
|
||||||
|
|
||||||
void clearRoute();
|
void clearRoute();
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
ROUTE_HIGH_AIRWAYS, ///< high-level airways routing
|
|
||||||
ROUTE_LOW_AIRWAYS, ///< low-level airways routing
|
|
||||||
ROUTE_VOR ///< VOR-VOR routing
|
|
||||||
} RouteType;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Insert waypoints from index-1 to index. In practice this means you can
|
|
||||||
* 'fill in the gaps' between defined waypoints. If index=0, the departure
|
|
||||||
* airport is used as index-1; if index is -1, the destination airport is
|
|
||||||
* used as the final waypoint.
|
|
||||||
*/
|
|
||||||
bool routeToIndex(int index, RouteType aRouteType);
|
|
||||||
|
|
||||||
void autoRoute();
|
|
||||||
|
|
||||||
bool isRouteActive() const;
|
|
||||||
|
|
||||||
int currentIndex() const
|
|
||||||
{ return _currentIndex; }
|
|
||||||
|
|
||||||
flightgear::Waypt* currentWaypt() const;
|
flightgear::Waypt* currentWaypt() const;
|
||||||
flightgear::Waypt* nextWaypt() const;
|
|
||||||
flightgear::Waypt* previousWaypt() const;
|
|
||||||
|
|
||||||
const flightgear::WayptVec& waypts() const
|
int numLegs() const;
|
||||||
{ return _route; }
|
|
||||||
|
|
||||||
|
// deprecated
|
||||||
int numWaypts() const
|
int numWaypts() const
|
||||||
{ return _route.size(); }
|
{ return numLegs(); }
|
||||||
|
|
||||||
|
// deprecated
|
||||||
flightgear::Waypt* wayptAtIndex(int index) const;
|
flightgear::Waypt* wayptAtIndex(int index) const;
|
||||||
|
|
||||||
SGPropertyNode_ptr wayptNodeAtIndex(int index) const;
|
SGPropertyNode_ptr wayptNodeAtIndex(int index) const;
|
||||||
|
|
||||||
/**
|
void removeLegAtIndex(int aIndex);
|
||||||
* Find a waypoint in the route, by position, and return its index, or
|
|
||||||
* -1 if no matching waypoint was found in the route.
|
|
||||||
*/
|
|
||||||
int findWayptIndex(const SGGeod& aPos) const;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Activate a built route. This checks for various mandatory pieces of
|
* Activate a built route. This checks for various mandatory pieces of
|
||||||
|
@ -125,38 +98,20 @@ public:
|
||||||
bool saveRoute(const SGPath& p);
|
bool saveRoute(const SGPath& p);
|
||||||
bool loadRoute(const SGPath& p);
|
bool loadRoute(const SGPath& p);
|
||||||
|
|
||||||
|
flightgear::WayptRef waypointFromString(const std::string& target);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper command to setup current airport/runway if necessary
|
* Helper command to setup current airport/runway if necessary
|
||||||
*/
|
*/
|
||||||
void initAtPosition();
|
void initAtPosition();
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a WayPoint from a string in the following format:
|
|
||||||
* - simple identifier
|
|
||||||
* - decimal-lon,decimal-lat
|
|
||||||
* - airport-id/runway-id
|
|
||||||
* - navaid/radial-deg/offset-nm
|
|
||||||
*/
|
|
||||||
flightgear::WayptRef waypointFromString(const std::string& target);
|
|
||||||
|
|
||||||
FGAirportRef departureAirport() const;
|
|
||||||
FGAirportRef destinationAirport() const;
|
|
||||||
|
|
||||||
FGRunway* departureRunway() const;
|
|
||||||
FGRunway* destinationRunway() const;
|
|
||||||
private:
|
private:
|
||||||
flightgear::WayptVec _route;
|
flightgear::FlightPlan* _plan;
|
||||||
int _currentIndex;
|
|
||||||
|
|
||||||
time_t _takeoffTime;
|
time_t _takeoffTime;
|
||||||
time_t _touchdownTime;
|
time_t _touchdownTime;
|
||||||
FGAirportRef _departure;
|
|
||||||
FGAirportRef _destination;
|
|
||||||
|
|
||||||
// automatic inputs
|
// automatic inputs
|
||||||
SGPropertyNode_ptr lon;
|
|
||||||
SGPropertyNode_ptr lat;
|
|
||||||
SGPropertyNode_ptr alt;
|
|
||||||
SGPropertyNode_ptr magvar;
|
SGPropertyNode_ptr magvar;
|
||||||
|
|
||||||
// automatic outputs
|
// automatic outputs
|
||||||
|
@ -181,8 +136,6 @@ private:
|
||||||
SGPropertyNode_ptr _pathNode;
|
SGPropertyNode_ptr _pathNode;
|
||||||
SGPropertyNode_ptr _currentWpt;
|
SGPropertyNode_ptr _currentWpt;
|
||||||
|
|
||||||
/// integer property corresponding to the RouteType enum
|
|
||||||
SGPropertyNode_ptr _routingType;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Signal property to notify people that the route was edited
|
* Signal property to notify people that the route was edited
|
||||||
|
@ -194,6 +147,8 @@ private:
|
||||||
*/
|
*/
|
||||||
SGPropertyNode_ptr _finished;
|
SGPropertyNode_ptr _finished;
|
||||||
|
|
||||||
|
SGPropertyNode_ptr _flightplanChanged;
|
||||||
|
|
||||||
void setETAPropertyFromDistance(SGPropertyNode_ptr aProp, double aDistance);
|
void setETAPropertyFromDistance(SGPropertyNode_ptr aProp, double aDistance);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -212,31 +167,21 @@ private:
|
||||||
|
|
||||||
SGPropertyNode_ptr input;
|
SGPropertyNode_ptr input;
|
||||||
SGPropertyNode_ptr weightOnWheels;
|
SGPropertyNode_ptr weightOnWheels;
|
||||||
|
SGPropertyNode_ptr groundSpeed;
|
||||||
|
|
||||||
InputListener *listener;
|
InputListener *listener;
|
||||||
SGPropertyNode_ptr mirror;
|
SGPropertyNode_ptr mirror;
|
||||||
|
|
||||||
void departureChanged();
|
|
||||||
void buildDeparture(flightgear::WayptRef enroute, flightgear::WayptVec& wps);
|
|
||||||
|
|
||||||
void arrivalChanged();
|
|
||||||
void buildArrival(flightgear::WayptRef enroute, flightgear::WayptVec& wps);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper to keep various pieces of state in sync when the route is
|
* Helper to keep various pieces of state in sync when the route is
|
||||||
* modified (waypoints added, inserted, removed). Notably, this fires the
|
* modified (waypoints added, inserted, removed). Notably, this fires the
|
||||||
* 'edited' signal.
|
* 'edited' signal.
|
||||||
*/
|
*/
|
||||||
void waypointsChanged();
|
virtual void waypointsChanged();
|
||||||
|
|
||||||
void update_mirror();
|
void update_mirror();
|
||||||
|
|
||||||
void currentWaypointChanged();
|
virtual void currentWaypointChanged();
|
||||||
|
|
||||||
/**
|
|
||||||
* Parse a route/wp node (from a saved, property-lsit formatted route)
|
|
||||||
*/
|
|
||||||
void parseRouteWaypoint(SGPropertyNode* aWP);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if we've reached the final waypoint.
|
* Check if we've reached the final waypoint.
|
||||||
|
@ -244,14 +189,6 @@ private:
|
||||||
*/
|
*/
|
||||||
bool checkFinished();
|
bool checkFinished();
|
||||||
|
|
||||||
|
|
||||||
bool loadPlainTextRoute(const SGPath& path);
|
|
||||||
|
|
||||||
void loadVersion1XMLRoute(SGPropertyNode_ptr routeData);
|
|
||||||
void loadVersion2XMLRoute(SGPropertyNode_ptr routeData);
|
|
||||||
void loadXMLRouteHeader(SGPropertyNode_ptr routeData);
|
|
||||||
flightgear::WayptRef parseVersion1XMLWaypt(SGPropertyNode* aWP);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Predicate for helping the UI - test if at least one waypoint was
|
* Predicate for helping the UI - test if at least one waypoint was
|
||||||
* entered by the user (as opposed to being generated by the route-manager)
|
* entered by the user (as opposed to being generated by the route-manager)
|
||||||
|
@ -263,12 +200,27 @@ private:
|
||||||
const char* getDepartureName() const;
|
const char* getDepartureName() const;
|
||||||
void setDepartureICAO(const char* aIdent);
|
void setDepartureICAO(const char* aIdent);
|
||||||
|
|
||||||
|
const char* getDepartureRunway() const;
|
||||||
|
void setDepartureRunway(const char* aIdent);
|
||||||
|
|
||||||
|
const char* getSID() const;
|
||||||
|
void setSID(const char* aIdent);
|
||||||
|
|
||||||
const char* getDestinationICAO() const;
|
const char* getDestinationICAO() const;
|
||||||
const char* getDestinationName() const;
|
const char* getDestinationName() const;
|
||||||
void setDestinationICAO(const char* aIdent);
|
void setDestinationICAO(const char* aIdent);
|
||||||
|
|
||||||
PropertyWatcher* _departureWatcher;
|
const char* getDestinationRunway() const;
|
||||||
PropertyWatcher* _arrivalWatcher;
|
void setDestinationRunway(const char* aIdent);
|
||||||
|
|
||||||
|
const char* getApproach() const;
|
||||||
|
void setApproach(const char* aIdent);
|
||||||
|
|
||||||
|
const char* getSTAR() const;
|
||||||
|
void setSTAR(const char* aIdent);
|
||||||
|
|
||||||
|
double getDepartureFieldElevation() const;
|
||||||
|
double getDestinationFieldElevation() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,7 @@ foreach( mylibfolder
|
||||||
Aircraft
|
Aircraft
|
||||||
ATC
|
ATC
|
||||||
ATCDCL
|
ATCDCL
|
||||||
|
Canvas
|
||||||
Radio
|
Radio
|
||||||
Autopilot
|
Autopilot
|
||||||
Cockpit
|
Cockpit
|
||||||
|
|
19
src/Canvas/CMakeLists.txt
Normal file
19
src/Canvas/CMakeLists.txt
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
include(FlightGearComponent)
|
||||||
|
|
||||||
|
set(SOURCES
|
||||||
|
canvas.cxx
|
||||||
|
canvas_mgr.cxx
|
||||||
|
elements/element.cxx
|
||||||
|
elements/group.cxx
|
||||||
|
elements/text.cxx
|
||||||
|
)
|
||||||
|
|
||||||
|
set(HEADERS
|
||||||
|
canvas.hxx
|
||||||
|
canvas_mgr.hxx
|
||||||
|
elements/element.hxx
|
||||||
|
elements/group.hxx
|
||||||
|
elements/text.hxx
|
||||||
|
)
|
||||||
|
|
||||||
|
flightgear_component(Canvas "${SOURCES}" "${HEADERS}")
|
430
src/Canvas/canvas.cxx
Normal file
430
src/Canvas/canvas.cxx
Normal file
|
@ -0,0 +1,430 @@
|
||||||
|
// The canvas for rendering with the 2d api
|
||||||
|
//
|
||||||
|
// Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com>
|
||||||
|
//
|
||||||
|
// This program is free software; you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU General Public License as
|
||||||
|
// published by the Free Software Foundation; either version 2 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful, but
|
||||||
|
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
// General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program; if not, write to the Free Software
|
||||||
|
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
#include "canvas.hxx"
|
||||||
|
#include "elements/group.hxx"
|
||||||
|
|
||||||
|
#include <osg/Camera>
|
||||||
|
#include <osg/Geode>
|
||||||
|
#include <osgText/Text>
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
//#include <Main/globals.hxx>
|
||||||
|
//#include <Viewer/renderer.hxx>
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
/**
|
||||||
|
* Callback used to disable/enable rendering to the texture if it is not
|
||||||
|
* visible
|
||||||
|
*/
|
||||||
|
class CameraCullCallback:
|
||||||
|
public osg::NodeCallback
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
CameraCullCallback():
|
||||||
|
_render( true )
|
||||||
|
{}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enable rendering for the next frame
|
||||||
|
*/
|
||||||
|
void enableRendering()
|
||||||
|
{
|
||||||
|
_render = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
bool _render;
|
||||||
|
|
||||||
|
virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)
|
||||||
|
{
|
||||||
|
if( _render )
|
||||||
|
{
|
||||||
|
traverse(node, nv);
|
||||||
|
_render = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This callback is installed on every placement of the canvas in the scene to
|
||||||
|
* only render the canvas if at least one placement is visible
|
||||||
|
*/
|
||||||
|
class PlacementCullCallback:
|
||||||
|
public osg::NodeCallback
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
PlacementCullCallback(Canvas* canvas, CameraCullCallback* camera_cull):
|
||||||
|
_canvas( canvas ),
|
||||||
|
_camera_cull( camera_cull )
|
||||||
|
{}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
Canvas *_canvas;
|
||||||
|
CameraCullCallback *_camera_cull;
|
||||||
|
|
||||||
|
virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)
|
||||||
|
{
|
||||||
|
_camera_cull->enableRendering();
|
||||||
|
traverse(node, nv);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
Canvas::Canvas():
|
||||||
|
_size_x(-1),
|
||||||
|
_size_y(-1),
|
||||||
|
_view_width(-1),
|
||||||
|
_view_height(-1),
|
||||||
|
_status(0),
|
||||||
|
_node(0),
|
||||||
|
_sampling_dirty(false)
|
||||||
|
{
|
||||||
|
setStatusFlags(MISSING_SIZE_X | MISSING_SIZE_Y);
|
||||||
|
|
||||||
|
CameraCullCallback *camera_callback = new CameraCullCallback;
|
||||||
|
_camera_callback = camera_callback;
|
||||||
|
_cull_callback = new PlacementCullCallback(this, camera_callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
Canvas::~Canvas()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
int Canvas::getStatus() const
|
||||||
|
{
|
||||||
|
return _status;
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
void Canvas::reset(SGPropertyNode* node)
|
||||||
|
{
|
||||||
|
if( _node )
|
||||||
|
{
|
||||||
|
_node->untie("size[0]");
|
||||||
|
_node->untie("size[1]");
|
||||||
|
_node->untie("view[0]");
|
||||||
|
_node->untie("view[1]");
|
||||||
|
_node->untie("status");
|
||||||
|
_node->untie("status-msg");
|
||||||
|
_node->removeChangeListener(this);
|
||||||
|
_node = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
setStatusFlags(MISSING_SIZE_X | MISSING_SIZE_Y);
|
||||||
|
|
||||||
|
if( node )
|
||||||
|
{
|
||||||
|
_node = node;
|
||||||
|
_node->tie
|
||||||
|
(
|
||||||
|
"size[0]",
|
||||||
|
SGRawValueMethods<Canvas, int>( *this, &Canvas::getSizeX,
|
||||||
|
&Canvas::setSizeX )
|
||||||
|
);
|
||||||
|
_node->tie
|
||||||
|
(
|
||||||
|
"size[1]",
|
||||||
|
SGRawValueMethods<Canvas, int>( *this, &Canvas::getSizeY,
|
||||||
|
&Canvas::setSizeY )
|
||||||
|
);
|
||||||
|
_node->tie
|
||||||
|
(
|
||||||
|
"view[0]",
|
||||||
|
SGRawValueMethods<Canvas, int>( *this, &Canvas::getViewWidth,
|
||||||
|
&Canvas::setViewWidth )
|
||||||
|
);
|
||||||
|
_node->tie
|
||||||
|
(
|
||||||
|
"view[1]",
|
||||||
|
SGRawValueMethods<Canvas, int>( *this, &Canvas::getViewHeight,
|
||||||
|
&Canvas::setViewHeight )
|
||||||
|
);
|
||||||
|
_node->tie
|
||||||
|
(
|
||||||
|
"status",
|
||||||
|
SGRawValueMethods<Canvas, int>(*this, &Canvas::getStatus)
|
||||||
|
);
|
||||||
|
_node->tie
|
||||||
|
(
|
||||||
|
"status-msg",
|
||||||
|
SGRawValueMethods<Canvas, const char*>(*this, &Canvas::getStatusMsg)
|
||||||
|
);
|
||||||
|
_node->addChangeListener(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
void Canvas::update(double delta_time_sec)
|
||||||
|
{
|
||||||
|
if( !_texture.serviceable() )
|
||||||
|
{
|
||||||
|
if( _status != STATUS_OK )
|
||||||
|
return;
|
||||||
|
|
||||||
|
_texture.setSize(_size_x, _size_y);
|
||||||
|
_texture.useImageCoords(true);
|
||||||
|
_texture.useStencil(true);
|
||||||
|
_texture.allocRT(_camera_callback);
|
||||||
|
_texture.getCamera()->setClearColor(osg::Vec4(0.0f, 0.0f, 0.0f , 1.0f));
|
||||||
|
|
||||||
|
for( size_t i = 0; i < _groups.size(); ++i )
|
||||||
|
_texture.getCamera()->addChild( _groups[i]->getMatrixTransform() );
|
||||||
|
|
||||||
|
if( _texture.serviceable() )
|
||||||
|
{
|
||||||
|
setStatusFlags(STATUS_OK);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
setStatusFlags(CREATE_FAILED);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for( size_t i = 0; i < _groups.size(); ++i )
|
||||||
|
_groups[i]->update(delta_time_sec);
|
||||||
|
|
||||||
|
if( _sampling_dirty )
|
||||||
|
{
|
||||||
|
_texture.setSampling(
|
||||||
|
_node->getBoolValue("mipmapping"),
|
||||||
|
_node->getIntValue("coverage-samples"),
|
||||||
|
_node->getIntValue("color-samples")
|
||||||
|
);
|
||||||
|
_sampling_dirty = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
while( !_dirty_placements.empty() )
|
||||||
|
{
|
||||||
|
SGPropertyNode *node = _dirty_placements.back();
|
||||||
|
_dirty_placements.pop_back();
|
||||||
|
|
||||||
|
if( node->getIndex() >= static_cast<int>(_placements.size()) )
|
||||||
|
// New placement
|
||||||
|
_placements.resize(node->getIndex() + 1);
|
||||||
|
else
|
||||||
|
// Remove maybe already existing placements
|
||||||
|
clearPlacements(node->getIndex());
|
||||||
|
|
||||||
|
// add new placements
|
||||||
|
_placements[node->getIndex()] = _texture.set_texture(
|
||||||
|
node,
|
||||||
|
_texture.getTexture(),
|
||||||
|
_cull_callback
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
void Canvas::setSizeX(int sx)
|
||||||
|
{
|
||||||
|
if( _size_x == sx )
|
||||||
|
return;
|
||||||
|
_size_x = sx;
|
||||||
|
|
||||||
|
// TODO resize if texture already allocated
|
||||||
|
|
||||||
|
if( _size_x <= 0 )
|
||||||
|
setStatusFlags(MISSING_SIZE_X);
|
||||||
|
else
|
||||||
|
setStatusFlags(MISSING_SIZE_X, false);
|
||||||
|
|
||||||
|
// reset flag to allow creation with new size
|
||||||
|
setStatusFlags(CREATE_FAILED, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
int Canvas::getSizeX() const
|
||||||
|
{
|
||||||
|
return _size_x;
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
void Canvas::setSizeY(int sy)
|
||||||
|
{
|
||||||
|
if( _size_y == sy )
|
||||||
|
return;
|
||||||
|
_size_y = sy;
|
||||||
|
|
||||||
|
// TODO resize if texture already allocated
|
||||||
|
|
||||||
|
if( _size_y <= 0 )
|
||||||
|
setStatusFlags(MISSING_SIZE_Y);
|
||||||
|
else
|
||||||
|
setStatusFlags(MISSING_SIZE_Y, false);
|
||||||
|
|
||||||
|
// reset flag to allow creation with new size
|
||||||
|
setStatusFlags(CREATE_FAILED, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
int Canvas::getSizeY() const
|
||||||
|
{
|
||||||
|
return _size_y;
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
void Canvas::setViewWidth(int w)
|
||||||
|
{
|
||||||
|
if( _view_width == w )
|
||||||
|
return;
|
||||||
|
_view_width = w;
|
||||||
|
|
||||||
|
_texture.setViewSize(_view_width, _view_height);
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
int Canvas::getViewWidth() const
|
||||||
|
{
|
||||||
|
return _view_width;
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
void Canvas::setViewHeight(int h)
|
||||||
|
{
|
||||||
|
if( _view_height == h )
|
||||||
|
return;
|
||||||
|
_view_height = h;
|
||||||
|
|
||||||
|
_texture.setViewSize(_view_width, _view_height);
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
int Canvas::getViewHeight() const
|
||||||
|
{
|
||||||
|
return _view_height;
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
const char* Canvas::getStatusMsg() const
|
||||||
|
{
|
||||||
|
return _status_msg.c_str();
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
void Canvas::childAdded( SGPropertyNode * parent,
|
||||||
|
SGPropertyNode * child )
|
||||||
|
{
|
||||||
|
if( parent != _node )
|
||||||
|
return;
|
||||||
|
|
||||||
|
if( child->getNameString() == "group" )
|
||||||
|
{
|
||||||
|
_groups.push_back
|
||||||
|
(
|
||||||
|
boost::shared_ptr<canvas::Group>(new canvas::Group(child))
|
||||||
|
);
|
||||||
|
if( _texture.serviceable() )
|
||||||
|
_texture.getCamera()->addChild( _groups.back()->getMatrixTransform() );
|
||||||
|
}
|
||||||
|
else if( child->getNameString() == "placement" )
|
||||||
|
{
|
||||||
|
_dirty_placements.push_back(child);
|
||||||
|
}
|
||||||
|
// else
|
||||||
|
// std::cout << "Canvas::childAdded: " << child->getPath() << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
void Canvas::childRemoved( SGPropertyNode * parent,
|
||||||
|
SGPropertyNode * child )
|
||||||
|
{
|
||||||
|
if( parent != _node )
|
||||||
|
return;
|
||||||
|
|
||||||
|
if( child->getNameString() == "placement" )
|
||||||
|
clearPlacements(child->getIndex());
|
||||||
|
else
|
||||||
|
std::cout << "Canvas::childRemoved: " << child->getPath() << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
void Canvas::valueChanged(SGPropertyNode * node)
|
||||||
|
{
|
||||||
|
if( node->getParent()->getParent() == _node
|
||||||
|
&& node->getParent()->getNameString() == "placement" )
|
||||||
|
{
|
||||||
|
// prevent double updates...
|
||||||
|
for( size_t i = 0; i < _dirty_placements.size(); ++i )
|
||||||
|
{
|
||||||
|
if( node->getParent() == _dirty_placements[i] )
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_dirty_placements.push_back(node->getParent());
|
||||||
|
}
|
||||||
|
else if( node->getParent() == _node )
|
||||||
|
{
|
||||||
|
if( node->getNameString() == "mipmapping"
|
||||||
|
|| node->getNameString() == "coverage-samples"
|
||||||
|
|| node->getNameString() == "color-samples" )
|
||||||
|
_sampling_dirty = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
void Canvas::setStatusFlags(unsigned int flags, bool set)
|
||||||
|
{
|
||||||
|
if( set )
|
||||||
|
_status |= flags;
|
||||||
|
else
|
||||||
|
_status &= ~flags;
|
||||||
|
|
||||||
|
if( (_status & MISSING_SIZE_X) && (_status & MISSING_SIZE_Y) )
|
||||||
|
_status_msg = "Missing size";
|
||||||
|
else if( _status & MISSING_SIZE_X )
|
||||||
|
_status_msg = "Missing size-x";
|
||||||
|
else if( _status & MISSING_SIZE_Y )
|
||||||
|
_status_msg = "Missing size-y";
|
||||||
|
else if( _status & CREATE_FAILED )
|
||||||
|
_status_msg = "Creating render target failed";
|
||||||
|
else if( _status == STATUS_OK && !_texture.serviceable() )
|
||||||
|
_status_msg = "Creation pending...";
|
||||||
|
else
|
||||||
|
_status_msg = "Ok";
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
void Canvas::clearPlacements(int index)
|
||||||
|
{
|
||||||
|
Placements& placements = _placements.at(index);
|
||||||
|
while( !placements.empty() )
|
||||||
|
{
|
||||||
|
osg::ref_ptr<osg::Group> group = placements.back();
|
||||||
|
placements.pop_back();
|
||||||
|
|
||||||
|
assert( group->getNumParents() == 1 );
|
||||||
|
assert( group->getNumChildren() == 1 );
|
||||||
|
|
||||||
|
osg::Group *parent = group->getParent(0);
|
||||||
|
osg::Node *child = group->getChild(0);
|
||||||
|
|
||||||
|
parent->addChild(child);
|
||||||
|
group->removeChild(child);
|
||||||
|
parent->removeChild(group);
|
||||||
|
}
|
||||||
|
}
|
101
src/Canvas/canvas.hxx
Normal file
101
src/Canvas/canvas.hxx
Normal file
|
@ -0,0 +1,101 @@
|
||||||
|
// The canvas for rendering with the 2d api
|
||||||
|
//
|
||||||
|
// Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com>
|
||||||
|
//
|
||||||
|
// This program is free software; you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU General Public License as
|
||||||
|
// published by the Free Software Foundation; either version 2 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful, but
|
||||||
|
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
// General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program; if not, write to the Free Software
|
||||||
|
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
#ifndef CANVAS_HXX_
|
||||||
|
#define CANVAS_HXX_
|
||||||
|
|
||||||
|
#include <Instrumentation/od_gauge.hxx>
|
||||||
|
#include <simgear/props/props.hxx>
|
||||||
|
#include <osg/NodeCallback>
|
||||||
|
|
||||||
|
#include <boost/shared_ptr.hpp>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace canvas
|
||||||
|
{
|
||||||
|
class Group;
|
||||||
|
}
|
||||||
|
|
||||||
|
class Canvas:
|
||||||
|
public SGPropertyChangeListener
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
enum StatusFlags
|
||||||
|
{
|
||||||
|
STATUS_OK,
|
||||||
|
MISSING_SIZE_X = 0x0001,
|
||||||
|
MISSING_SIZE_Y = 0x0002,
|
||||||
|
CREATE_FAILED = 0x0004
|
||||||
|
};
|
||||||
|
|
||||||
|
Canvas();
|
||||||
|
virtual ~Canvas();
|
||||||
|
|
||||||
|
void reset(SGPropertyNode* node);
|
||||||
|
void update(double delta_time_sec);
|
||||||
|
|
||||||
|
void setSizeX(int sx);
|
||||||
|
int getSizeX() const;
|
||||||
|
|
||||||
|
void setSizeY(int sy);
|
||||||
|
int getSizeY() const;
|
||||||
|
|
||||||
|
void setViewWidth(int w);
|
||||||
|
int getViewWidth() const;
|
||||||
|
|
||||||
|
void setViewHeight(int h);
|
||||||
|
int getViewHeight() const;
|
||||||
|
|
||||||
|
int getStatus() const;
|
||||||
|
const char* getStatusMsg() const;
|
||||||
|
|
||||||
|
virtual void childAdded( SGPropertyNode * parent,
|
||||||
|
SGPropertyNode * child );
|
||||||
|
virtual void childRemoved( SGPropertyNode * parent,
|
||||||
|
SGPropertyNode * child );
|
||||||
|
virtual void valueChanged (SGPropertyNode * node);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
int _size_x,
|
||||||
|
_size_y,
|
||||||
|
_view_width,
|
||||||
|
_view_height;
|
||||||
|
|
||||||
|
int _status;
|
||||||
|
std::string _status_msg;
|
||||||
|
|
||||||
|
FGODGauge _texture;
|
||||||
|
SGPropertyNode *_node;
|
||||||
|
|
||||||
|
bool _sampling_dirty;
|
||||||
|
|
||||||
|
osg::ref_ptr<osg::NodeCallback> _camera_callback;
|
||||||
|
osg::ref_ptr<osg::NodeCallback> _cull_callback;
|
||||||
|
std::vector<SGPropertyNode*> _dirty_placements;
|
||||||
|
std::vector<Placements> _placements;
|
||||||
|
|
||||||
|
// TODO replace auto_ptr with unique_ptr as soon as C++11 is used!
|
||||||
|
std::vector<boost::shared_ptr<canvas::Group> > _groups;
|
||||||
|
|
||||||
|
void setStatusFlags(unsigned int flags, bool set = true);
|
||||||
|
void clearPlacements(int index);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* CANVAS_HXX_ */
|
144
src/Canvas/canvas_mgr.cxx
Normal file
144
src/Canvas/canvas_mgr.cxx
Normal file
|
@ -0,0 +1,144 @@
|
||||||
|
// Canvas with 2D rendering api
|
||||||
|
//
|
||||||
|
// Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com>
|
||||||
|
//
|
||||||
|
// This program is free software; you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU General Public License as
|
||||||
|
// published by the Free Software Foundation; either version 2 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful, but
|
||||||
|
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
// General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program; if not, write to the Free Software
|
||||||
|
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
#include "canvas_mgr.hxx"
|
||||||
|
#include "canvas.hxx"
|
||||||
|
|
||||||
|
#include <Main/fg_props.hxx>
|
||||||
|
|
||||||
|
#include <osg/Camera>
|
||||||
|
#include <osg/Texture2D>
|
||||||
|
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
CanvasMgr::CanvasMgr():
|
||||||
|
_props( fgGetNode("/canvas", true) )
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
CanvasMgr::~CanvasMgr()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
void CanvasMgr::init()
|
||||||
|
{
|
||||||
|
_props->addChangeListener(this);
|
||||||
|
triggerChangeRecursive(_props);
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
void CanvasMgr::reinit()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
void CanvasMgr::shutdown()
|
||||||
|
{
|
||||||
|
_props->removeChangeListener(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
void CanvasMgr::bind()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
void CanvasMgr::unbind()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
void CanvasMgr::update(double delta_time_sec)
|
||||||
|
{
|
||||||
|
for( size_t i = 0; i < _canvases.size(); ++i )
|
||||||
|
_canvases[i].update(delta_time_sec);
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
void CanvasMgr::childAdded( SGPropertyNode * parent,
|
||||||
|
SGPropertyNode * child )
|
||||||
|
{
|
||||||
|
if( parent != _props )
|
||||||
|
return;
|
||||||
|
|
||||||
|
if( child->getNameString() == "texture" )
|
||||||
|
textureAdded(child);
|
||||||
|
else
|
||||||
|
std::cout << "CanvasMgr::childAdded: " << child->getPath() << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
void CanvasMgr::childRemoved( SGPropertyNode * parent,
|
||||||
|
SGPropertyNode * child )
|
||||||
|
{
|
||||||
|
if( parent != _props )
|
||||||
|
return;
|
||||||
|
|
||||||
|
std::cout << "CanvasMgr::childRemoved: " << child->getPath() << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
void CanvasMgr::textureAdded(SGPropertyNode* node)
|
||||||
|
{
|
||||||
|
size_t index = node->getIndex();
|
||||||
|
|
||||||
|
if( index >= _canvases.size() )
|
||||||
|
{
|
||||||
|
if( index > _canvases.size() )
|
||||||
|
SG_LOG(SG_GL, SG_WARN, "Skipping unused texture slot(s)!");
|
||||||
|
SG_LOG(SG_GL, SG_INFO, "Add new texture[" << index << "]");
|
||||||
|
|
||||||
|
_canvases.resize(index + 1);
|
||||||
|
_canvases[index];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SG_LOG(SG_GL, SG_WARN, "texture[" << index << "] already exists!");
|
||||||
|
}
|
||||||
|
|
||||||
|
_canvases[index].reset(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
void CanvasMgr::triggerChangeRecursive(SGPropertyNode* node)
|
||||||
|
{
|
||||||
|
node->getParent()->fireChildAdded(node);
|
||||||
|
|
||||||
|
if( node->nChildren() == 0 && node->getType() != simgear::props::NONE )
|
||||||
|
return node->fireValueChanged();
|
||||||
|
|
||||||
|
for( int i = 0; i < node->nChildren(); ++i )
|
||||||
|
triggerChangeRecursive( node->getChild(i) );
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
template<class T>
|
||||||
|
T CanvasMgr::getParam(const SGPropertyNode* node, const char* prop)
|
||||||
|
{
|
||||||
|
const SGPropertyNode* child = node->getChild(prop);
|
||||||
|
if( !child )
|
||||||
|
throw std::runtime_error(std::string("Missing property ") + prop);
|
||||||
|
return getValue<T>(child);
|
||||||
|
}
|
76
src/Canvas/canvas_mgr.hxx
Normal file
76
src/Canvas/canvas_mgr.hxx
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
// Canvas with 2D rendering api
|
||||||
|
//
|
||||||
|
// Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com>
|
||||||
|
//
|
||||||
|
// This program is free software; you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU General Public License as
|
||||||
|
// published by the Free Software Foundation; either version 2 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful, but
|
||||||
|
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
// General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program; if not, write to the Free Software
|
||||||
|
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
#ifndef CANVAS_MGR_H_
|
||||||
|
#define CANVAS_MGR_H_
|
||||||
|
|
||||||
|
#include <simgear/props/props.hxx>
|
||||||
|
#include <simgear/structure/subsystem_mgr.hxx>
|
||||||
|
|
||||||
|
#include <boost/shared_ptr.hpp>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
class Canvas;
|
||||||
|
|
||||||
|
class CanvasMgr:
|
||||||
|
public SGSubsystem,
|
||||||
|
public SGPropertyChangeListener
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CanvasMgr();
|
||||||
|
virtual ~CanvasMgr();
|
||||||
|
|
||||||
|
virtual void init();
|
||||||
|
virtual void reinit();
|
||||||
|
virtual void shutdown();
|
||||||
|
|
||||||
|
virtual void bind();
|
||||||
|
virtual void unbind();
|
||||||
|
|
||||||
|
virtual void update(double delta_time_sec);
|
||||||
|
|
||||||
|
virtual void childAdded( SGPropertyNode * parent,
|
||||||
|
SGPropertyNode * child );
|
||||||
|
virtual void childRemoved( SGPropertyNode * parent,
|
||||||
|
SGPropertyNode * child );
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
/** Root node for everything concerning the canvas system */
|
||||||
|
SGPropertyNode_ptr _props;
|
||||||
|
|
||||||
|
/** The actual canvases */
|
||||||
|
std::vector<Canvas> _canvases;
|
||||||
|
|
||||||
|
void textureAdded(SGPropertyNode* node);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Trigger a childAdded and valueChanged event for every child of node
|
||||||
|
* (Unlimited depth) and node itself.
|
||||||
|
*/
|
||||||
|
void triggerChangeRecursive(SGPropertyNode* node);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the value of a property or throw an exception if it doesn't exist.
|
||||||
|
*/
|
||||||
|
template<class T>
|
||||||
|
T getParam(const SGPropertyNode* node, const char* prop);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* CANVAS_MGR_H_ */
|
266
src/Canvas/elements/element.cxx
Normal file
266
src/Canvas/elements/element.cxx
Normal file
|
@ -0,0 +1,266 @@
|
||||||
|
// Interface for 2D canvas element
|
||||||
|
//
|
||||||
|
// Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com>
|
||||||
|
//
|
||||||
|
// This program is free software; you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU General Public License as
|
||||||
|
// published by the Free Software Foundation; either version 2 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful, but
|
||||||
|
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
// General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program; if not, write to the Free Software
|
||||||
|
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
#include "element.hxx"
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
|
#include <osg/Drawable>
|
||||||
|
|
||||||
|
namespace canvas
|
||||||
|
{
|
||||||
|
const std::string NAME_TRANSFORM = "tf";
|
||||||
|
const std::string NAME_COLOR = "color";
|
||||||
|
const std::string NAME_COLOR_FILL = "color-fill";
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
Element::~Element()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
SGPropertyNode* Element::getPropertyNode()
|
||||||
|
{
|
||||||
|
return _node;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
void Element::update(double dt)
|
||||||
|
{
|
||||||
|
if( _transform_dirty )
|
||||||
|
{
|
||||||
|
osg::Matrix m;
|
||||||
|
for( size_t i = 0; i < _transform_types.size(); ++i )
|
||||||
|
{
|
||||||
|
// Skip unused indizes...
|
||||||
|
if( _transform_types[i] == TT_NONE )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
SGPropertyNode* tf_node = _node->getChild("tf", i, true);
|
||||||
|
|
||||||
|
// Build up the matrix representation of the current transform node
|
||||||
|
osg::Matrix tf;
|
||||||
|
switch( _transform_types[i] )
|
||||||
|
{
|
||||||
|
case TT_MATRIX:
|
||||||
|
tf = osg::Matrix( tf_node->getDoubleValue("a", 1),
|
||||||
|
tf_node->getDoubleValue("b", 0), 0, 0,
|
||||||
|
|
||||||
|
tf_node->getDoubleValue("c", 0),
|
||||||
|
tf_node->getDoubleValue("d", 1), 0, 0,
|
||||||
|
|
||||||
|
0, 0, 1, 0,
|
||||||
|
tf_node->getDoubleValue("e", 0),
|
||||||
|
tf_node->getDoubleValue("f", 0), 0, 1 );
|
||||||
|
break;
|
||||||
|
case TT_TRANSLATE:
|
||||||
|
tf.makeTranslate( osg::Vec3f( tf_node->getDoubleValue("tx", 0),
|
||||||
|
tf_node->getDoubleValue("ty", 0),
|
||||||
|
0 ) );
|
||||||
|
break;
|
||||||
|
case TT_ROTATE:
|
||||||
|
tf.makeRotate( tf_node->getDoubleValue("rot", 0), 0, 0, 1 );
|
||||||
|
break;
|
||||||
|
case TT_SCALE:
|
||||||
|
{
|
||||||
|
float sx = tf_node->getDoubleValue("sx", 1);
|
||||||
|
// sy defaults to sx...
|
||||||
|
tf.makeScale( sx, tf_node->getDoubleValue("sy", sx), 1 );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
m.postMult( tf );
|
||||||
|
}
|
||||||
|
_transform->setMatrix(m);
|
||||||
|
_transform_dirty = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( _attributes_dirty & COLOR )
|
||||||
|
{
|
||||||
|
colorChanged( osg::Vec4( _color[0]->getFloatValue(),
|
||||||
|
_color[1]->getFloatValue(),
|
||||||
|
_color[2]->getFloatValue(),
|
||||||
|
1 ) );
|
||||||
|
_attributes_dirty &= ~COLOR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( _attributes_dirty & COLOR_FILL )
|
||||||
|
{
|
||||||
|
colorFillChanged( osg::Vec4( _color_fill[0]->getFloatValue(),
|
||||||
|
_color_fill[1]->getFloatValue(),
|
||||||
|
_color_fill[2]->getFloatValue(),
|
||||||
|
1 ) );
|
||||||
|
_attributes_dirty &= ~COLOR_FILL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( _drawable && (_attributes_dirty & BOUNDING_BOX) )
|
||||||
|
{
|
||||||
|
_bounding_box[0]->setFloatValue(_drawable->getBound()._min.x());
|
||||||
|
_bounding_box[1]->setFloatValue(_drawable->getBound()._min.y());
|
||||||
|
_bounding_box[2]->setFloatValue(_drawable->getBound()._max.x());
|
||||||
|
_bounding_box[3]->setFloatValue(_drawable->getBound()._max.y());
|
||||||
|
|
||||||
|
_attributes_dirty &= ~BOUNDING_BOX;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
osg::ref_ptr<osg::MatrixTransform> Element::getMatrixTransform()
|
||||||
|
{
|
||||||
|
return _transform;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
Element::Element(SGPropertyNode* node, uint32_t attributes_used):
|
||||||
|
_node( node ),
|
||||||
|
_drawable( 0 ),
|
||||||
|
_attributes_used( attributes_used ),
|
||||||
|
_attributes_dirty( 0 ),
|
||||||
|
_transform_dirty( false ),
|
||||||
|
_transform( new osg::MatrixTransform )
|
||||||
|
{
|
||||||
|
assert( _node );
|
||||||
|
_node->addChangeListener(this);
|
||||||
|
|
||||||
|
if( _attributes_used & COLOR )
|
||||||
|
linkColorNodes("color", _color, osg::Vec4f(0,1,0,1));
|
||||||
|
if( _attributes_used & COLOR_FILL )
|
||||||
|
linkColorNodes("color-fill", _color_fill);
|
||||||
|
if( _attributes_used & BOUNDING_BOX )
|
||||||
|
{
|
||||||
|
SGPropertyNode* bb = _node->getChild("bounding-box", 0, true);
|
||||||
|
_bounding_box[0] = bb->getChild("x-min", 0, true);
|
||||||
|
_bounding_box[1] = bb->getChild("y-min", 0, true);
|
||||||
|
_bounding_box[2] = bb->getChild("x-max", 0, true);
|
||||||
|
_bounding_box[3] = bb->getChild("y-max", 0, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
SG_LOG
|
||||||
|
(
|
||||||
|
SG_GL,
|
||||||
|
SG_DEBUG,
|
||||||
|
"New canvas element " << node->getPath()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
void Element::linkColorNodes( const char* name,
|
||||||
|
SGPropertyNode** nodes,
|
||||||
|
const osg::Vec4& def )
|
||||||
|
{
|
||||||
|
// Don't tie to allow the usage of aliases
|
||||||
|
SGPropertyNode* color = _node->getChild(name, 0, true);
|
||||||
|
|
||||||
|
static const char* color_names[] = {"red", "green", "blue"};
|
||||||
|
for( size_t i = 0; i < sizeof(color_names)/sizeof(color_names[0]); ++i )
|
||||||
|
{
|
||||||
|
color->setFloatValue
|
||||||
|
(
|
||||||
|
color_names[i],
|
||||||
|
color->getFloatValue(color_names[i], def[i])
|
||||||
|
);
|
||||||
|
nodes[i] = color->getChild(color_names[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
void Element::childAdded(SGPropertyNode* parent, SGPropertyNode* child)
|
||||||
|
{
|
||||||
|
if( parent == _node )
|
||||||
|
{
|
||||||
|
if( child->getNameString() == NAME_TRANSFORM )
|
||||||
|
{
|
||||||
|
if( child->getIndex() >= static_cast<int>(_transform_types.size()) )
|
||||||
|
_transform_types.resize( child->getIndex() + 1 );
|
||||||
|
|
||||||
|
_transform_types[ child->getIndex() ] = TT_NONE;
|
||||||
|
_transform_dirty = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
childAdded(child);
|
||||||
|
}
|
||||||
|
else if( parent->getParent() == _node
|
||||||
|
&& parent->getNameString() == NAME_TRANSFORM )
|
||||||
|
{
|
||||||
|
assert(parent->getIndex() < static_cast<int>(_transform_types.size()));
|
||||||
|
|
||||||
|
const std::string& name = child->getNameString();
|
||||||
|
|
||||||
|
TransformType& type = _transform_types[parent->getIndex()];
|
||||||
|
|
||||||
|
if( name == "a" || name == "b" || name == "c"
|
||||||
|
|| name == "d" || name == "e" || name == "f" )
|
||||||
|
type = TT_MATRIX;
|
||||||
|
else if( name == "tx" || name == "ty" )
|
||||||
|
type = TT_TRANSLATE;
|
||||||
|
else if( name == "rot" )
|
||||||
|
type = TT_ROTATE;
|
||||||
|
else if( name == "sx" || name == "sy" )
|
||||||
|
type = TT_SCALE;
|
||||||
|
else
|
||||||
|
SG_LOG
|
||||||
|
(
|
||||||
|
SG_GL,
|
||||||
|
SG_WARN,
|
||||||
|
"Unknown transform element " << child->getPath()
|
||||||
|
);
|
||||||
|
|
||||||
|
_transform_dirty = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
void Element::childRemoved(SGPropertyNode* parent, SGPropertyNode* child)
|
||||||
|
{
|
||||||
|
if( parent != _node )
|
||||||
|
return;
|
||||||
|
|
||||||
|
if( child->getNameString() == NAME_TRANSFORM )
|
||||||
|
{
|
||||||
|
assert(child->getIndex() < static_cast<int>(_transform_types.size()));
|
||||||
|
_transform_types[ child->getIndex() ] = TT_NONE;
|
||||||
|
|
||||||
|
while( !_transform_types.empty() && _transform_types.back() == TT_NONE )
|
||||||
|
_transform_types.pop_back();
|
||||||
|
|
||||||
|
_transform_dirty = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
childRemoved(child);
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
void Element::valueChanged(SGPropertyNode* child)
|
||||||
|
{
|
||||||
|
SGPropertyNode *parent = child->getParent();
|
||||||
|
if( parent->getParent() == _node )
|
||||||
|
{
|
||||||
|
if( parent->getNameString() == NAME_TRANSFORM )
|
||||||
|
_transform_dirty = true;
|
||||||
|
else if( parent->getNameString() == NAME_COLOR )
|
||||||
|
_attributes_dirty |= COLOR;
|
||||||
|
else if( parent->getNameString() == NAME_COLOR_FILL )
|
||||||
|
_attributes_dirty |= COLOR_FILL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
childChanged(child);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace canvas
|
107
src/Canvas/elements/element.hxx
Normal file
107
src/Canvas/elements/element.hxx
Normal file
|
@ -0,0 +1,107 @@
|
||||||
|
// Interface for 2D canvas element
|
||||||
|
//
|
||||||
|
// Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com>
|
||||||
|
//
|
||||||
|
// This program is free software; you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU General Public License as
|
||||||
|
// published by the Free Software Foundation; either version 2 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful, but
|
||||||
|
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
// General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program; if not, write to the Free Software
|
||||||
|
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
#ifndef CANVAS_ELEMENT_HXX_
|
||||||
|
#define CANVAS_ELEMENT_HXX_
|
||||||
|
|
||||||
|
#include <simgear/props/props.hxx>
|
||||||
|
#include <osg/MatrixTransform>
|
||||||
|
#include <simgear/misc/stdint.hxx> // for uint32_t
|
||||||
|
|
||||||
|
namespace osg
|
||||||
|
{
|
||||||
|
class Drawable;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace canvas
|
||||||
|
{
|
||||||
|
|
||||||
|
class Element:
|
||||||
|
private SGPropertyChangeListener
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual ~Element() = 0;
|
||||||
|
SGPropertyNode* getPropertyNode();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called every frame to update internal state
|
||||||
|
*
|
||||||
|
* @param dt Frame time in seconds
|
||||||
|
*/
|
||||||
|
virtual void update(double dt);
|
||||||
|
|
||||||
|
osg::ref_ptr<osg::MatrixTransform> getMatrixTransform();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
enum Attributes
|
||||||
|
{
|
||||||
|
COLOR = 0x0001,
|
||||||
|
COLOR_FILL = 0x0002,
|
||||||
|
BOUNDING_BOX = 0x0004
|
||||||
|
};
|
||||||
|
|
||||||
|
enum TransformType
|
||||||
|
{
|
||||||
|
TT_NONE,
|
||||||
|
TT_MATRIX,
|
||||||
|
TT_TRANSLATE,
|
||||||
|
TT_ROTATE,
|
||||||
|
TT_SCALE
|
||||||
|
};
|
||||||
|
|
||||||
|
SGPropertyNode *_node;
|
||||||
|
osg::Drawable *_drawable;
|
||||||
|
|
||||||
|
uint32_t _attributes_used;
|
||||||
|
uint32_t _attributes_dirty;
|
||||||
|
|
||||||
|
bool _transform_dirty;
|
||||||
|
osg::ref_ptr<osg::MatrixTransform> _transform;
|
||||||
|
std::vector<TransformType> _transform_types;
|
||||||
|
|
||||||
|
SGPropertyNode *_bounding_box[4]; ///<! x-min, y-min, x-max, y-max
|
||||||
|
SGPropertyNode *_color[3];
|
||||||
|
SGPropertyNode *_color_fill[3];
|
||||||
|
|
||||||
|
Element(SGPropertyNode* node, uint32_t attributes_used = 0);
|
||||||
|
|
||||||
|
virtual void childAdded(SGPropertyNode * child) {}
|
||||||
|
virtual void childRemoved(SGPropertyNode * child){}
|
||||||
|
virtual void childChanged(SGPropertyNode * child){}
|
||||||
|
|
||||||
|
virtual void colorChanged(const osg::Vec4& color) {}
|
||||||
|
virtual void colorFillChanged(const osg::Vec4& color){}
|
||||||
|
|
||||||
|
void linkColorNodes( const char* name,
|
||||||
|
SGPropertyNode** nodes,
|
||||||
|
const osg::Vec4& def = osg::Vec4(1,1,0,1) );
|
||||||
|
|
||||||
|
private:
|
||||||
|
Element(const Element&);// = delete
|
||||||
|
|
||||||
|
virtual void childAdded( SGPropertyNode * parent,
|
||||||
|
SGPropertyNode * child );
|
||||||
|
virtual void childRemoved( SGPropertyNode * parent,
|
||||||
|
SGPropertyNode * child );
|
||||||
|
virtual void valueChanged(SGPropertyNode * child);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace canvas
|
||||||
|
|
||||||
|
#endif /* CANVAS_ELEMENT_HXX_ */
|
65
src/Canvas/elements/group.cxx
Normal file
65
src/Canvas/elements/group.cxx
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
// A group of 2D canvas elements
|
||||||
|
//
|
||||||
|
// Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com>
|
||||||
|
//
|
||||||
|
// This program is free software; you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU General Public License as
|
||||||
|
// published by the Free Software Foundation; either version 2 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful, but
|
||||||
|
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
// General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program; if not, write to the Free Software
|
||||||
|
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
#include "group.hxx"
|
||||||
|
#include "text.hxx"
|
||||||
|
|
||||||
|
namespace canvas
|
||||||
|
{
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
Group::Group(SGPropertyNode* node):
|
||||||
|
Element(node)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
Group::~Group()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
void Group::update(double dt)
|
||||||
|
{
|
||||||
|
for( size_t i = 0; i < _children.size(); ++i )
|
||||||
|
_children[i]->update(dt);
|
||||||
|
|
||||||
|
Element::update(dt);
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
void Group::childAdded(SGPropertyNode* child)
|
||||||
|
{
|
||||||
|
if( child->getNameString() == "text" )
|
||||||
|
{
|
||||||
|
_children.push_back( boost::shared_ptr<Element>(new Text(child)) );
|
||||||
|
_transform->addChild( _children.back()->getMatrixTransform() );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
std::cout << "New unknown child: " << child->getDisplayName() << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
void Group::childRemoved(SGPropertyNode* child)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace canvas
|
47
src/Canvas/elements/group.hxx
Normal file
47
src/Canvas/elements/group.hxx
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
// A group of 2D canvas elements
|
||||||
|
//
|
||||||
|
// Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com>
|
||||||
|
//
|
||||||
|
// This program is free software; you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU General Public License as
|
||||||
|
// published by the Free Software Foundation; either version 2 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful, but
|
||||||
|
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
// General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program; if not, write to the Free Software
|
||||||
|
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
#ifndef CANVAS_GROUP_HXX_
|
||||||
|
#define CANVAS_GROUP_HXX_
|
||||||
|
|
||||||
|
#include "element.hxx"
|
||||||
|
#include <boost/shared_ptr.hpp>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace canvas
|
||||||
|
{
|
||||||
|
|
||||||
|
class Group:
|
||||||
|
public Element
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Group(SGPropertyNode* node);
|
||||||
|
virtual ~Group();
|
||||||
|
|
||||||
|
virtual void update(double dt);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
std::vector<boost::shared_ptr<Element> > _children;
|
||||||
|
|
||||||
|
virtual void childAdded(SGPropertyNode * child);
|
||||||
|
virtual void childRemoved(SGPropertyNode * child);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace canvas
|
||||||
|
|
||||||
|
#endif /* CANVAS_GROUP_HXX_ */
|
41
src/Canvas/elements/text-alignment.hxx
Normal file
41
src/Canvas/elements/text-alignment.hxx
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
// Mapping between strings and osg text alignment flags
|
||||||
|
//
|
||||||
|
// Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com>
|
||||||
|
//
|
||||||
|
// This program is free software; you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU General Public License as
|
||||||
|
// published by the Free Software Foundation; either version 2 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful, but
|
||||||
|
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
// General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program; if not, write to the Free Software
|
||||||
|
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
#ifndef ENUM_MAPPING
|
||||||
|
# error "Only include with ENUM_MAPPING defined!"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ENUM_MAPPING(LEFT_TOP, "left-top")
|
||||||
|
ENUM_MAPPING(LEFT_CENTER, "left-center")
|
||||||
|
ENUM_MAPPING(LEFT_BOTTOM, "left-bottom")
|
||||||
|
|
||||||
|
ENUM_MAPPING(CENTER_TOP, "center-top")
|
||||||
|
ENUM_MAPPING(CENTER_CENTER, "center-center")
|
||||||
|
ENUM_MAPPING(CENTER_BOTTOM, "center-bottom")
|
||||||
|
|
||||||
|
ENUM_MAPPING(RIGHT_TOP, "right-top")
|
||||||
|
ENUM_MAPPING(RIGHT_CENTER, "right-center")
|
||||||
|
ENUM_MAPPING(RIGHT_BOTTOM, "right-bottom")
|
||||||
|
|
||||||
|
ENUM_MAPPING(LEFT_BASE_LINE, "left-baseline")
|
||||||
|
ENUM_MAPPING(CENTER_BASE_LINE, "center-baseline")
|
||||||
|
ENUM_MAPPING(RIGHT_BASE_LINE, "right-baseline")
|
||||||
|
|
||||||
|
ENUM_MAPPING(LEFT_BOTTOM_BASE_LINE, "left-bottom-baseline")
|
||||||
|
ENUM_MAPPING(CENTER_BOTTOM_BASE_LINE, "center-bottom-baseline")
|
||||||
|
ENUM_MAPPING(RIGHT_BOTTOM_BASE_LINE, "right-bottom-baseline")
|
184
src/Canvas/elements/text.cxx
Normal file
184
src/Canvas/elements/text.cxx
Normal file
|
@ -0,0 +1,184 @@
|
||||||
|
// A text on the canvas
|
||||||
|
//
|
||||||
|
// Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com>
|
||||||
|
//
|
||||||
|
// This program is free software; you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU General Public License as
|
||||||
|
// published by the Free Software Foundation; either version 2 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful, but
|
||||||
|
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
// General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program; if not, write to the Free Software
|
||||||
|
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
#include "text.hxx"
|
||||||
|
#include <osgText/Text>
|
||||||
|
|
||||||
|
#include <Main/globals.hxx>
|
||||||
|
#include <Main/fg_props.hxx>
|
||||||
|
|
||||||
|
namespace canvas
|
||||||
|
{
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
Text::Text(SGPropertyNode* node):
|
||||||
|
Element(node, COLOR | COLOR_FILL | BOUNDING_BOX),
|
||||||
|
_text( new osgText::Text )
|
||||||
|
{
|
||||||
|
_drawable = _text;
|
||||||
|
_text->setCharacterSizeMode(osgText::Text::SCREEN_COORDS);
|
||||||
|
|
||||||
|
// font size and property node
|
||||||
|
float character_size = _node->getFloatValue("size", 32);
|
||||||
|
_text->setCharacterSize( character_size );
|
||||||
|
_node->setFloatValue("size", character_size);
|
||||||
|
|
||||||
|
osg::ref_ptr<osg::Geode> geode = new osg::Geode;
|
||||||
|
geode->addDrawable(_text);
|
||||||
|
_transform->addChild(geode);
|
||||||
|
|
||||||
|
_node->tie
|
||||||
|
(
|
||||||
|
"alignment",
|
||||||
|
SGRawValueMethods<Text, const char*>
|
||||||
|
(
|
||||||
|
*this,
|
||||||
|
&Text::getAlignment,
|
||||||
|
&Text::setAlignment
|
||||||
|
)
|
||||||
|
);
|
||||||
|
_node->tie
|
||||||
|
(
|
||||||
|
"padding",
|
||||||
|
SGRawValueMethods<osgText::Text, float>
|
||||||
|
(
|
||||||
|
*_text.get(),
|
||||||
|
&osgText::Text::getBoundingBoxMargin,
|
||||||
|
&osgText::Text::setBoundingBoxMargin
|
||||||
|
)
|
||||||
|
);
|
||||||
|
typedef SGRawValueMethods<osgText::Text, int> TextIntMethods;
|
||||||
|
_node->tie
|
||||||
|
(
|
||||||
|
"draw-mode",
|
||||||
|
// TEXT = 1 default
|
||||||
|
// BOUNDINGBOX = 2
|
||||||
|
// FILLEDBOUNDINGBOX = 4
|
||||||
|
// ALIGNMENT = 8
|
||||||
|
TextIntMethods
|
||||||
|
(
|
||||||
|
*_text.get(),
|
||||||
|
(TextIntMethods::getter_t)&osgText::Text::getDrawMode,
|
||||||
|
(TextIntMethods::setter_t)&osgText::Text::setDrawMode
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
Text::~Text()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
void Text::setFont(const char* name)
|
||||||
|
{
|
||||||
|
_text->setFont( getFont(name) );
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
void Text::setAlignment(const char* align)
|
||||||
|
{
|
||||||
|
const std::string align_string(align);
|
||||||
|
if( 0 ) return;
|
||||||
|
#define ENUM_MAPPING(enum_val, string_val) \
|
||||||
|
else if( align_string == string_val )\
|
||||||
|
_text->setAlignment( osgText::Text::enum_val );
|
||||||
|
#include "text-alignment.hxx"
|
||||||
|
#undef ENUM_MAPPING
|
||||||
|
else
|
||||||
|
_text->setAlignment(osgText::Text::LEFT_BASE_LINE);
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
const char* Text::getAlignment() const
|
||||||
|
{
|
||||||
|
switch( _text->getAlignment() )
|
||||||
|
{
|
||||||
|
#define ENUM_MAPPING(enum_val, string_val) \
|
||||||
|
case osgText::Text::enum_val:\
|
||||||
|
return string_val;
|
||||||
|
#include "text-alignment.hxx"
|
||||||
|
#undef ENUM_MAPPING
|
||||||
|
default:
|
||||||
|
return "unknown";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
void Text::childChanged(SGPropertyNode* child)
|
||||||
|
{
|
||||||
|
if( child->getNameString() == "text" )
|
||||||
|
_text->setText(child->getStringValue());
|
||||||
|
else if( child->getNameString() == "size" )
|
||||||
|
_text->setCharacterSize( child->getFloatValue() );
|
||||||
|
else if( child->getNameString() == "font" )
|
||||||
|
setFont( child->getStringValue() );
|
||||||
|
else
|
||||||
|
return;
|
||||||
|
|
||||||
|
_attributes_dirty |= BOUNDING_BOX;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
void Text::colorChanged(const osg::Vec4& color)
|
||||||
|
{
|
||||||
|
_text->setColor(color);
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
void Text::colorFillChanged(const osg::Vec4& color)
|
||||||
|
{
|
||||||
|
_text->setBoundingBoxColor(color);
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
Text::font_ptr Text::getFont(const std::string& name)
|
||||||
|
{
|
||||||
|
SGPath path = globals->resolve_ressource_path("Fonts/" + name);
|
||||||
|
if( path.isNull() )
|
||||||
|
{
|
||||||
|
SG_LOG
|
||||||
|
(
|
||||||
|
SG_GL,
|
||||||
|
SG_ALERT,
|
||||||
|
"canvas::Text: No such font: " << name
|
||||||
|
);
|
||||||
|
return font_ptr();
|
||||||
|
}
|
||||||
|
|
||||||
|
SG_LOG
|
||||||
|
(
|
||||||
|
SG_GL,
|
||||||
|
SG_INFO,
|
||||||
|
"canvas::Text: using font file " << path.str()
|
||||||
|
);
|
||||||
|
|
||||||
|
font_ptr font = osgText::readFontFile(path.c_str());
|
||||||
|
if( !font )
|
||||||
|
SG_LOG
|
||||||
|
(
|
||||||
|
SG_GL,
|
||||||
|
SG_ALERT,
|
||||||
|
"canvas::Text: Failed to open font file " << path.c_str()
|
||||||
|
);
|
||||||
|
|
||||||
|
return font;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace canvas
|
56
src/Canvas/elements/text.hxx
Normal file
56
src/Canvas/elements/text.hxx
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
// A text on the canvas
|
||||||
|
//
|
||||||
|
// Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com>
|
||||||
|
//
|
||||||
|
// This program is free software; you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU General Public License as
|
||||||
|
// published by the Free Software Foundation; either version 2 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful, but
|
||||||
|
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
// General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program; if not, write to the Free Software
|
||||||
|
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
#ifndef CANVAS_TEXT_HXX_
|
||||||
|
#define CANVAS_TEXT_HXX_
|
||||||
|
|
||||||
|
#include "element.hxx"
|
||||||
|
#include <osgText/Text>
|
||||||
|
#include <boost/shared_ptr.hpp>
|
||||||
|
#include <map>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace canvas
|
||||||
|
{
|
||||||
|
|
||||||
|
class Text:
|
||||||
|
public Element
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Text(SGPropertyNode* node);
|
||||||
|
virtual ~Text();
|
||||||
|
|
||||||
|
void setFont(const char* name);
|
||||||
|
|
||||||
|
void setAlignment(const char* align);
|
||||||
|
const char* getAlignment() const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
osg::ref_ptr<osgText::Text> _text;
|
||||||
|
|
||||||
|
virtual void childChanged(SGPropertyNode * child);
|
||||||
|
virtual void colorChanged(const osg::Vec4& color);
|
||||||
|
virtual void colorFillChanged(const osg::Vec4& color);
|
||||||
|
|
||||||
|
typedef osg::ref_ptr<osgText::Font> font_ptr;
|
||||||
|
static font_ptr getFont(const std::string& name);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace canvas
|
||||||
|
|
||||||
|
#endif /* CANVAS_TEXT_HXX_ */
|
|
@ -93,28 +93,6 @@ get_aspect_adjust (int xsize, int ysize)
|
||||||
float real_aspect = float(xsize) / float(ysize);
|
float real_aspect = float(xsize) / float(ysize);
|
||||||
return (real_aspect / ideal_aspect);
|
return (real_aspect / ideal_aspect);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
// Global functions.
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
bool
|
|
||||||
fgPanelVisible ()
|
|
||||||
{
|
|
||||||
const FGPanel* current = globals->get_current_panel();
|
|
||||||
if (current == 0)
|
|
||||||
return false;
|
|
||||||
if (current->getVisibility() == 0)
|
|
||||||
return false;
|
|
||||||
if (globals->get_viewmgr()->get_current() != 0)
|
|
||||||
return false;
|
|
||||||
if (current->getAutohide() && globals->get_current_view()->getHeadingOffset_deg() * SGD_DEGREES_TO_RADIANS != 0)
|
|
||||||
return false;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
||||||
// Implementation of FGTextureManager.
|
// Implementation of FGTextureManager.
|
||||||
|
@ -201,8 +179,6 @@ FGPanel::FGPanel ()
|
||||||
: _mouseDown(false),
|
: _mouseDown(false),
|
||||||
_mouseInstrument(0),
|
_mouseInstrument(0),
|
||||||
_width(WIN_W), _height(int(WIN_H * 0.5768 + 1)),
|
_width(WIN_W), _height(int(WIN_H * 0.5768 + 1)),
|
||||||
// _view_height(int(WIN_H * 0.4232)),
|
|
||||||
_visibility(fgGetNode("/sim/panel/visibility", true)),
|
|
||||||
_x_offset(fgGetNode("/sim/panel/x-offset", true)),
|
_x_offset(fgGetNode("/sim/panel/x-offset", true)),
|
||||||
_y_offset(fgGetNode("/sim/panel/y-offset", true)),
|
_y_offset(fgGetNode("/sim/panel/y-offset", true)),
|
||||||
_jitter(fgGetNode("/sim/panel/jitter", true)),
|
_jitter(fgGetNode("/sim/panel/jitter", true)),
|
||||||
|
@ -210,6 +186,7 @@ FGPanel::FGPanel ()
|
||||||
_xsize_node(fgGetNode("/sim/startup/xsize", true)),
|
_xsize_node(fgGetNode("/sim/startup/xsize", true)),
|
||||||
_ysize_node(fgGetNode("/sim/startup/ysize", true)),
|
_ysize_node(fgGetNode("/sim/startup/ysize", true)),
|
||||||
_enable_depth_test(false),
|
_enable_depth_test(false),
|
||||||
|
_autohide(true),
|
||||||
_drawPanelHotspots("/sim/panel-hotspots")
|
_drawPanelHotspots("/sim/panel-hotspots")
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -238,44 +215,6 @@ FGPanel::addInstrument (FGPanelInstrument * instrument)
|
||||||
_instruments.push_back(instrument);
|
_instruments.push_back(instrument);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize the panel.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
FGPanel::init ()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Bind panel properties.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
FGPanel::bind ()
|
|
||||||
{
|
|
||||||
fgSetArchivable("/sim/panel/visibility");
|
|
||||||
fgSetArchivable("/sim/panel/x-offset");
|
|
||||||
fgSetArchivable("/sim/panel/y-offset");
|
|
||||||
fgSetArchivable("/sim/panel/jitter");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Unbind panel properties.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
FGPanel::unbind ()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
FGPanel::update (double dt)
|
|
||||||
{
|
|
||||||
updateMouseDelay(dt);
|
|
||||||
}
|
|
||||||
|
|
||||||
double
|
double
|
||||||
FGPanel::getAspectScale() const
|
FGPanel::getAspectScale() const
|
||||||
{
|
{
|
||||||
|
@ -506,26 +445,6 @@ FGPanel::draw(osg::State& state)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the panel's visibility.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
FGPanel::setVisibility (bool visibility)
|
|
||||||
{
|
|
||||||
_visibility->setBoolValue( visibility );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return true if the panel is visible.
|
|
||||||
*/
|
|
||||||
bool
|
|
||||||
FGPanel::getVisibility () const
|
|
||||||
{
|
|
||||||
return _visibility->getBoolValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the panel's background texture.
|
* Set the panel's background texture.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -29,7 +29,6 @@
|
||||||
#include <simgear/props/props.hxx>
|
#include <simgear/props/props.hxx>
|
||||||
#include <simgear/props/propertyObject.hxx>
|
#include <simgear/props/propertyObject.hxx>
|
||||||
|
|
||||||
#include <simgear/structure/subsystem_mgr.hxx>
|
|
||||||
#include <simgear/structure/SGBinding.hxx>
|
#include <simgear/structure/SGBinding.hxx>
|
||||||
#include <simgear/math/interpolater.hxx>
|
#include <simgear/math/interpolater.hxx>
|
||||||
#include <simgear/timing/timestamp.hxx>
|
#include <simgear/timing/timestamp.hxx>
|
||||||
|
@ -118,22 +117,14 @@ private:
|
||||||
* redraw themselves when necessary, and will pass mouse clicks on to
|
* redraw themselves when necessary, and will pass mouse clicks on to
|
||||||
* the appropriate instruments for processing.
|
* the appropriate instruments for processing.
|
||||||
*/
|
*/
|
||||||
class FGPanel : public SGSubsystem
|
class FGPanel : public SGReferenced
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
FGPanel ();
|
FGPanel ();
|
||||||
virtual ~FGPanel ();
|
virtual ~FGPanel ();
|
||||||
|
|
||||||
// Update the panel (every frame).
|
|
||||||
virtual void init ();
|
|
||||||
virtual void bind ();
|
|
||||||
virtual void unbind ();
|
|
||||||
virtual void draw (osg::State& state);
|
virtual void draw (osg::State& state);
|
||||||
virtual void update (double);
|
|
||||||
|
|
||||||
//void update (osg::State& state);
|
|
||||||
//virtual void update (osg::State& state, GLfloat winx, GLfloat winw, GLfloat winy, GLfloat winh);
|
|
||||||
|
|
||||||
virtual void updateMouseDelay(double dt);
|
virtual void updateMouseDelay(double dt);
|
||||||
|
|
||||||
|
@ -146,11 +137,6 @@ public:
|
||||||
// Background multiple textures.
|
// Background multiple textures.
|
||||||
virtual void setMultiBackground (osg::Texture2D* texture, int idx);
|
virtual void setMultiBackground (osg::Texture2D* texture, int idx);
|
||||||
|
|
||||||
// Make the panel visible or invisible.
|
|
||||||
virtual bool getVisibility () const;
|
|
||||||
virtual void setVisibility (bool visibility);
|
|
||||||
|
|
||||||
// Full width of panel.
|
|
||||||
virtual void setWidth (int width) { _width = width; }
|
virtual void setWidth (int width) { _width = width; }
|
||||||
virtual int getWidth () const { return _width; }
|
virtual int getWidth () const { return _width; }
|
||||||
|
|
||||||
|
@ -201,7 +187,6 @@ private:
|
||||||
int _height;
|
int _height;
|
||||||
// int _view_height;
|
// int _view_height;
|
||||||
|
|
||||||
SGPropertyNode_ptr _visibility;
|
|
||||||
SGPropertyNode_ptr _x_offset;
|
SGPropertyNode_ptr _x_offset;
|
||||||
SGPropertyNode_ptr _y_offset;
|
SGPropertyNode_ptr _y_offset;
|
||||||
SGPropertyNode_ptr _jitter;
|
SGPropertyNode_ptr _jitter;
|
||||||
|
@ -584,22 +569,7 @@ public:
|
||||||
FGSwitchLayer ();
|
FGSwitchLayer ();
|
||||||
virtual void draw (osg::State& state);
|
virtual void draw (osg::State& state);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
// Functions.
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test whether the panel should be visible.
|
|
||||||
*/
|
|
||||||
bool fgPanelVisible ();
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif // __PANEL_HXX
|
#endif // __PANEL_HXX
|
||||||
|
|
||||||
// end of panel.hxx
|
// end of panel.hxx
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
#include <boost/tuple/tuple.hpp>
|
#include <boost/tuple/tuple.hpp>
|
||||||
|
|
||||||
#include <simgear/props/props.hxx>
|
#include <simgear/props/props.hxx>
|
||||||
|
#include <simgear/math/SGMath.hxx>
|
||||||
|
|
||||||
#include <Main/fg_props.hxx>
|
#include <Main/fg_props.hxx>
|
||||||
|
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
|
#include <simgear/math/SGMath.hxx>
|
||||||
#include <Main/fg_props.hxx>
|
#include <Main/fg_props.hxx>
|
||||||
#include "environment_ctrl.hxx"
|
#include "environment_ctrl.hxx"
|
||||||
#include "environment.hxx"
|
#include "environment.hxx"
|
||||||
|
|
|
@ -24,7 +24,6 @@
|
||||||
|
|
||||||
#include <simgear/compiler.h>
|
#include <simgear/compiler.h>
|
||||||
#include <simgear/structure/subsystem_mgr.hxx>
|
#include <simgear/structure/subsystem_mgr.hxx>
|
||||||
#include <simgear/math/SGMath.hxx>
|
|
||||||
#include <simgear/props/tiedpropertylist.hxx>
|
#include <simgear/props/tiedpropertylist.hxx>
|
||||||
|
|
||||||
#ifdef SG_HAVE_STD_INCLUDES
|
#ifdef SG_HAVE_STD_INCLUDES
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <simgear/math/SGMisc.hxx>
|
#include <simgear/math/SGMisc.hxx>
|
||||||
|
#include <simgear/math/SGMath.hxx>
|
||||||
#include <Main/fg_props.hxx>
|
#include <Main/fg_props.hxx>
|
||||||
|
|
||||||
namespace Environment {
|
namespace Environment {
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
//
|
//
|
||||||
// You should have received a copy of the GNU Lesser General Public License
|
// You should have received a copy of the GNU Lesser General Public License
|
||||||
// along with this program; if not, write to the Free Software
|
// along with this program; if not, write to the Free Software
|
||||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
//
|
//
|
||||||
// $Id: JSBSim.cxx,v 1.64 2010/10/31 04:49:25 jberndt Exp $
|
// $Id: JSBSim.cxx,v 1.64 2010/10/31 04:49:25 jberndt Exp $
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public License
|
You should have received a copy of the GNU Lesser General Public License
|
||||||
along with this program; if not, write to the Free Software
|
along with this program; if not, write to the Free Software
|
||||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
HISTORY
|
HISTORY
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
|
|
0
src/FDM/JSBSim/input_output/FGScript.cpp
Executable file → Normal file
0
src/FDM/JSBSim/input_output/FGScript.cpp
Executable file → Normal file
0
src/FDM/JSBSim/models/FGAuxiliary.cpp
Executable file → Normal file
0
src/FDM/JSBSim/models/FGAuxiliary.cpp
Executable file → Normal file
0
src/FDM/JSBSim/models/FGExternalForce.cpp
Executable file → Normal file
0
src/FDM/JSBSim/models/FGExternalForce.cpp
Executable file → Normal file
0
src/FDM/JSBSim/models/FGExternalForce.h
Executable file → Normal file
0
src/FDM/JSBSim/models/FGExternalForce.h
Executable file → Normal file
0
src/FDM/JSBSim/models/FGExternalReactions.h
Executable file → Normal file
0
src/FDM/JSBSim/models/FGExternalReactions.h
Executable file → Normal file
0
src/FDM/JSBSim/models/flight_control/FGFCSFunction.h
Executable file → Normal file
0
src/FDM/JSBSim/models/flight_control/FGFCSFunction.h
Executable file → Normal file
0
src/FDM/JSBSim/models/propulsion/FGTurboProp.cpp
Executable file → Normal file
0
src/FDM/JSBSim/models/propulsion/FGTurboProp.cpp
Executable file → Normal file
|
@ -3,6 +3,8 @@
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <cstdlib>
|
||||||
|
|
||||||
#include <simgear/debug/logstream.hxx>
|
#include <simgear/debug/logstream.hxx>
|
||||||
#include <simgear/math/sg_geodesy.hxx>
|
#include <simgear/math/sg_geodesy.hxx>
|
||||||
#include <simgear/misc/sg_path.hxx>
|
#include <simgear/misc/sg_path.hxx>
|
||||||
|
|
|
@ -5,8 +5,6 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include <simgear/math/SGMath.hxx>
|
|
||||||
|
|
||||||
#include "Math.hpp"
|
#include "Math.hpp"
|
||||||
#include "FGFDM.hpp"
|
#include "FGFDM.hpp"
|
||||||
#include "PropEngine.hpp"
|
#include "PropEngine.hpp"
|
||||||
|
|
|
@ -10,8 +10,6 @@
|
||||||
#include "Atmosphere.hpp"
|
#include "Atmosphere.hpp"
|
||||||
#include "Airplane.hpp"
|
#include "Airplane.hpp"
|
||||||
|
|
||||||
#include <simgear/math/SGMath.hxx>
|
|
||||||
|
|
||||||
using namespace yasim;
|
using namespace yasim;
|
||||||
|
|
||||||
// Stubs. Not needed by a batch program, but required to link.
|
// Stubs. Not needed by a batch program, but required to link.
|
||||||
|
|
|
@ -28,7 +28,6 @@
|
||||||
|
|
||||||
#include <simgear/constants.h>
|
#include <simgear/constants.h>
|
||||||
#include <simgear/debug/logstream.hxx>
|
#include <simgear/debug/logstream.hxx>
|
||||||
#include <simgear/math/SGMath.hxx>
|
|
||||||
#include <simgear/timing/timestamp.hxx>
|
#include <simgear/timing/timestamp.hxx>
|
||||||
|
|
||||||
#include <Scenery/scenery.hxx>
|
#include <Scenery/scenery.hxx>
|
||||||
|
|
|
@ -62,4 +62,9 @@ private:
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* open a URL using the system's web-browser
|
||||||
|
*/
|
||||||
|
void cocoaOpenUrl(const std::string& url);
|
||||||
|
|
||||||
#endif // __MENUBAR_HXX
|
#endif // __MENUBAR_HXX
|
||||||
|
|
|
@ -110,6 +110,23 @@ static void setItemShortcutFromString(NSMenuItem* item, const string& s)
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
class CocoaAutoreleasePool
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CocoaAutoreleasePool()
|
||||||
|
{
|
||||||
|
pool = [[NSAutoreleasePool alloc] init];
|
||||||
|
}
|
||||||
|
|
||||||
|
~CocoaAutoreleasePool()
|
||||||
|
{
|
||||||
|
[pool release];
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
NSAutoreleasePool* pool;
|
||||||
|
};
|
||||||
|
|
||||||
class CocoaEnabledListener : public SGPropertyChangeListener
|
class CocoaEnabledListener : public SGPropertyChangeListener
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -120,6 +137,7 @@ namespace {
|
||||||
|
|
||||||
virtual void valueChanged(SGPropertyNode *node)
|
virtual void valueChanged(SGPropertyNode *node)
|
||||||
{
|
{
|
||||||
|
CocoaAutoreleasePool pool;
|
||||||
BOOL b = node->getBoolValue();
|
BOOL b = node->getBoolValue();
|
||||||
[item setEnabled:b];
|
[item setEnabled:b];
|
||||||
}
|
}
|
||||||
|
@ -137,6 +155,7 @@ FGCocoaMenuBar::CocoaMenuBarPrivate::CocoaMenuBarPrivate()
|
||||||
|
|
||||||
FGCocoaMenuBar::CocoaMenuBarPrivate::~CocoaMenuBarPrivate()
|
FGCocoaMenuBar::CocoaMenuBarPrivate::~CocoaMenuBarPrivate()
|
||||||
{
|
{
|
||||||
|
CocoaAutoreleasePool pool;
|
||||||
[delegate release];
|
[delegate release];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -153,16 +172,9 @@ void FGCocoaMenuBar::CocoaMenuBarPrivate::menuFromProps(NSMenu* menu, SGProperty
|
||||||
n->setBoolValue("enabled", true);
|
n->setBoolValue("enabled", true);
|
||||||
}
|
}
|
||||||
|
|
||||||
string shortcut;
|
string l = getLocalizedLabel(n);
|
||||||
string l = n->getStringValue("label");
|
|
||||||
string::size_type pos = l.find("(");
|
|
||||||
if (pos != string::npos) {
|
|
||||||
string full(l);
|
|
||||||
l = full.substr(0, pos);
|
|
||||||
shortcut = full.substr(pos + 1, full.size() - (pos + 2));
|
|
||||||
}
|
|
||||||
|
|
||||||
NSString* label = stdStringToCocoa(strutils::simplify(l));
|
NSString* label = stdStringToCocoa(strutils::simplify(l));
|
||||||
|
string shortcut = n->getStringValue("key");
|
||||||
|
|
||||||
NSMenuItem* item;
|
NSMenuItem* item;
|
||||||
if (index >= [menu numberOfItems]) {
|
if (index >= [menu numberOfItems]) {
|
||||||
|
@ -227,6 +239,8 @@ FGCocoaMenuBar::~FGCocoaMenuBar()
|
||||||
|
|
||||||
void FGCocoaMenuBar::init()
|
void FGCocoaMenuBar::init()
|
||||||
{
|
{
|
||||||
|
CocoaAutoreleasePool pool;
|
||||||
|
|
||||||
NSMenu* mainBar = [[NSApplication sharedApplication] mainMenu];
|
NSMenu* mainBar = [[NSApplication sharedApplication] mainMenu];
|
||||||
SGPropertyNode_ptr props = fgGetNode("/sim/menubar/default",true);
|
SGPropertyNode_ptr props = fgGetNode("/sim/menubar/default",true);
|
||||||
|
|
||||||
|
@ -237,7 +251,7 @@ void FGCocoaMenuBar::init()
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_FOREACH(SGPropertyNode_ptr n, props->getChildren("menu")) {
|
BOOST_FOREACH(SGPropertyNode_ptr n, props->getChildren("menu")) {
|
||||||
NSString* label = stdStringToCocoa(n->getStringValue("label"));
|
NSString* label = stdStringToCocoa(getLocalizedLabel(n));
|
||||||
NSMenuItem* item = [mainBar itemWithTitle:label];
|
NSMenuItem* item = [mainBar itemWithTitle:label];
|
||||||
NSMenu* menu;
|
NSMenu* menu;
|
||||||
|
|
||||||
|
@ -283,3 +297,10 @@ void FGCocoaMenuBar::hide()
|
||||||
{
|
{
|
||||||
// no-op
|
// no-op
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void cocoaOpenUrl(const std::string& url)
|
||||||
|
{
|
||||||
|
CocoaAutoreleasePool pool;
|
||||||
|
NSURL* nsu = [NSURL URLWithString:stdStringToCocoa(url)];
|
||||||
|
[[NSWorkspace sharedWorkspace] openURL:nsu];
|
||||||
|
}
|
||||||
|
|
|
@ -7,7 +7,6 @@
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
#include <simgear/props/props.hxx>
|
#include <simgear/props/props.hxx>
|
||||||
#include <simgear/math/SGMath.hxx>
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
||||||
// FGColor class.
|
// FGColor class.
|
||||||
|
|
|
@ -15,7 +15,6 @@
|
||||||
#ifndef __FGFONTCACHE_HXX
|
#ifndef __FGFONTCACHE_HXX
|
||||||
#define __FGFONTCACHE_HXX
|
#define __FGFONTCACHE_HXX
|
||||||
|
|
||||||
#include <simgear/math/SGMath.hxx>
|
|
||||||
#include <simgear/misc/sg_path.hxx>
|
#include <simgear/misc/sg_path.hxx>
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
|
@ -8,8 +8,6 @@
|
||||||
#include <algorithm> // for std::sort
|
#include <algorithm> // for std::sort
|
||||||
#include <plib/puAux.h>
|
#include <plib/puAux.h>
|
||||||
|
|
||||||
#include <simgear/sg_inlines.h>
|
|
||||||
#include <simgear/route/waypoint.hxx>
|
|
||||||
#include <simgear/sg_inlines.h>
|
#include <simgear/sg_inlines.h>
|
||||||
#include <simgear/misc/strutils.hxx>
|
#include <simgear/misc/strutils.hxx>
|
||||||
#include <simgear/magvar/magvar.hxx>
|
#include <simgear/magvar/magvar.hxx>
|
||||||
|
@ -682,7 +680,7 @@ void MapWidget::paintRoute()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
RoutePath path(_route->waypts());
|
RoutePath path(_route->flightPlan());
|
||||||
|
|
||||||
// first pass, draw the actual lines
|
// first pass, draw the actual lines
|
||||||
glLineWidth(2.0);
|
glLineWidth(2.0);
|
||||||
|
@ -889,7 +887,7 @@ public:
|
||||||
{
|
{
|
||||||
_heliports = nd->getBoolValue("show-heliports", false);
|
_heliports = nd->getBoolValue("show-heliports", false);
|
||||||
_hardRunwaysOnly = nd->getBoolValue("hard-surfaced-airports", true);
|
_hardRunwaysOnly = nd->getBoolValue("hard-surfaced-airports", true);
|
||||||
_minLengthFt = nd->getDoubleValue("min-runway-length-ft", 2000.0);
|
_minLengthFt = fgGetDouble("/sim/navdb/min-runway-length-ft", 2000);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual FGPositioned::Type maxType() const {
|
virtual FGPositioned::Type maxType() const {
|
||||||
|
|
|
@ -11,7 +11,6 @@
|
||||||
|
|
||||||
#include <plib/puAux.h>
|
#include <plib/puAux.h>
|
||||||
|
|
||||||
#include <simgear/route/waypoint.hxx>
|
|
||||||
#include <simgear/structure/callback.hxx>
|
#include <simgear/structure/callback.hxx>
|
||||||
#include <simgear/sg_inlines.h>
|
#include <simgear/sg_inlines.h>
|
||||||
|
|
||||||
|
@ -37,34 +36,37 @@ enum {
|
||||||
static const double BLINK_TIME = 0.3;
|
static const double BLINK_TIME = 0.3;
|
||||||
static const int DRAG_START_DISTANCE_PX = 5;
|
static const int DRAG_START_DISTANCE_PX = 5;
|
||||||
|
|
||||||
class RouteManagerWaypointModel :
|
class FlightPlanWaypointModel :
|
||||||
public WaypointList::Model,
|
public WaypointList::Model,
|
||||||
public SGPropertyChangeListener
|
public SGPropertyChangeListener
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
RouteManagerWaypointModel()
|
FlightPlanWaypointModel(flightgear::FlightPlan* fp) :
|
||||||
|
_fp(fp)
|
||||||
{
|
{
|
||||||
_rm = static_cast<FGRouteMgr*>(globals->get_subsystem("route-manager"));
|
|
||||||
|
|
||||||
SGPropertyNode* routeEdited = fgGetNode("/autopilot/route-manager/signals/edited", true);
|
SGPropertyNode* routeEdited = fgGetNode("/autopilot/route-manager/signals/edited", true);
|
||||||
|
SGPropertyNode* flightplanChanged = fgGetNode("/autopilot/route-manager/signals/flightplan-changed", true);
|
||||||
routeEdited->addChangeListener(this);
|
routeEdited->addChangeListener(this);
|
||||||
|
flightplanChanged->addChangeListener(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ~RouteManagerWaypointModel()
|
~FlightPlanWaypointModel()
|
||||||
{
|
{
|
||||||
SGPropertyNode* routeEdited = fgGetNode("/autopilot/route-manager/signals/edited", true);
|
SGPropertyNode* routeEdited = fgGetNode("/autopilot/route-manager/signals/edited", true);
|
||||||
|
SGPropertyNode* flightplanChanged = fgGetNode("/autopilot/route-manager/signals/flightplan-changed", true);
|
||||||
routeEdited->removeChangeListener(this);
|
routeEdited->removeChangeListener(this);
|
||||||
|
flightplanChanged->removeChangeListener(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
// implement WaypointList::Model
|
// implement WaypointList::Model
|
||||||
virtual unsigned int numWaypoints() const
|
virtual unsigned int numWaypoints() const
|
||||||
{
|
{
|
||||||
return _rm->numWaypts();
|
return _fp->numLegs();
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual int currentWaypoint() const
|
virtual int currentWaypoint() const
|
||||||
{
|
{
|
||||||
return _rm->currentIndex();
|
return _fp->currentIndex();
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual flightgear::Waypt* waypointAt(unsigned int index) const
|
virtual flightgear::Waypt* waypointAt(unsigned int index) const
|
||||||
|
@ -73,12 +75,12 @@ public:
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return _rm->wayptAtIndex(index);
|
return _fp->legAtIndex(index)->waypoint();
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void deleteAt(unsigned int index)
|
virtual void deleteAt(unsigned int index)
|
||||||
{
|
{
|
||||||
_rm->removeWayptAtIndex(index);
|
_fp->deleteIndex(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void moveWaypointToIndex(unsigned int srcIndex, unsigned int destIndex)
|
virtual void moveWaypointToIndex(unsigned int srcIndex, unsigned int destIndex)
|
||||||
|
@ -89,13 +91,15 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int currentWpIndex = currentWaypoint();
|
unsigned int currentWpIndex = currentWaypoint();
|
||||||
WayptRef w(_rm->removeWayptAtIndex(srcIndex));
|
WayptRef w(waypointAt(currentWpIndex));
|
||||||
|
_fp->deleteIndex(currentWpIndex);
|
||||||
|
|
||||||
SG_LOG(SG_GENERAL, SG_INFO, "wpt:" << w->ident());
|
SG_LOG(SG_GENERAL, SG_INFO, "wpt:" << w->ident());
|
||||||
_rm->insertWayptAtIndex(w, destIndex);
|
_fp->insertWayptAtIndex(w, destIndex);
|
||||||
|
|
||||||
if (srcIndex == currentWpIndex) {
|
if (srcIndex == currentWpIndex) {
|
||||||
// current waypoint was moved
|
// current waypoint was moved
|
||||||
_rm->jumpToIndex(destIndex);
|
_fp->setCurrentIndex(destIndex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,12 +111,19 @@ public:
|
||||||
// implement SGPropertyChangeListener
|
// implement SGPropertyChangeListener
|
||||||
void valueChanged(SGPropertyNode *prop)
|
void valueChanged(SGPropertyNode *prop)
|
||||||
{
|
{
|
||||||
if (_cb) {
|
if (prop->getNameString() == "edited") {
|
||||||
(*_cb)();
|
if (_cb) {
|
||||||
|
(*_cb)();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (prop->getNameString() == "flightplan-changed") {
|
||||||
|
_fp =
|
||||||
|
static_cast<FGRouteMgr*>(globals->get_subsystem("route-manager"))->flightPlan();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
FGRouteMgr* _rm;
|
flightgear::FlightPlan* _fp;
|
||||||
SGCallback* _cb;
|
SGCallback* _cb;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -152,7 +163,9 @@ WaypointList::WaypointList(int x, int y, int width, int height) :
|
||||||
{
|
{
|
||||||
// pretend to be a list, so fgPopup doesn't mess with our mouse events
|
// pretend to be a list, so fgPopup doesn't mess with our mouse events
|
||||||
type |= PUCLASS_LIST;
|
type |= PUCLASS_LIST;
|
||||||
setModel(new RouteManagerWaypointModel());
|
flightgear::FlightPlan* fp =
|
||||||
|
static_cast<FGRouteMgr*>(globals->get_subsystem("route-manager"))->flightPlan();
|
||||||
|
setModel(new FlightPlanWaypointModel(fp));
|
||||||
setSize(width, height);
|
setSize(width, height);
|
||||||
setValue(-1);
|
setValue(-1);
|
||||||
|
|
||||||
|
@ -399,12 +412,12 @@ void WaypointList::drawRow(int dx, int dy, int rowIndex, int y)
|
||||||
if (wp->flag(WPT_MISS)) {
|
if (wp->flag(WPT_MISS)) {
|
||||||
drawBox = true;
|
drawBox = true;
|
||||||
puSetColor(col, 1.0, 0.0, 0.0, 0.3); // red
|
puSetColor(col, 1.0, 0.0, 0.0, 0.3); // red
|
||||||
} else if (wp->flag(WPT_ARRIVAL)) {
|
} else if (wp->flag(WPT_ARRIVAL) || wp->flag(WPT_DEPARTURE)) {
|
||||||
drawBox = true;
|
drawBox = true;
|
||||||
puSetColor(col, 0.0, 0.0, 0.0, 0.3);
|
puSetColor(col, 0.0, 0.0, 0.0, 0.3);
|
||||||
} else if (wp->flag(WPT_DEPARTURE)) {
|
} else if (wp->flag(WPT_APPROACH)) {
|
||||||
drawBox = true;
|
drawBox = true;
|
||||||
puSetColor(col, 0.0, 0.0, 0.0, 0.3);
|
puSetColor(col, 0.0, 0.0, 0.1, 0.3);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isDragSource) {
|
if (isDragSource) {
|
||||||
|
|
|
@ -837,4 +837,4 @@ static fntBitmapFont fntHelvetica12(FontHelvetica12.Characters, 1,
|
||||||
|
|
||||||
puFont FONT_HELVETICA_14(&fntHelvetica14, 14, 0);
|
puFont FONT_HELVETICA_14(&fntHelvetica14, 14, 0);
|
||||||
puFont FONT_SANS_12B(&fntSans12B, 12, 0);
|
puFont FONT_SANS_12B(&fntSans12B, 12, 0);
|
||||||
puFont FONT_HELVETICA_12(&fntHelvetica12, 12, 0);
|
puFont FONT_HELVETICA_12(&fntHelvetica12, 13 /*[sic!]*/, 0); /* Original plib Helvetica 12 font also reported size 13, instead of 12 */
|
||||||
|
|
|
@ -60,6 +60,10 @@
|
||||||
# include <shellapi.h>
|
# include <shellapi.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef SG_MAC
|
||||||
|
# include "FGCocoaMenuBar.hxx" // for cocoaOpenUrl
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "gui.h"
|
#include "gui.h"
|
||||||
|
|
||||||
using std::string;
|
using std::string;
|
||||||
|
@ -182,6 +186,15 @@ bool openBrowser(string address)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef SG_MAC
|
||||||
|
if (address.find("://")==string::npos) {
|
||||||
|
address = "file://" + address;
|
||||||
|
}
|
||||||
|
|
||||||
|
cocoaOpenUrl(address);
|
||||||
|
return ok;
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
|
|
||||||
string command = globals->get_browser();
|
string command = globals->get_browser();
|
||||||
|
|
|
@ -4,7 +4,6 @@
|
||||||
|
|
||||||
#include <plib/pu.h>
|
#include <plib/pu.h>
|
||||||
#include <simgear/props/props.hxx>
|
#include <simgear/props/props.hxx>
|
||||||
#include <simgear/math/SGMath.hxx>
|
|
||||||
|
|
||||||
#include "layout.hxx"
|
#include "layout.hxx"
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
|
|
||||||
#include "layout.hxx"
|
#include "layout.hxx"
|
||||||
|
|
||||||
#include <simgear/math/SGMath.hxx>
|
|
||||||
|
|
||||||
// This file contains the actual layout engine. It has no dependence
|
// This file contains the actual layout engine. It has no dependence
|
||||||
// on outside libraries; see layout-props.cxx for the glue code.
|
// on outside libraries; see layout-props.cxx for the glue code.
|
||||||
|
|
|
@ -6,7 +6,6 @@
|
||||||
#include "menubar.hxx"
|
#include "menubar.hxx"
|
||||||
#include <Main/locale.hxx>
|
#include <Main/locale.hxx>
|
||||||
#include <Main/globals.hxx>
|
#include <Main/globals.hxx>
|
||||||
#include <simgear/math/SGMath.hxx>
|
|
||||||
|
|
||||||
FGMenuBar::FGMenuBar()
|
FGMenuBar::FGMenuBar()
|
||||||
{
|
{
|
||||||
|
|
|
@ -51,7 +51,7 @@ public:
|
||||||
* Take care of mapping it to the appropriate translation, if available.
|
* Take care of mapping it to the appropriate translation, if available.
|
||||||
* Returns an UTF-8 encoded string.
|
* Returns an UTF-8 encoded string.
|
||||||
*/
|
*/
|
||||||
const char* getLocalizedLabel(SGPropertyNode* node);
|
static const char* getLocalizedLabel(SGPropertyNode* node);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -68,6 +68,8 @@ NewGUI::init ()
|
||||||
setStyle();
|
setStyle();
|
||||||
SGPath p(globals->get_fg_root(), "gui/dialogs");
|
SGPath p(globals->get_fg_root(), "gui/dialogs");
|
||||||
readDir(p);
|
readDir(p);
|
||||||
|
const std::string aircraft_dir(fgGetString("/sim/aircraft-dir"));
|
||||||
|
readDir( SGPath(aircraft_dir, "gui/dialogs") );
|
||||||
_menubar->init();
|
_menubar->init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -164,8 +164,6 @@
|
||||||
|
|
||||||
#define NOMINMAX 1
|
#define NOMINMAX 1
|
||||||
|
|
||||||
#define HAVE_CULLSETTINGS_CLEAR_MASK 1
|
|
||||||
|
|
||||||
#ifndef ENABLE_AUDIO_SUPPORT
|
#ifndef ENABLE_AUDIO_SUPPORT
|
||||||
#define ENABLE_AUDIO_SUPPORT
|
#define ENABLE_AUDIO_SUPPORT
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -18,7 +18,6 @@
|
||||||
|
|
||||||
#cmakedefine HAVE_SYS_TIME_H
|
#cmakedefine HAVE_SYS_TIME_H
|
||||||
#cmakedefine HAVE_WINDOWS_H
|
#cmakedefine HAVE_WINDOWS_H
|
||||||
#cmakedefine HAVE_CULLSETTINGS_CLEAR_MASK
|
|
||||||
#cmakedefine HAVE_MKFIFO
|
#cmakedefine HAVE_MKFIFO
|
||||||
|
|
||||||
#define VERSION "@FLIGHTGEAR_VERSION@"
|
#define VERSION "@FLIGHTGEAR_VERSION@"
|
||||||
|
|
|
@ -16,8 +16,8 @@
|
||||||
//
|
//
|
||||||
// You should have received a copy of the GNU Library General Public
|
// You should have received a copy of the GNU Library General Public
|
||||||
// License along with this library; if not, write to the
|
// License along with this library; if not, write to the
|
||||||
// Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
// Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||||
// Boston, MA 02111-1307, USA.
|
// Boston, MA 02110-1301, USA.
|
||||||
//
|
//
|
||||||
// $Id$
|
// $Id$
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,6 @@
|
||||||
|
|
||||||
#include "FGButton.hxx"
|
#include "FGButton.hxx"
|
||||||
|
|
||||||
#include <simgear/math/SGMath.hxx>
|
|
||||||
|
|
||||||
FGButton::FGButton ()
|
FGButton::FGButton ()
|
||||||
: is_repeatable(false),
|
: is_repeatable(false),
|
||||||
|
|
|
@ -30,8 +30,6 @@
|
||||||
#include <Main/globals.hxx>
|
#include <Main/globals.hxx>
|
||||||
#include <Main/fg_os.hxx>
|
#include <Main/fg_os.hxx>
|
||||||
|
|
||||||
#include <simgear/math/SGMath.hxx>
|
|
||||||
|
|
||||||
using simgear::PropertyList;
|
using simgear::PropertyList;
|
||||||
using std::string;
|
using std::string;
|
||||||
|
|
||||||
|
|
|
@ -26,8 +26,6 @@
|
||||||
# include <config.h>
|
# include <config.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <simgear/math/SGMath.hxx>
|
|
||||||
|
|
||||||
#include "FGDeviceConfigurationMap.hxx"
|
#include "FGDeviceConfigurationMap.hxx"
|
||||||
|
|
||||||
#include <simgear/misc/sg_dir.hxx>
|
#include <simgear/misc/sg_dir.hxx>
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue