Merge branch 'next' into durk-atc
This commit is contained in:
commit
de1564d83e
80 changed files with 2854 additions and 1040 deletions
|
@ -583,7 +583,7 @@ if test "x$ac_cv_header_simgear_version_h" != "xyes"; then
|
||||||
exit
|
exit
|
||||||
fi
|
fi
|
||||||
|
|
||||||
AC_MSG_CHECKING([for SimGear 2.2.0 or newer])
|
AC_MSG_CHECKING([for SimGear 2.3.0 or newer])
|
||||||
AC_TRY_RUN([
|
AC_TRY_RUN([
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
@ -593,7 +593,7 @@ AC_TRY_RUN([
|
||||||
#define XSTRINGIFY(X) #X
|
#define XSTRINGIFY(X) #X
|
||||||
|
|
||||||
#define MIN_MAJOR 2
|
#define MIN_MAJOR 2
|
||||||
#define MIN_MINOR 2
|
#define MIN_MINOR 3
|
||||||
#define MIN_MICRO 0
|
#define MIN_MICRO 0
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
SDK_PATH="/Developer/SDKs/MacOSX10.5.sdk"
|
SDK_PATH="/Developer/SDKs/MacOSX10.6.sdk"
|
||||||
OSX_TARGET="10.5"
|
OSX_TARGET="10.6"
|
||||||
|
|
||||||
svn co https://macflightgear.svn.sourceforge.net/svnroot/macflightgear/trunk/FlightGearOSX macflightgear
|
svn co https://macflightgear.svn.sourceforge.net/svnroot/macflightgear/trunk/FlightGearOSX macflightgear
|
||||||
|
|
||||||
|
|
|
@ -54,6 +54,11 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "yasim", "yasim\yasim.vcproj
|
||||||
EndProject
|
EndProject
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SimGear", "..\..\..\Simgear\projects\VC90\SimGear.vcproj", "{22540CD3-D3CA-4C86-A773-80AEEE3ACDED}"
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SimGear", "..\..\..\Simgear\projects\VC90\SimGear.vcproj", "{22540CD3-D3CA-4C86-A773-80AEEE3ACDED}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "fgpanel", "fgpanel\fgpanel.vcproj", "{FA27B353-179C-4DE8-B3AC-E260F8F790DD}"
|
||||||
|
ProjectSection(ProjectDependencies) = postProject
|
||||||
|
{22540CD3-D3CA-4C86-A773-80AEEE3ACDED} = {22540CD3-D3CA-4C86-A773-80AEEE3ACDED}
|
||||||
|
EndProjectSection
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Win32 = Debug|Win32
|
Debug|Win32 = Debug|Win32
|
||||||
|
@ -156,6 +161,12 @@ Global
|
||||||
{22540CD3-D3CA-4C86-A773-80AEEE3ACDED}.Release|Win32.Build.0 = Release|Win32
|
{22540CD3-D3CA-4C86-A773-80AEEE3ACDED}.Release|Win32.Build.0 = Release|Win32
|
||||||
{22540CD3-D3CA-4C86-A773-80AEEE3ACDED}.Release|x64.ActiveCfg = Release|x64
|
{22540CD3-D3CA-4C86-A773-80AEEE3ACDED}.Release|x64.ActiveCfg = Release|x64
|
||||||
{22540CD3-D3CA-4C86-A773-80AEEE3ACDED}.Release|x64.Build.0 = Release|x64
|
{22540CD3-D3CA-4C86-A773-80AEEE3ACDED}.Release|x64.Build.0 = Release|x64
|
||||||
|
{FA27B353-179C-4DE8-B3AC-E260F8F790DD}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||||
|
{FA27B353-179C-4DE8-B3AC-E260F8F790DD}.Debug|Win32.Build.0 = Debug|Win32
|
||||||
|
{FA27B353-179C-4DE8-B3AC-E260F8F790DD}.Debug|x64.ActiveCfg = Debug|Win32
|
||||||
|
{FA27B353-179C-4DE8-B3AC-E260F8F790DD}.Release|Win32.ActiveCfg = Release|Win32
|
||||||
|
{FA27B353-179C-4DE8-B3AC-E260F8F790DD}.Release|Win32.Build.0 = Release|Win32
|
||||||
|
{FA27B353-179C-4DE8-B3AC-E260F8F790DD}.Release|x64.ActiveCfg = Release|Win32
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
|
|
@ -2977,6 +2977,14 @@
|
||||||
RelativePath="..\..\..\src\Network\AV400Sim.hxx"
|
RelativePath="..\..\..\src\Network\AV400Sim.hxx"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\src\Network\AV400WSim.cxx"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\src\Network\AV400WSim.hxx"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\..\src\Network\garmin.cxx"
|
RelativePath="..\..\..\src\Network\garmin.cxx"
|
||||||
>
|
>
|
||||||
|
@ -3025,14 +3033,6 @@
|
||||||
RelativePath="..\..\..\src\Network\jsclient.hxx"
|
RelativePath="..\..\..\src\Network\jsclient.hxx"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
|
||||||
RelativePath="..\..\..\src\Network\multiplay.cxx"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\..\..\src\Network\multiplay.hxx"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\..\src\Network\native.cxx"
|
RelativePath="..\..\..\src\Network\native.cxx"
|
||||||
>
|
>
|
||||||
|
@ -3437,6 +3437,14 @@
|
||||||
RelativePath="..\..\..\src\Environment\presets.hxx"
|
RelativePath="..\..\..\src\Environment\presets.hxx"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\src\Environment\gravity.cxx"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\src\Environment\gravity.hxx"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
</Filter>
|
</Filter>
|
||||||
<Filter
|
<Filter
|
||||||
Name="Lib_Model"
|
Name="Lib_Model"
|
||||||
|
|
1
projects/VC90/fgpanel/.gitignore
vendored
Executable file
1
projects/VC90/fgpanel/.gitignore
vendored
Executable file
|
@ -0,0 +1 @@
|
||||||
|
*.user
|
262
projects/VC90/fgpanel/fgpanel.vcproj
Executable file
262
projects/VC90/fgpanel/fgpanel.vcproj
Executable file
|
@ -0,0 +1,262 @@
|
||||||
|
<?xml version="1.0" encoding="Windows-1252"?>
|
||||||
|
<VisualStudioProject
|
||||||
|
ProjectType="Visual C++"
|
||||||
|
Version="9,00"
|
||||||
|
Name="fgpanel"
|
||||||
|
ProjectGUID="{FA27B353-179C-4DE8-B3AC-E260F8F790DD}"
|
||||||
|
RootNamespace="fgpanel"
|
||||||
|
Keyword="Win32Proj"
|
||||||
|
TargetFrameworkVersion="196613"
|
||||||
|
>
|
||||||
|
<Platforms>
|
||||||
|
<Platform
|
||||||
|
Name="Win32"
|
||||||
|
/>
|
||||||
|
</Platforms>
|
||||||
|
<ToolFiles>
|
||||||
|
</ToolFiles>
|
||||||
|
<Configurations>
|
||||||
|
<Configuration
|
||||||
|
Name="Debug|Win32"
|
||||||
|
OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
|
||||||
|
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
|
||||||
|
ConfigurationType="1"
|
||||||
|
CharacterSet="2"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreBuildEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCustomBuildTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXMLDataGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCWebServiceProxyGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCMIDLTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
Optimization="0"
|
||||||
|
AdditionalIncludeDirectories="..\..\..\..\SimGear;..\..\..\..\boost_1_44_0;..\..\..\..\install\msvc90\OpenSceneGraph\include;..\..\..\..\3rdParty\include;..\..\..\src\include"
|
||||||
|
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;NOMINMAX;HAVE_CONFIG_H"
|
||||||
|
MinimalRebuild="true"
|
||||||
|
BasicRuntimeChecks="3"
|
||||||
|
RuntimeLibrary="3"
|
||||||
|
UsePrecompiledHeader="0"
|
||||||
|
WarningLevel="3"
|
||||||
|
DebugInformationFormat="4"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManagedResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreLinkEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCLinkerTool"
|
||||||
|
AdditionalDependencies="wsock32.lib zlibd.lib libpngd.lib fnt_d.lib ul_d.lib sg_d.lib pui_d.lib"
|
||||||
|
LinkIncremental="2"
|
||||||
|
AdditionalLibraryDirectories="..\..\..\..\install\msvc90\OpenSceneGraph\lib;..\..\..\..\3rdParty\lib"
|
||||||
|
GenerateDebugInformation="true"
|
||||||
|
SubSystem="1"
|
||||||
|
TargetMachine="1"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCALinkTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManifestTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXDCMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCBscMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCFxCopTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCAppVerifierTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPostBuildEventTool"
|
||||||
|
/>
|
||||||
|
</Configuration>
|
||||||
|
<Configuration
|
||||||
|
Name="Release|Win32"
|
||||||
|
OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
|
||||||
|
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
|
||||||
|
ConfigurationType="1"
|
||||||
|
CharacterSet="2"
|
||||||
|
WholeProgramOptimization="1"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreBuildEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCustomBuildTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXMLDataGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCWebServiceProxyGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCMIDLTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
Optimization="2"
|
||||||
|
EnableIntrinsicFunctions="true"
|
||||||
|
AdditionalIncludeDirectories="..\..\..\src;..\..\..\src\include;..\..\..\src\FDM\JSBSim;..\..\..\..\SimGear;..\..\..\..\install\msvc90\OpenSceneGraph\include;..\..\..\..\3rdParty\include;..\..\..\..\boost_1_44_0"
|
||||||
|
PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;HAVE_CONFIG_H;FGFS;ENABLE_AUDIO_SUPPORT;_FG_NDEBUG;ENABLE_THREADS=1;FG_ENABLE_MULTIPASS_CLOUDS;ENABLE_SP_FMDS;_USE_MATH_DEFINES;FG_JPEG_SERVER;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;HAVE_VERSION_H=$(HAVE_VERSION_H)0"
|
||||||
|
StringPooling="true"
|
||||||
|
RuntimeLibrary="2"
|
||||||
|
EnableFunctionLevelLinking="true"
|
||||||
|
UsePrecompiledHeader="0"
|
||||||
|
WarningLevel="3"
|
||||||
|
DebugInformationFormat="3"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManagedResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreLinkEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCLinkerTool"
|
||||||
|
AdditionalDependencies="wsock32.lib net.lib sg.lib pui.lib fnt.lib ul.lib libpng.lib zlib.lib "
|
||||||
|
LinkIncremental="1"
|
||||||
|
AdditionalLibraryDirectories="..\..\..\..\install\msvc90\OpenSceneGraph\lib;..\..\..\..\3rdParty\lib"
|
||||||
|
GenerateDebugInformation="true"
|
||||||
|
SubSystem="1"
|
||||||
|
OptimizeReferences="2"
|
||||||
|
EnableCOMDATFolding="2"
|
||||||
|
RandomizedBaseAddress="1"
|
||||||
|
DataExecutionPrevention="0"
|
||||||
|
TargetMachine="0"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCALinkTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManifestTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXDCMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCBscMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCFxCopTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCAppVerifierTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPostBuildEventTool"
|
||||||
|
/>
|
||||||
|
</Configuration>
|
||||||
|
</Configurations>
|
||||||
|
<References>
|
||||||
|
</References>
|
||||||
|
<Files>
|
||||||
|
<Filter
|
||||||
|
Name="Source Files"
|
||||||
|
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||||
|
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
|
||||||
|
>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\utils\fgpanel\ApplicationProperties.hxx"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\utils\fgpanel\FGFontCache.cxx"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\utils\fgpanel\FGFontCache.hxx"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\utils\fgpanel\FGGLApplication.cxx"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\utils\fgpanel\FGGLApplication.hxx"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\utils\fgpanel\FGPanelApplication.cxx"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\utils\fgpanel\FGPanelApplication.hxx"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\utils\fgpanel\FGPanelProtocol.cxx"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\utils\fgpanel\FGPanelProtocol.hxx"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\utils\fgpanel\FGPNGTextureLoader.cxx"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\utils\fgpanel\FGPNGTextureLoader.hxx"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\utils\fgpanel\FGRGBTextureLoader.cxx"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\utils\fgpanel\FGRGBTextureLoader.hxx"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\utils\fgpanel\FGTextureLoaderInterface.hxx"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\utils\fgpanel\main.cxx"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\utils\fgpanel\panel.cxx"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\utils\fgpanel\panel.hxx"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\utils\fgpanel\panel_io.cxx"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\utils\fgpanel\panel_io.hxx"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
</Filter>
|
||||||
|
</Files>
|
||||||
|
<Globals>
|
||||||
|
</Globals>
|
||||||
|
</VisualStudioProject>
|
|
@ -182,7 +182,7 @@ void FGAIBallistic::bind() {
|
||||||
|
|
||||||
props->tie("sim/time/elapsed-sec",
|
props->tie("sim/time/elapsed-sec",
|
||||||
SGRawValueMethods<FGAIBallistic,double>(*this,
|
SGRawValueMethods<FGAIBallistic,double>(*this,
|
||||||
&FGAIBallistic::_getTime));
|
&FGAIBallistic::_getTime, &FGAIBallistic::setTime));
|
||||||
//props->tie("mass-slug",
|
//props->tie("mass-slug",
|
||||||
// SGRawValueMethods<FGAIBallistic,double>(*this,
|
// SGRawValueMethods<FGAIBallistic,double>(*this,
|
||||||
// &FGAIBallistic::getMass));
|
// &FGAIBallistic::getMass));
|
||||||
|
@ -586,6 +586,7 @@ void FGAIBallistic::setHt(double h, double dt, double coeff){
|
||||||
int FGAIBallistic::setHdg(double tgt_hdg, double dt, double coeff){
|
int FGAIBallistic::setHdg(double tgt_hdg, double dt, double coeff){
|
||||||
double recip = getRecip(hdg);
|
double recip = getRecip(hdg);
|
||||||
double c = dt / (coeff + dt);
|
double c = dt / (coeff + dt);
|
||||||
|
//cout << "set heading " << tgt_hdg << endl;
|
||||||
//we need to ensure that we turn the short way to the new hdg
|
//we need to ensure that we turn the short way to the new hdg
|
||||||
if (tgt_hdg < recip && tgt_hdg < hdg && hdg > 180) {
|
if (tgt_hdg < recip && tgt_hdg < hdg && hdg > 180) {
|
||||||
hdg = ((tgt_hdg + 360) * c) + (hdg * (1 - c));
|
hdg = ((tgt_hdg + 360) * c) + (hdg * (1 - c));
|
||||||
|
@ -626,6 +627,9 @@ void FGAIBallistic::setTgtZOffset(double z){
|
||||||
|
|
||||||
void FGAIBallistic::slaveToAC(double dt){
|
void FGAIBallistic::slaveToAC(double dt){
|
||||||
|
|
||||||
|
if (invisible)
|
||||||
|
return;
|
||||||
|
|
||||||
double hdg, pch, rll, agl = 0;
|
double hdg, pch, rll, agl = 0;
|
||||||
|
|
||||||
if (_pnode != 0) {
|
if (_pnode != 0) {
|
||||||
|
@ -652,6 +656,7 @@ void FGAIBallistic::slaveToAC(double dt){
|
||||||
setPitch(pch + _pitch_offset);
|
setPitch(pch + _pitch_offset);
|
||||||
setBank(rll + _roll_offset);
|
setBank(rll + _roll_offset);
|
||||||
setOffsetVelocity(dt, pos);
|
setOffsetVelocity(dt, pos);
|
||||||
|
setTime(0);
|
||||||
|
|
||||||
//update the mass (slugs)
|
//update the mass (slugs)
|
||||||
_mass = (_weight_lb + getContents()) / slugs_to_lbs;
|
_mass = (_weight_lb + getContents()) / slugs_to_lbs;
|
||||||
|
@ -710,23 +715,13 @@ void FGAIBallistic::Run(double dt) {
|
||||||
speed = 0.0;
|
speed = 0.0;
|
||||||
|
|
||||||
double speed_fps = speed * SG_KT_TO_FPS;
|
double speed_fps = speed * SG_KT_TO_FPS;
|
||||||
//double hs;
|
|
||||||
|
|
||||||
// calculate vertical and horizontal speed components
|
// calculate vertical and horizontal speed components
|
||||||
if (speed == 0.0) {
|
calcVSHS();
|
||||||
hs = vs = 0.0;
|
|
||||||
} else {
|
|
||||||
vs = sin( _elevation * SG_DEGREES_TO_RADIANS ) * speed_fps;
|
|
||||||
hs = cos( _elevation * SG_DEGREES_TO_RADIANS ) * speed_fps;
|
|
||||||
}
|
|
||||||
|
|
||||||
//resolve horizontal speed into north and east components:
|
//resolve horizontal speed into north and east components:
|
||||||
double speed_north_fps = cos(_azimuth / SG_RADIANS_TO_DEGREES) * hs;
|
//and convert horizontal speed (fps) to degrees per second
|
||||||
double speed_east_fps = sin(_azimuth / SG_RADIANS_TO_DEGREES) * hs;
|
calcNE();
|
||||||
|
|
||||||
// convert horizontal speed (fps) to degrees per second
|
|
||||||
double speed_north_deg_sec = speed_north_fps / ft_per_deg_lat;
|
|
||||||
double speed_east_deg_sec = speed_east_fps / ft_per_deg_lon;
|
|
||||||
|
|
||||||
// if wind not required, set to zero
|
// if wind not required, set to zero
|
||||||
if (!_wind) {
|
if (!_wind) {
|
||||||
|
@ -755,20 +750,24 @@ void FGAIBallistic::Run(double dt) {
|
||||||
double friction_force_speed_north_deg_sec = 0;
|
double friction_force_speed_north_deg_sec = 0;
|
||||||
double friction_force_speed_east_deg_sec = 0;
|
double friction_force_speed_east_deg_sec = 0;
|
||||||
double force_elevation_deg = 0;
|
double force_elevation_deg = 0;
|
||||||
|
double force_azimuth_deg = 0;
|
||||||
|
double force_lbs = 0;
|
||||||
|
|
||||||
if (_external_force) {
|
if (_external_force) {
|
||||||
//cout << _name << " external force" << endl;
|
//cout << _name << " external force " << hdg << " az " << _azimuth << endl;
|
||||||
|
|
||||||
SGPropertyNode *n = fgGetNode(_force_path.c_str(), true);
|
SGPropertyNode *n = fgGetNode(_force_path.c_str(), true);
|
||||||
double force_lbs = n->getChild("force-lb", 0, true)->getDoubleValue();
|
force_lbs = n->getChild("force-lb", 0, true)->getDoubleValue();
|
||||||
force_elevation_deg = n->getChild("force-elevation-deg", 0, true)->getDoubleValue();
|
force_elevation_deg = n->getChild("force-elevation-deg", 0, true)->getDoubleValue();
|
||||||
double force_azimuth_deg = n->getChild("force-azimuth-deg", 0, true)->getDoubleValue();
|
force_azimuth_deg = n->getChild("force-azimuth-deg", 0, true)->getDoubleValue();
|
||||||
|
|
||||||
//resolve force into vertical and horizontal components:
|
//resolve force into vertical and horizontal components:
|
||||||
double v_force_lbs = force_lbs * sin( force_elevation_deg * SG_DEGREES_TO_RADIANS );
|
double v_force_lbs = force_lbs * sin( force_elevation_deg * SG_DEGREES_TO_RADIANS );
|
||||||
h_force_lbs = force_lbs * cos( force_elevation_deg * SG_DEGREES_TO_RADIANS );
|
h_force_lbs = force_lbs * cos( force_elevation_deg * SG_DEGREES_TO_RADIANS );
|
||||||
|
|
||||||
//ground interaction
|
//ground interaction
|
||||||
|
//we don't do this if impacts are calculated
|
||||||
|
if(!_report_impact){
|
||||||
|
|
||||||
if (getHtAGL(10000)){
|
if (getHtAGL(10000)){
|
||||||
double deadzone = 0.1;
|
double deadzone = 0.1;
|
||||||
|
@ -792,7 +791,7 @@ void FGAIBallistic::Run(double dt) {
|
||||||
//adjust horizontal force. We assume that a speed of <= 5 fps is static
|
//adjust horizontal force. We assume that a speed of <= 5 fps is static
|
||||||
if (h_force_lbs <= static_friction_force_lbs && hs <= 5){
|
if (h_force_lbs <= static_friction_force_lbs && hs <= 5){
|
||||||
h_force_lbs = hs = 0;
|
h_force_lbs = hs = 0;
|
||||||
speed_north_fps = speed_east_fps = 0;
|
_speed_north_fps = _speed_east_fps = 0;
|
||||||
} else
|
} else
|
||||||
dynamic_friction_force_lbs = (static_friction_force_lbs * 0.95);
|
dynamic_friction_force_lbs = (static_friction_force_lbs * 0.95);
|
||||||
|
|
||||||
|
@ -805,6 +804,8 @@ void FGAIBallistic::Run(double dt) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} //endif
|
||||||
|
|
||||||
//acceleration = (force(lbsf)/mass(slugs))
|
//acceleration = (force(lbsf)/mass(slugs))
|
||||||
v_force_acc_fpss = v_force_lbs/_mass;
|
v_force_acc_fpss = v_force_lbs/_mass;
|
||||||
normal_force_fpss = normal_force_lbs/_mass;
|
normal_force_fpss = normal_force_lbs/_mass;
|
||||||
|
@ -835,10 +836,10 @@ void FGAIBallistic::Run(double dt) {
|
||||||
double wind_speed_from_east_deg_sec = _wind_from_east / ft_per_deg_lon;
|
double wind_speed_from_east_deg_sec = _wind_from_east / ft_per_deg_lon;
|
||||||
|
|
||||||
//recombine the horizontal velocity components
|
//recombine the horizontal velocity components
|
||||||
hs = sqrt(((speed_north_fps + force_speed_north_fps + friction_force_speed_north_fps)
|
hs = sqrt(((_speed_north_fps + force_speed_north_fps + friction_force_speed_north_fps)
|
||||||
* (speed_north_fps + force_speed_north_fps + friction_force_speed_north_fps))
|
* (_speed_north_fps + force_speed_north_fps + friction_force_speed_north_fps))
|
||||||
+ ((speed_east_fps + force_speed_east_fps + friction_force_speed_east_fps)
|
+ ((_speed_east_fps + force_speed_east_fps + friction_force_speed_east_fps)
|
||||||
* (speed_east_fps + force_speed_east_fps + friction_force_speed_east_fps)));
|
* (_speed_east_fps + force_speed_east_fps + friction_force_speed_east_fps)));
|
||||||
|
|
||||||
if (hs <= 0.00001)
|
if (hs <= 0.00001)
|
||||||
hs = 0;
|
hs = 0;
|
||||||
|
@ -890,8 +891,8 @@ void FGAIBallistic::Run(double dt) {
|
||||||
|
|
||||||
// recalculate elevation and azimuth (velocity vectors)
|
// recalculate elevation and azimuth (velocity vectors)
|
||||||
_elevation = atan2( vs, hs ) * SG_RADIANS_TO_DEGREES;
|
_elevation = atan2( vs, hs ) * SG_RADIANS_TO_DEGREES;
|
||||||
_azimuth = atan2((speed_east_fps + force_speed_east_fps + friction_force_speed_east_fps),
|
_azimuth = atan2((_speed_east_fps + force_speed_east_fps + friction_force_speed_east_fps),
|
||||||
(speed_north_fps + force_speed_north_fps + friction_force_speed_north_fps))
|
(_speed_north_fps + force_speed_north_fps + friction_force_speed_north_fps))
|
||||||
* SG_RADIANS_TO_DEGREES;
|
* SG_RADIANS_TO_DEGREES;
|
||||||
|
|
||||||
// rationalise azimuth
|
// rationalise azimuth
|
||||||
|
@ -899,7 +900,7 @@ void FGAIBallistic::Run(double dt) {
|
||||||
_azimuth += 360;
|
_azimuth += 360;
|
||||||
|
|
||||||
if (_aero_stabilised) { // we simulate rotational moment of inertia by using a filter
|
if (_aero_stabilised) { // we simulate rotational moment of inertia by using a filter
|
||||||
//cout<< "_aero_stabilised "<< endl;
|
//cout<< "_aero_stabilised " << hdg << " az " << _azimuth << endl;
|
||||||
const double coeff = 0.9;
|
const double coeff = 0.9;
|
||||||
|
|
||||||
// we assume a symetrical MI about the pitch and yaw axis
|
// we assume a symetrical MI about the pitch and yaw axis
|
||||||
|
@ -941,16 +942,20 @@ double FGAIBallistic::_getTime() const {
|
||||||
return _life_timer;
|
return _life_timer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FGAIBallistic::setTime(double s){
|
||||||
|
_life_timer = s;
|
||||||
|
}
|
||||||
|
|
||||||
void FGAIBallistic::handle_impact() {
|
void FGAIBallistic::handle_impact() {
|
||||||
|
|
||||||
// try terrain intersection
|
// try terrain intersection
|
||||||
double start = pos.getElevationM() + 10;
|
double start = pos.getElevationM() + 100;
|
||||||
|
|
||||||
if(!getHtAGL(start))
|
if(!getHtAGL(start))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (_ht_agl_ft <= 0) {
|
if (_ht_agl_ft <= 0) {
|
||||||
SG_LOG(SG_GENERAL, SG_DEBUG, "AIBallistic: terrain impact");
|
SG_LOG(SG_GENERAL, SG_DEBUG, "AIBallistic: terrain impact material" << _mat_name);
|
||||||
report_impact(_elevation_m);
|
report_impact(_elevation_m);
|
||||||
_impact_reported = true;
|
_impact_reported = true;
|
||||||
|
|
||||||
|
@ -1004,7 +1009,8 @@ void FGAIBallistic::report_impact(double elevation, const FGAIBase *object)
|
||||||
else
|
else
|
||||||
n->setStringValue("type", "terrain");
|
n->setStringValue("type", "terrain");
|
||||||
|
|
||||||
SG_LOG(SG_GENERAL, SG_DEBUG, "AIBallistic: object impact" << _name << " lon " <<_impact_lon);
|
SG_LOG(SG_GENERAL, SG_DEBUG, "AIBallistic: object impact " << _name
|
||||||
|
<< " lon " <<_impact_lon << " lat " <<_impact_lat);
|
||||||
|
|
||||||
n->setDoubleValue("longitude-deg", _impact_lon);
|
n->setDoubleValue("longitude-deg", _impact_lon);
|
||||||
n->setDoubleValue("latitude-deg", _impact_lat);
|
n->setDoubleValue("latitude-deg", _impact_lat);
|
||||||
|
@ -1239,9 +1245,17 @@ void FGAIBallistic::setOffsetVelocity(double dt, SGGeod offsetpos) {
|
||||||
calcVSHS();
|
calcVSHS();
|
||||||
|
|
||||||
//calculate the bearing of the new offset position from the old
|
//calculate the bearing of the new offset position from the old
|
||||||
|
//don't do this if speed is low
|
||||||
|
//cout << "speed " << speed << endl;
|
||||||
|
if (speed > 0.1){
|
||||||
double az1, az2, dist;
|
double az1, az2, dist;
|
||||||
geo_inverse_wgs_84(_oldoffsetpos, offsetpos, &az1, &az2, &dist);
|
geo_inverse_wgs_84(_oldoffsetpos, offsetpos, &az1, &az2, &dist);
|
||||||
_azimuth = az1;
|
_azimuth = az1;
|
||||||
|
//cout << "offset az " << _azimuth << endl;
|
||||||
|
} else {
|
||||||
|
_azimuth = hdg;
|
||||||
|
//cout << " slow offset az " << _azimuth << endl;
|
||||||
|
}
|
||||||
|
|
||||||
//resolve horizontal speed into north and east components:
|
//resolve horizontal speed into north and east components:
|
||||||
calcNE();
|
calcNE();
|
||||||
|
|
|
@ -96,9 +96,9 @@ public:
|
||||||
void setParentPos();
|
void setParentPos();
|
||||||
void setOffsetPos(SGGeod pos, double heading, double pitch, double roll);
|
void setOffsetPos(SGGeod pos, double heading, double pitch, double roll);
|
||||||
void setOffsetVelocity(double dt, SGGeod pos);
|
void setOffsetVelocity(double dt, SGGeod pos);
|
||||||
|
void setTime(double sec);
|
||||||
|
|
||||||
|
double _getTime()const;
|
||||||
double _getTime() const;
|
|
||||||
double getRelBrgHitchToUser() const;
|
double getRelBrgHitchToUser() const;
|
||||||
double getElevHitchToUser() const;
|
double getElevHitchToUser() const;
|
||||||
double getLoadOffset() const;
|
double getLoadOffset() const;
|
||||||
|
|
|
@ -100,6 +100,7 @@ void FGReplay::init()
|
||||||
disable_replay = fgGetNode( "/sim/replay/disable", true );
|
disable_replay = fgGetNode( "/sim/replay/disable", true );
|
||||||
replay_master = fgGetNode( "/sim/freeze/replay-state", true );
|
replay_master = fgGetNode( "/sim/freeze/replay-state", true );
|
||||||
replay_time = fgGetNode( "/sim/replay/time", true);
|
replay_time = fgGetNode( "/sim/replay/time", true);
|
||||||
|
replay_looped = fgGetNode( "/sim/replay/looped", true);
|
||||||
reinit();
|
reinit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -194,10 +195,28 @@ void FGReplay::update( double dt )
|
||||||
// replay inactive, keep recording
|
// replay inactive, keep recording
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
|
{
|
||||||
// replay active
|
// replay active
|
||||||
replay( replay_time->getDoubleValue() );
|
double current_time = replay_time->getDoubleValue();
|
||||||
replay_time->setDoubleValue( replay_time->getDoubleValue()
|
if (current_time<0.0)
|
||||||
+ ( dt * fgGetInt("/sim/speed-up") ) );
|
{
|
||||||
|
// initialize start time
|
||||||
|
fgSetDouble( "/sim/replay/start-time", get_start_time() );
|
||||||
|
fgSetDouble( "/sim/replay/end-time", get_end_time() );
|
||||||
|
double duration = fgGetDouble( "/sim/replay/duration" );
|
||||||
|
if( duration && duration < (get_end_time() - get_start_time()) ) {
|
||||||
|
current_time = get_end_time() - duration;
|
||||||
|
} else {
|
||||||
|
current_time = get_start_time();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bool IsFinished = replay( replay_time->getDoubleValue() );
|
||||||
|
if ((IsFinished)&&(replay_looped->getBoolValue()))
|
||||||
|
current_time = -1;
|
||||||
|
else
|
||||||
|
current_time += dt * fgGetInt("/sim/speed-up");
|
||||||
|
replay_time->setDoubleValue(current_time);
|
||||||
|
}
|
||||||
return; // don't record the replay session
|
return; // don't record the replay session
|
||||||
case 2:
|
case 2:
|
||||||
// replay paused, no-op
|
// replay paused, no-op
|
||||||
|
@ -558,9 +577,10 @@ static void interpolate( double time, const replay_list_type &list ) {
|
||||||
/**
|
/**
|
||||||
* Replay a saved frame based on time, interpolate from the two
|
* Replay a saved frame based on time, interpolate from the two
|
||||||
* nearest saved frames.
|
* nearest saved frames.
|
||||||
|
* Returns true when replay sequence has finished, false otherwise.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void FGReplay::replay( double time ) {
|
bool FGReplay::replay( double time ) {
|
||||||
// cout << "replay: " << time << " ";
|
// cout << "replay: " << time << " ";
|
||||||
// find the two frames to interpolate between
|
// find the two frames to interpolate between
|
||||||
double t1, t2;
|
double t1, t2;
|
||||||
|
@ -571,6 +591,8 @@ void FGReplay::replay( double time ) {
|
||||||
if ( time > t1 ) {
|
if ( time > t1 ) {
|
||||||
// replay the most recent frame
|
// replay the most recent frame
|
||||||
update_fdm( (*short_term.back()) );
|
update_fdm( (*short_term.back()) );
|
||||||
|
// replay is finished now
|
||||||
|
return true;
|
||||||
// cout << "first frame" << endl;
|
// cout << "first frame" << endl;
|
||||||
} else if ( time <= t1 && time >= t2 ) {
|
} else if ( time <= t1 && time >= t2 ) {
|
||||||
interpolate( time, short_term );
|
interpolate( time, short_term );
|
||||||
|
@ -624,7 +646,9 @@ void FGReplay::replay( double time ) {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// nothing to replay
|
// nothing to replay
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -74,7 +74,7 @@ public:
|
||||||
virtual void unbind();
|
virtual void unbind();
|
||||||
virtual void update( double dt );
|
virtual void update( double dt );
|
||||||
|
|
||||||
void replay( double time );
|
bool replay( double time );
|
||||||
double get_start_time();
|
double get_start_time();
|
||||||
double get_end_time();
|
double get_end_time();
|
||||||
|
|
||||||
|
@ -101,6 +101,7 @@ private:
|
||||||
SGPropertyNode_ptr disable_replay;
|
SGPropertyNode_ptr disable_replay;
|
||||||
SGPropertyNode_ptr replay_master;
|
SGPropertyNode_ptr replay_master;
|
||||||
SGPropertyNode_ptr replay_time;
|
SGPropertyNode_ptr replay_time;
|
||||||
|
SGPropertyNode_ptr replay_looped;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -14,8 +14,8 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
#include <simgear/misc/sg_path.hxx>
|
#include <simgear/misc/sg_path.hxx>
|
||||||
|
|
||||||
#include <simgear/xml/easyxml.hxx>
|
#include <simgear/xml/easyxml.hxx>
|
||||||
|
#include <simgear/misc/strutils.hxx>
|
||||||
|
|
||||||
#include <Main/globals.hxx>
|
#include <Main/globals.hxx>
|
||||||
#include <Main/fg_props.hxx>
|
#include <Main/fg_props.hxx>
|
||||||
|
@ -84,11 +84,16 @@ void XMLLoader::load(FGSidStar* p) {
|
||||||
bool XMLLoader::findAirportData(const std::string& aICAO,
|
bool XMLLoader::findAirportData(const std::string& aICAO,
|
||||||
const std::string& aFileName, SGPath& aPath)
|
const std::string& aFileName, SGPath& aPath)
|
||||||
{
|
{
|
||||||
|
string fileName(aFileName);
|
||||||
|
if (!simgear::strutils::ends_with(aFileName, ".xml")) {
|
||||||
|
fileName.append(".xml");
|
||||||
|
}
|
||||||
|
|
||||||
string_list sc = globals->get_fg_scenery();
|
string_list sc = globals->get_fg_scenery();
|
||||||
char buffer[128];
|
char buffer[128];
|
||||||
::snprintf(buffer, 128, "%c/%c/%c/%s.%s.xml",
|
::snprintf(buffer, 128, "%c/%c/%c/%s.%s",
|
||||||
aICAO[0], aICAO[1], aICAO[2],
|
aICAO[0], aICAO[1], aICAO[2],
|
||||||
aICAO.c_str(), aFileName.c_str());
|
aICAO.c_str(), fileName.c_str());
|
||||||
|
|
||||||
for (string_list_iterator it = sc.begin(); it != sc.end(); ++it) {
|
for (string_list_iterator it = sc.begin(); it != sc.end(); ++it) {
|
||||||
SGPath path(*it);
|
SGPath path(*it);
|
||||||
|
|
|
@ -224,6 +224,15 @@ void FGRouteMgr::init() {
|
||||||
|
|
||||||
void FGRouteMgr::postinit()
|
void FGRouteMgr::postinit()
|
||||||
{
|
{
|
||||||
|
SGPath path(_pathNode->getStringValue());
|
||||||
|
if (path.exists()) {
|
||||||
|
SG_LOG(SG_AUTOPILOT, SG_INFO, "loading flight-plan from:" << path.str());
|
||||||
|
loadRoute();
|
||||||
|
}
|
||||||
|
|
||||||
|
// this code only matters for the --wp option now - perhaps the option
|
||||||
|
// should be deprecated in favour of an explicit flight-plan file?
|
||||||
|
// then the global initial waypoint list could die.
|
||||||
string_list *waypoints = globals->get_initial_waypoints();
|
string_list *waypoints = globals->get_initial_waypoints();
|
||||||
if (waypoints) {
|
if (waypoints) {
|
||||||
string_list::iterator it;
|
string_list::iterator it;
|
||||||
|
|
|
@ -16,6 +16,7 @@ set(SOURCES
|
||||||
ridge_lift.cxx
|
ridge_lift.cxx
|
||||||
terrainsampler.cxx
|
terrainsampler.cxx
|
||||||
presets.cxx
|
presets.cxx
|
||||||
|
gravity.cxx
|
||||||
)
|
)
|
||||||
|
|
||||||
flightgear_component(Environment "${SOURCES}")
|
flightgear_component(Environment "${SOURCES}")
|
||||||
|
|
|
@ -17,6 +17,7 @@ libEnvironment_a_SOURCES = \
|
||||||
ridge_lift.cxx ridge_lift.hxx \
|
ridge_lift.cxx ridge_lift.hxx \
|
||||||
ephemeris.cxx ephemeris.hxx \
|
ephemeris.cxx ephemeris.hxx \
|
||||||
terrainsampler.cxx terrainsampler.cxx \
|
terrainsampler.cxx terrainsampler.cxx \
|
||||||
presets.cxx presets.hxx
|
presets.cxx presets.hxx \
|
||||||
|
gravity.cxx gravity.hxx
|
||||||
|
|
||||||
INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/src
|
INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/src
|
||||||
|
|
|
@ -31,8 +31,6 @@
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Model the atmosphere in a way consistent with the laws
|
* Model the atmosphere in a way consistent with the laws
|
||||||
* of physics.
|
* of physics.
|
||||||
|
|
|
@ -27,7 +27,6 @@
|
||||||
#include <simgear/constants.h>
|
#include <simgear/constants.h>
|
||||||
#include <simgear/debug/logstream.hxx>
|
#include <simgear/debug/logstream.hxx>
|
||||||
#include <simgear/scene/sky/sky.hxx>
|
#include <simgear/scene/sky/sky.hxx>
|
||||||
#include <simgear/environment/visual_enviro.hxx>
|
|
||||||
#include <simgear/scene/model/particles.hxx>
|
#include <simgear/scene/model/particles.hxx>
|
||||||
|
|
||||||
#include <Main/main.hxx>
|
#include <Main/main.hxx>
|
||||||
|
@ -43,6 +42,7 @@
|
||||||
#include "ridge_lift.hxx"
|
#include "ridge_lift.hxx"
|
||||||
#include "terrainsampler.hxx"
|
#include "terrainsampler.hxx"
|
||||||
#include "Airports/simple.hxx"
|
#include "Airports/simple.hxx"
|
||||||
|
#include "gravity.hxx"
|
||||||
|
|
||||||
class SGSky;
|
class SGSky;
|
||||||
extern SGSky *thesky;
|
extern SGSky *thesky;
|
||||||
|
@ -51,7 +51,7 @@ FGEnvironmentMgr::FGEnvironmentMgr () :
|
||||||
_environment(new FGEnvironment()),
|
_environment(new FGEnvironment()),
|
||||||
fgClouds(new FGClouds()),
|
fgClouds(new FGClouds()),
|
||||||
_cloudLayersDirty(true),
|
_cloudLayersDirty(true),
|
||||||
_altitudeNode(fgGetNode("/position/altitude-ft", true)),
|
_altitude_n(fgGetNode("/position/altitude-ft", true)),
|
||||||
_longitude_n(fgGetNode( "/position/longitude-deg", true )),
|
_longitude_n(fgGetNode( "/position/longitude-deg", true )),
|
||||||
_latitude_n( fgGetNode( "/position/latitude-deg", true )),
|
_latitude_n( fgGetNode( "/position/latitude-deg", true )),
|
||||||
_positionTimeToLive(0.0)
|
_positionTimeToLive(0.0)
|
||||||
|
@ -98,6 +98,14 @@ FGEnvironmentMgr::init ()
|
||||||
SG_LOG( SG_GENERAL, SG_INFO, "Initializing environment subsystem");
|
SG_LOG( SG_GENERAL, SG_INFO, "Initializing environment subsystem");
|
||||||
SGSubsystemGroup::init();
|
SGSubsystemGroup::init();
|
||||||
fgClouds->Init();
|
fgClouds->Init();
|
||||||
|
|
||||||
|
// FIXME: is this really part of the environment_mgr?
|
||||||
|
// Initialize the longitude, latitude and altitude to the initial position
|
||||||
|
// of the aircraft so that the atmospheric properties (pressure, temperature
|
||||||
|
// and density) can be initialized accordingly.
|
||||||
|
_altitude_n->setDoubleValue(fgGetDouble("/sim/presets/altitude-ft"));
|
||||||
|
_longitude_n->setDoubleValue(fgGetDouble("/sim/presets/longitude-deg"));
|
||||||
|
_latitude_n->setDoubleValue(fgGetDouble("/sim/presets/latitude-deg"));
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -122,9 +130,9 @@ FGEnvironmentMgr::bind ()
|
||||||
&FGClouds::get_update_event,
|
&FGClouds::get_update_event,
|
||||||
&FGClouds::set_update_event);
|
&FGClouds::set_update_event);
|
||||||
|
|
||||||
_tiedProperties.Tie("turbulence/use-cloud-turbulence", &sgEnviro,
|
// _tiedProperties.Tie("turbulence/use-cloud-turbulence", &sgEnviro,
|
||||||
&SGEnviro::get_turbulence_enable_state,
|
// &SGEnviro::get_turbulence_enable_state,
|
||||||
&SGEnviro::set_turbulence_enable_state);
|
// &SGEnviro::set_turbulence_enable_state);
|
||||||
|
|
||||||
for (int i = 0; i < MAX_CLOUD_LAYERS; i++) {
|
for (int i = 0; i < MAX_CLOUD_LAYERS; i++) {
|
||||||
SGPropertyNode_ptr layerNode = fgGetNode("/environment/clouds",true)->getChild("layer", i, true );
|
SGPropertyNode_ptr layerNode = fgGetNode("/environment/clouds",true)->getChild("layer", i, true );
|
||||||
|
@ -176,15 +184,10 @@ FGEnvironmentMgr::bind ()
|
||||||
&SGSky::get_3dCloudVisRange,
|
&SGSky::get_3dCloudVisRange,
|
||||||
&SGSky::set_3dCloudVisRange);
|
&SGSky::set_3dCloudVisRange);
|
||||||
|
|
||||||
_tiedProperties.Tie("precipitation-enable", &sgEnviro,
|
// _tiedProperties.Tie("lightning-enable", &sgEnviro,
|
||||||
&SGEnviro::get_precipitation_enable_state,
|
// &SGEnviro::get_lightning_enable_state,
|
||||||
&SGEnviro::set_precipitation_enable_state);
|
// &SGEnviro::set_lightning_enable_state);
|
||||||
|
|
||||||
_tiedProperties.Tie("lightning-enable", &sgEnviro,
|
|
||||||
&SGEnviro::get_lightning_enable_state,
|
|
||||||
&SGEnviro::set_lightning_enable_state);
|
|
||||||
|
|
||||||
sgEnviro.config(fgGetNode("/sim/rendering/precipitation"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -200,7 +203,7 @@ FGEnvironmentMgr::update (double dt)
|
||||||
{
|
{
|
||||||
SGSubsystemGroup::update(dt);
|
SGSubsystemGroup::update(dt);
|
||||||
|
|
||||||
_environment->set_elevation_ft( _altitudeNode->getDoubleValue() );
|
_environment->set_elevation_ft( _altitude_n->getDoubleValue() );
|
||||||
|
|
||||||
simgear::Particles::setWindFrom( _environment->get_wind_from_heading_deg(),
|
simgear::Particles::setWindFrom( _environment->get_wind_from_heading_deg(),
|
||||||
_environment->get_wind_speed_kt() );
|
_environment->get_wind_speed_kt() );
|
||||||
|
@ -209,6 +212,14 @@ FGEnvironmentMgr::update (double dt)
|
||||||
fgClouds->set_update_event( fgClouds->get_update_event()+1 );
|
fgClouds->set_update_event( fgClouds->get_update_event()+1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fgSetDouble( "/environment/gravitational-acceleration-mps2",
|
||||||
|
Environment::Gravity::instance()->getGravity(SGGeod::fromDegFt(
|
||||||
|
_longitude_n->getDoubleValue(),
|
||||||
|
_latitude_n->getDoubleValue(),
|
||||||
|
_altitude_n->getDoubleValue()
|
||||||
|
)));
|
||||||
|
|
||||||
_positionTimeToLive -= dt;
|
_positionTimeToLive -= dt;
|
||||||
if( _positionTimeToLive <= 0.0 )
|
if( _positionTimeToLive <= 0.0 )
|
||||||
{
|
{
|
||||||
|
|
|
@ -95,7 +95,7 @@ private:
|
||||||
FGEnvironment * _environment; // always the same, for now
|
FGEnvironment * _environment; // always the same, for now
|
||||||
FGClouds *fgClouds;
|
FGClouds *fgClouds;
|
||||||
bool _cloudLayersDirty;
|
bool _cloudLayersDirty;
|
||||||
SGPropertyNode_ptr _altitudeNode;
|
SGPropertyNode_ptr _altitude_n;
|
||||||
SGPropertyNode_ptr _longitude_n;
|
SGPropertyNode_ptr _longitude_n;
|
||||||
SGPropertyNode_ptr _latitude_n;
|
SGPropertyNode_ptr _latitude_n;
|
||||||
double _positionTimeToLive;
|
double _positionTimeToLive;
|
||||||
|
|
|
@ -30,7 +30,7 @@
|
||||||
#include <simgear/constants.h>
|
#include <simgear/constants.h>
|
||||||
#include <simgear/sound/soundmgr_openal.hxx>
|
#include <simgear/sound/soundmgr_openal.hxx>
|
||||||
#include <simgear/scene/sky/sky.hxx>
|
#include <simgear/scene/sky/sky.hxx>
|
||||||
#include <simgear/environment/visual_enviro.hxx>
|
//#include <simgear/environment/visual_enviro.hxx>
|
||||||
#include <simgear/scene/sky/cloudfield.hxx>
|
#include <simgear/scene/sky/cloudfield.hxx>
|
||||||
#include <simgear/scene/sky/newcloud.hxx>
|
#include <simgear/scene/sky/newcloud.hxx>
|
||||||
#include <simgear/structure/commands.hxx>
|
#include <simgear/structure/commands.hxx>
|
||||||
|
@ -45,9 +45,14 @@
|
||||||
|
|
||||||
extern SGSky *thesky;
|
extern SGSky *thesky;
|
||||||
|
|
||||||
|
static bool do_delete_3Dcloud (const SGPropertyNode *arg);
|
||||||
|
static bool do_move_3Dcloud (const SGPropertyNode *arg);
|
||||||
|
static bool do_add_3Dcloud (const SGPropertyNode *arg);
|
||||||
|
|
||||||
FGClouds::FGClouds() :
|
FGClouds::FGClouds() :
|
||||||
|
#if 0
|
||||||
snd_lightning(0),
|
snd_lightning(0),
|
||||||
|
#endif
|
||||||
clouds_3d_enabled(false),
|
clouds_3d_enabled(false),
|
||||||
index(0)
|
index(0)
|
||||||
{
|
{
|
||||||
|
@ -68,6 +73,7 @@ void FGClouds::set_update_event(int count) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void FGClouds::Init(void) {
|
void FGClouds::Init(void) {
|
||||||
|
#if 0
|
||||||
if( snd_lightning == NULL ) {
|
if( snd_lightning == NULL ) {
|
||||||
snd_lightning = new SGSoundSample("Sounds/thunder.wav", SGPath());
|
snd_lightning = new SGSoundSample("Sounds/thunder.wav", SGPath());
|
||||||
snd_lightning->set_max_dist(7000.0f);
|
snd_lightning->set_max_dist(7000.0f);
|
||||||
|
@ -75,8 +81,8 @@ void FGClouds::Init(void) {
|
||||||
SGSoundMgr *smgr = globals->get_soundmgr();
|
SGSoundMgr *smgr = globals->get_soundmgr();
|
||||||
SGSampleGroup *sgr = smgr->find("weather", true);
|
SGSampleGroup *sgr = smgr->find("weather", true);
|
||||||
sgr->add( snd_lightning, "thunder" );
|
sgr->add( snd_lightning, "thunder" );
|
||||||
sgEnviro.set_sampleGroup( sgr );
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
globals->get_commands()->addCommand("add-cloud", do_add_3Dcloud);
|
globals->get_commands()->addCommand("add-cloud", do_add_3Dcloud);
|
||||||
globals->get_commands()->addCommand("del-cloud", do_delete_3Dcloud);
|
globals->get_commands()->addCommand("del-cloud", do_delete_3Dcloud);
|
||||||
|
|
|
@ -45,7 +45,9 @@ private:
|
||||||
void buildCloudLayers(void);
|
void buildCloudLayers(void);
|
||||||
|
|
||||||
int update_event;
|
int update_event;
|
||||||
|
#if 0
|
||||||
SGSoundSample *snd_lightning;
|
SGSoundSample *snd_lightning;
|
||||||
|
#endif
|
||||||
bool clouds_3d_enabled;
|
bool clouds_3d_enabled;
|
||||||
int index;
|
int index;
|
||||||
|
|
||||||
|
@ -62,9 +64,5 @@ public:
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static bool do_delete_3Dcloud (const SGPropertyNode *arg);
|
|
||||||
static bool do_move_3Dcloud (const SGPropertyNode *arg);
|
|
||||||
static bool do_add_3Dcloud (const SGPropertyNode *arg);
|
|
||||||
|
|
||||||
#endif // _FGCLOUDS_HXX
|
#endif // _FGCLOUDS_HXX
|
||||||
|
|
||||||
|
|
89
src/Environment/gravity.cxx
Normal file
89
src/Environment/gravity.cxx
Normal file
|
@ -0,0 +1,89 @@
|
||||||
|
// gravity.cxx -- interface for earth gravitational model
|
||||||
|
//
|
||||||
|
// Written by Torsten Dreyer, June 2011
|
||||||
|
//
|
||||||
|
// Copyright (C) 2011 Torsten Dreyer - torsten (at) t3r _dot_ de
|
||||||
|
//
|
||||||
|
// 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 "gravity.hxx"
|
||||||
|
|
||||||
|
#include <simgear/structure/exception.hxx>
|
||||||
|
|
||||||
|
namespace Environment {
|
||||||
|
|
||||||
|
/*
|
||||||
|
http://de.wikipedia.org/wiki/Normalschwereformel
|
||||||
|
*/
|
||||||
|
class Somigliana : public Gravity {
|
||||||
|
public:
|
||||||
|
Somigliana();
|
||||||
|
virtual ~Somigliana();
|
||||||
|
virtual double getGravity( const SGGeod & position ) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
Somigliana::Somigliana()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Somigliana::~Somigliana()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
double Somigliana::getGravity( const SGGeod & position ) const
|
||||||
|
{
|
||||||
|
// Geodetic Reference System 1980 parameter
|
||||||
|
#define A 6378137.0 // equatorial radius of earth
|
||||||
|
#define B 6356752.3141 // semiminor axis
|
||||||
|
#define AGA (A*9.7803267715) // A times normal gravity at equator
|
||||||
|
#define BGB (B*9.8321863685) // B times normal gravity at pole
|
||||||
|
// forumla of Somigliana
|
||||||
|
double cosphi = ::cos(position.getLatitudeRad());
|
||||||
|
double cos2phi = cosphi*cosphi;
|
||||||
|
double sinphi = ::sin(position.getLatitudeRad());
|
||||||
|
double sin2phi = sinphi*sinphi;
|
||||||
|
double g0 = (AGA * cos2phi + BGB * sin2phi) / sqrt( A*A*cos2phi+B*B*sin2phi );
|
||||||
|
|
||||||
|
static const double k1 = 3.15704e-7;
|
||||||
|
static const double k2 = 2.10269e-9;
|
||||||
|
static const double k3 = 7.37452e-14;
|
||||||
|
|
||||||
|
double h = position.getElevationM();
|
||||||
|
|
||||||
|
return g0*(1-(k1-k2*sin2phi)*h+k3*h*h);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Somigliana _somigliana;
|
||||||
|
|
||||||
|
/* --------------------- Gravity implementation --------------------- */
|
||||||
|
Gravity * Gravity::_instance = NULL;
|
||||||
|
|
||||||
|
Gravity::~Gravity()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//double Gravity::getGravity( const SGGeoc & position ) = 0;
|
||||||
|
|
||||||
|
const Gravity * Gravity::instance()
|
||||||
|
{
|
||||||
|
if( _instance == NULL )
|
||||||
|
_instance = &_somigliana;
|
||||||
|
|
||||||
|
return _instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
43
src/Environment/gravity.hxx
Normal file
43
src/Environment/gravity.hxx
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
// gravity.hxx -- interface for earth gravitational model
|
||||||
|
//
|
||||||
|
// Written by Torsten Dreyer, June 2011
|
||||||
|
//
|
||||||
|
// Copyright (C) 2011 Torsten Dreyer - torsten (at) t3r _dot_ de
|
||||||
|
//
|
||||||
|
// 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 __GRAVITY_HXX
|
||||||
|
#define __GRAVITY_HXX
|
||||||
|
|
||||||
|
#include <simgear/math/SGMath.hxx>
|
||||||
|
|
||||||
|
namespace Environment {
|
||||||
|
|
||||||
|
class Gravity
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual ~Gravity();
|
||||||
|
virtual double getGravity( const SGGeod & position ) const = 0;
|
||||||
|
|
||||||
|
const static Gravity * instance();
|
||||||
|
|
||||||
|
private:
|
||||||
|
static Gravity * _instance;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
#endif // __GRAVITY_HXX
|
|
@ -36,7 +36,6 @@
|
||||||
#include <simgear/math/SGMath.hxx>
|
#include <simgear/math/SGMath.hxx>
|
||||||
#include <simgear/scene/sky/sky.hxx>
|
#include <simgear/scene/sky/sky.hxx>
|
||||||
#include <simgear/scene/sky/cloud.hxx>
|
#include <simgear/scene/sky/cloud.hxx>
|
||||||
#include <simgear/environment/visual_enviro.hxx>
|
|
||||||
|
|
||||||
#include <Main/fg_props.hxx>
|
#include <Main/fg_props.hxx>
|
||||||
#include <Main/globals.hxx>
|
#include <Main/globals.hxx>
|
||||||
|
@ -93,6 +92,19 @@ void FGPrecipitationMgr::init()
|
||||||
fgGetNode("environment/params/precipitation-level-ft", true);
|
fgGetNode("environment/params/precipitation-level-ft", true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FGPrecipitationMgr::bind ()
|
||||||
|
{
|
||||||
|
_tiedProperties.setRoot( fgGetNode("/sim/rendering", true ) );
|
||||||
|
_tiedProperties.Tie("precipitation-enable", precipitation.get(),
|
||||||
|
&SGPrecipitation::getEnabled,
|
||||||
|
&SGPrecipitation::setEnabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FGPrecipitationMgr::unbind ()
|
||||||
|
{
|
||||||
|
_tiedProperties.Untie();
|
||||||
|
}
|
||||||
|
|
||||||
void FGPrecipitationMgr::setPrecipitationLevel(double a)
|
void FGPrecipitationMgr::setPrecipitationLevel(double a)
|
||||||
{
|
{
|
||||||
fgSetDouble("environment/params/precipitation-level-ft",a);
|
fgSetDouble("environment/params/precipitation-level-ft",a);
|
||||||
|
@ -206,7 +218,7 @@ void FGPrecipitationMgr::update(double dt)
|
||||||
setPrecipitationLevel(altitudeCloudLayer);
|
setPrecipitationLevel(altitudeCloudLayer);
|
||||||
|
|
||||||
// Does the user enable the precipitation ?
|
// Does the user enable the precipitation ?
|
||||||
if (!sgEnviro.get_precipitation_enable_state()) {
|
if (!precipitation->getEnabled() ) {
|
||||||
// Disable precipitations
|
// Disable precipitations
|
||||||
precipitation->setRainIntensity(0);
|
precipitation->setRainIntensity(0);
|
||||||
precipitation->setSnowIntensity(0);
|
precipitation->setSnowIntensity(0);
|
||||||
|
|
|
@ -31,7 +31,7 @@
|
||||||
|
|
||||||
#include <simgear/structure/subsystem_mgr.hxx>
|
#include <simgear/structure/subsystem_mgr.hxx>
|
||||||
#include <simgear/environment/precipitation.hxx>
|
#include <simgear/environment/precipitation.hxx>
|
||||||
|
#include <simgear/props/tiedpropertylist.hxx>
|
||||||
|
|
||||||
class FGPrecipitationMgr : public SGSubsystem
|
class FGPrecipitationMgr : public SGSubsystem
|
||||||
{
|
{
|
||||||
|
@ -40,12 +40,15 @@ private:
|
||||||
osg::ref_ptr<osg::MatrixTransform> transform;
|
osg::ref_ptr<osg::MatrixTransform> transform;
|
||||||
osg::ref_ptr<SGPrecipitation> precipitation;
|
osg::ref_ptr<SGPrecipitation> precipitation;
|
||||||
float getPrecipitationAtAltitudeMax(void);
|
float getPrecipitationAtAltitudeMax(void);
|
||||||
|
simgear::TiedPropertyList _tiedProperties;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
FGPrecipitationMgr();
|
FGPrecipitationMgr();
|
||||||
virtual ~FGPrecipitationMgr();
|
virtual ~FGPrecipitationMgr();
|
||||||
|
|
||||||
// SGSubsystem methods
|
// SGSubsystem methods
|
||||||
|
virtual void bind ();
|
||||||
|
virtual void unbind ();
|
||||||
virtual void init ();
|
virtual void init ();
|
||||||
virtual void update (double dt);
|
virtual void update (double dt);
|
||||||
|
|
||||||
|
|
|
@ -114,12 +114,38 @@ private:
|
||||||
FGJSBsim* mInterface;
|
FGJSBsim* mInterface;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// FG uses a squared normalized magnitude for turbulence
|
||||||
|
// this lookup table maps fg's severity levels
|
||||||
|
// none(0), light(1/3), moderate(2/3) and severe(3/3)
|
||||||
|
// to the POE table indexes 0, 3, 4 and 7
|
||||||
|
class FGTurbulenceSeverityTable : public FGTable {
|
||||||
|
public:
|
||||||
|
FGTurbulenceSeverityTable() : FGTable(4) {
|
||||||
|
*this << (0.0/9.0) << 0.0;
|
||||||
|
*this << (1.0/9.0) << 3.0;
|
||||||
|
*this << (4.0/9.0) << 4.0;
|
||||||
|
*this << (9.0/9.0) << 7.0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
std::map<std::string,int> FGJSBsim::TURBULENCE_TYPE_NAMES;
|
||||||
|
|
||||||
|
static FGTurbulenceSeverityTable TurbulenceSeverityTable;
|
||||||
|
|
||||||
FGJSBsim::FGJSBsim( double dt )
|
FGJSBsim::FGJSBsim( double dt )
|
||||||
: FGInterface(dt), got_wire(false)
|
: FGInterface(dt), got_wire(false)
|
||||||
{
|
{
|
||||||
bool result;
|
bool result;
|
||||||
|
if( TURBULENCE_TYPE_NAMES.empty() ) {
|
||||||
|
TURBULENCE_TYPE_NAMES["ttNone"] = FGAtmosphere::ttNone;
|
||||||
|
TURBULENCE_TYPE_NAMES["ttStandard"] = FGAtmosphere::ttStandard;
|
||||||
|
TURBULENCE_TYPE_NAMES["ttBerndt"] = FGAtmosphere::ttBerndt;
|
||||||
|
TURBULENCE_TYPE_NAMES["ttCulp"] = FGAtmosphere::ttCulp;
|
||||||
|
TURBULENCE_TYPE_NAMES["ttMilspec"] = FGAtmosphere::ttMilspec;
|
||||||
|
TURBULENCE_TYPE_NAMES["ttTustin"] = FGAtmosphere::ttTustin;
|
||||||
|
}
|
||||||
|
|
||||||
// Set up the debugging level
|
// Set up the debugging level
|
||||||
// FIXME: this will not respond to
|
// FIXME: this will not respond to
|
||||||
// runtime changes
|
// runtime changes
|
||||||
|
@ -282,8 +308,10 @@ FGJSBsim::FGJSBsim( double dt )
|
||||||
temperature = fgGetNode("/environment/temperature-degc",true);
|
temperature = fgGetNode("/environment/temperature-degc",true);
|
||||||
pressure = fgGetNode("/environment/pressure-inhg",true);
|
pressure = fgGetNode("/environment/pressure-inhg",true);
|
||||||
density = fgGetNode("/environment/density-slugft3",true);
|
density = fgGetNode("/environment/density-slugft3",true);
|
||||||
|
ground_wind = fgGetNode("/environment/config/boundary/entry[0]/wind-speed-kt",true);
|
||||||
turbulence_gain = fgGetNode("/environment/turbulence/magnitude-norm",true);
|
turbulence_gain = fgGetNode("/environment/turbulence/magnitude-norm",true);
|
||||||
turbulence_rate = fgGetNode("/environment/turbulence/rate-hz",true);
|
turbulence_rate = fgGetNode("/environment/turbulence/rate-hz",true);
|
||||||
|
turbulence_model = fgGetNode("/environment/params/jsbsim-turbulence-model",true);
|
||||||
|
|
||||||
wind_from_north= fgGetNode("/environment/wind-from-north-fps",true);
|
wind_from_north= fgGetNode("/environment/wind-from-north-fps",true);
|
||||||
wind_from_east = fgGetNode("/environment/wind-from-east-fps" ,true);
|
wind_from_east = fgGetNode("/environment/wind-from-east-fps" ,true);
|
||||||
|
@ -331,17 +359,19 @@ void FGJSBsim::init()
|
||||||
9.0/5.0*(temperature->getDoubleValue()+273.15) );
|
9.0/5.0*(temperature->getDoubleValue()+273.15) );
|
||||||
Atmosphere->SetExPressure(pressure->getDoubleValue()*70.726566);
|
Atmosphere->SetExPressure(pressure->getDoubleValue()*70.726566);
|
||||||
Atmosphere->SetExDensity(density->getDoubleValue());
|
Atmosphere->SetExDensity(density->getDoubleValue());
|
||||||
Atmosphere->SetTurbType(FGAtmosphere::ttCulp);
|
// initialize to no turbulence, these values get set in the update loop
|
||||||
Atmosphere->SetTurbGain(turbulence_gain->getDoubleValue());
|
Atmosphere->SetTurbType(FGAtmosphere::ttNone);
|
||||||
Atmosphere->SetTurbRate(turbulence_rate->getDoubleValue());
|
Atmosphere->SetTurbGain(0.0);
|
||||||
|
Atmosphere->SetTurbRate(0.0);
|
||||||
|
Atmosphere->SetWindspeed20ft(0.0);
|
||||||
|
Atmosphere->SetProbabilityOfExceedence(0.0);
|
||||||
} else {
|
} else {
|
||||||
Atmosphere->UseInternal();
|
Atmosphere->UseInternal();
|
||||||
}
|
}
|
||||||
|
|
||||||
fgic->SetVNorthFpsIC( -wind_from_north->getDoubleValue() );
|
fgic->SetWindNEDFpsIC( -wind_from_north->getDoubleValue(),
|
||||||
fgic->SetVEastFpsIC( -wind_from_east->getDoubleValue() );
|
-wind_from_east->getDoubleValue(),
|
||||||
fgic->SetVDownFpsIC( -wind_from_down->getDoubleValue() );
|
-wind_from_down->getDoubleValue() );
|
||||||
|
|
||||||
//Atmosphere->SetExTemperature(get_Static_temperature());
|
//Atmosphere->SetExTemperature(get_Static_temperature());
|
||||||
//Atmosphere->SetExPressure(get_Static_pressure());
|
//Atmosphere->SetExPressure(get_Static_pressure());
|
||||||
|
@ -351,34 +381,32 @@ void FGJSBsim::init()
|
||||||
<< ", " << fdmex->GetAtmosphere()->GetDensity() );
|
<< ", " << fdmex->GetAtmosphere()->GetDensity() );
|
||||||
|
|
||||||
// deprecate egt_degf for egt-degf to have consistent naming
|
// deprecate egt_degf for egt-degf to have consistent naming
|
||||||
// TODO: raise log-level to ALERT in summer 2010,
|
// TODO: remove this by end of 2011
|
||||||
// remove alias in fall 2010,
|
|
||||||
// remove this code in winter 2010
|
|
||||||
for (unsigned int i=0; i < Propulsion->GetNumEngines(); i++) {
|
for (unsigned int i=0; i < Propulsion->GetNumEngines(); i++) {
|
||||||
SGPropertyNode * node = fgGetNode("engines/engine", i, true);
|
SGPropertyNode * node = fgGetNode("engines/engine", i, true);
|
||||||
SGPropertyNode * egtn = node->getNode( "egt_degf" );
|
SGPropertyNode * egtn = node->getNode( "egt_degf" );
|
||||||
if( egtn != NULL ) {
|
if( egtn != NULL ) {
|
||||||
SG_LOG(SG_FLIGHT,SG_WARN,
|
SG_LOG(SG_FLIGHT,SG_ALERT,
|
||||||
"Aircraft uses deprecated node egt_degf. Please upgrade to egt-degf");
|
"Aircraft uses deprecated node egt_degf. Please upgrade to egt-degf");
|
||||||
node->getNode("egt-degf", true)->alias( egtn );
|
node->getNode("egt-degf", true)->alias( egtn );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// end of egt_degf deprecation patch
|
// end of egt_degf deprecation patch
|
||||||
|
|
||||||
if (fgGetBool("/sim/presets/running")) {
|
|
||||||
for (unsigned int i=0; i < Propulsion->GetNumEngines(); i++) {
|
|
||||||
SGPropertyNode * node = fgGetNode("engines/engine", i, true);
|
|
||||||
node->setBoolValue("running", true);
|
|
||||||
Propulsion->GetEngine(i)->SetRunning(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
FCS->SetDfPos( ofNorm, globals->get_controls()->get_flaps() );
|
FCS->SetDfPos( ofNorm, globals->get_controls()->get_flaps() );
|
||||||
|
|
||||||
common_init();
|
common_init();
|
||||||
|
|
||||||
copy_to_JSBsim();
|
copy_to_JSBsim();
|
||||||
fdmex->RunIC(); //loop JSBSim once w/o integrating
|
fdmex->RunIC(); //loop JSBSim once w/o integrating
|
||||||
|
if (fgGetBool("/sim/presets/running")) {
|
||||||
|
Propulsion->InitRunning(-1);
|
||||||
|
for (unsigned int i = 0; i < Propulsion->GetNumEngines(); i++) {
|
||||||
|
FGPiston* eng = (FGPiston*)Propulsion->GetEngine(i);
|
||||||
|
globals->get_controls()->set_magnetos(i, eng->GetMagnetos());
|
||||||
|
globals->get_controls()->set_mixture(i, FCS->GetMixtureCmd(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
copy_from_JSBsim(); //update the bus
|
copy_from_JSBsim(); //update the bus
|
||||||
|
|
||||||
SG_LOG( SG_FLIGHT, SG_INFO, " Initialized JSBSim with:" );
|
SG_LOG( SG_FLIGHT, SG_INFO, " Initialized JSBSim with:" );
|
||||||
|
@ -590,7 +618,6 @@ void FGJSBsim::resume()
|
||||||
|
|
||||||
bool FGJSBsim::copy_to_JSBsim()
|
bool FGJSBsim::copy_to_JSBsim()
|
||||||
{
|
{
|
||||||
double tmp;
|
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
// copy control positions into the JSBsim structure
|
// copy control positions into the JSBsim structure
|
||||||
|
@ -686,11 +713,31 @@ bool FGJSBsim::copy_to_JSBsim()
|
||||||
Atmosphere->SetExPressure(pressure->getDoubleValue()*70.726566);
|
Atmosphere->SetExPressure(pressure->getDoubleValue()*70.726566);
|
||||||
Atmosphere->SetExDensity(density->getDoubleValue());
|
Atmosphere->SetExDensity(density->getDoubleValue());
|
||||||
|
|
||||||
tmp = turbulence_gain->getDoubleValue();
|
Atmosphere->SetTurbType((FGAtmosphere::tType)TURBULENCE_TYPE_NAMES[turbulence_model->getStringValue()]);
|
||||||
//Atmosphere->SetTurbGain(tmp * tmp * 100.0);
|
switch( Atmosphere->GetTurbType() ) {
|
||||||
|
case FGAtmosphere::ttStandard:
|
||||||
|
case FGAtmosphere::ttCulp:
|
||||||
|
case FGAtmosphere::ttBerndt: {
|
||||||
|
double tmp = turbulence_gain->getDoubleValue();
|
||||||
|
Atmosphere->SetTurbGain(tmp * tmp * 100.0);
|
||||||
|
Atmosphere->SetTurbRate(turbulence_rate->getDoubleValue());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case FGAtmosphere::ttMilspec:
|
||||||
|
case FGAtmosphere::ttTustin: {
|
||||||
|
// milspec turbulence: 3=light, 4=moderate, 6=severe turbulence
|
||||||
|
// turbulence_gain normalized: 0: none, 1/3: light, 2/3: moderate, 3/3: severe
|
||||||
|
double tmp = turbulence_gain->getDoubleValue();
|
||||||
|
Atmosphere->SetProbabilityOfExceedence(
|
||||||
|
SGMiscd::roundToInt(TurbulenceSeverityTable.GetValue( tmp ) )
|
||||||
|
);
|
||||||
|
Atmosphere->SetWindspeed20ft(ground_wind->getDoubleValue());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
tmp = turbulence_rate->getDoubleValue();
|
default:
|
||||||
//Atmosphere->SetTurbRate(tmp);
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
Atmosphere->SetWindNED( -wind_from_north->getDoubleValue(),
|
Atmosphere->SetWindNED( -wind_from_north->getDoubleValue(),
|
||||||
-wind_from_east->getDoubleValue(),
|
-wind_from_east->getDoubleValue(),
|
||||||
|
@ -1235,7 +1282,7 @@ void FGJSBsim::do_trim(void)
|
||||||
{
|
{
|
||||||
fgtrim = new FGTrim(fdmex,tGround);
|
fgtrim = new FGTrim(fdmex,tGround);
|
||||||
} else {
|
} else {
|
||||||
fgtrim = new FGTrim(fdmex,tLongitudinal);
|
fgtrim = new FGTrim(fdmex,tFull);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !fgtrim->DoTrim() ) {
|
if ( !fgtrim->DoTrim() ) {
|
||||||
|
@ -1249,7 +1296,7 @@ void FGJSBsim::do_trim(void)
|
||||||
pitch_trim->setDoubleValue( FCS->GetPitchTrimCmd() );
|
pitch_trim->setDoubleValue( FCS->GetPitchTrimCmd() );
|
||||||
throttle_trim->setDoubleValue( FCS->GetThrottleCmd(0) );
|
throttle_trim->setDoubleValue( FCS->GetThrottleCmd(0) );
|
||||||
aileron_trim->setDoubleValue( FCS->GetDaCmd() );
|
aileron_trim->setDoubleValue( FCS->GetDaCmd() );
|
||||||
rudder_trim->setDoubleValue( FCS->GetDrCmd() );
|
rudder_trim->setDoubleValue( -FCS->GetDrCmd() );
|
||||||
|
|
||||||
globals->get_controls()->set_elevator_trim(FCS->GetPitchTrimCmd());
|
globals->get_controls()->set_elevator_trim(FCS->GetPitchTrimCmd());
|
||||||
globals->get_controls()->set_elevator(FCS->GetDeCmd());
|
globals->get_controls()->set_elevator(FCS->GetDeCmd());
|
||||||
|
@ -1257,7 +1304,7 @@ void FGJSBsim::do_trim(void)
|
||||||
globals->get_controls()->set_throttle(i, FCS->GetThrottleCmd(i));
|
globals->get_controls()->set_throttle(i, FCS->GetThrottleCmd(i));
|
||||||
|
|
||||||
globals->get_controls()->set_aileron(FCS->GetDaCmd());
|
globals->get_controls()->set_aileron(FCS->GetDaCmd());
|
||||||
globals->get_controls()->set_rudder( FCS->GetDrCmd());
|
globals->get_controls()->set_rudder( -FCS->GetDrCmd());
|
||||||
|
|
||||||
SG_LOG( SG_FLIGHT, SG_INFO, " Trim complete" );
|
SG_LOG( SG_FLIGHT, SG_INFO, " Trim complete" );
|
||||||
}
|
}
|
||||||
|
|
|
@ -271,8 +271,10 @@ private:
|
||||||
SGPropertyNode_ptr temperature;
|
SGPropertyNode_ptr temperature;
|
||||||
SGPropertyNode_ptr pressure;
|
SGPropertyNode_ptr pressure;
|
||||||
SGPropertyNode_ptr density;
|
SGPropertyNode_ptr density;
|
||||||
|
SGPropertyNode_ptr ground_wind;
|
||||||
SGPropertyNode_ptr turbulence_gain;
|
SGPropertyNode_ptr turbulence_gain;
|
||||||
SGPropertyNode_ptr turbulence_rate;
|
SGPropertyNode_ptr turbulence_rate;
|
||||||
|
SGPropertyNode_ptr turbulence_model;
|
||||||
|
|
||||||
SGPropertyNode_ptr wind_from_north;
|
SGPropertyNode_ptr wind_from_north;
|
||||||
SGPropertyNode_ptr wind_from_east;
|
SGPropertyNode_ptr wind_from_east;
|
||||||
|
@ -280,6 +282,8 @@ private:
|
||||||
|
|
||||||
SGPropertyNode_ptr slaved;
|
SGPropertyNode_ptr slaved;
|
||||||
|
|
||||||
|
static std::map<std::string,int> TURBULENCE_TYPE_NAMES;
|
||||||
|
|
||||||
double last_hook_tip[3];
|
double last_hook_tip[3];
|
||||||
double last_hook_root[3];
|
double last_hook_root[3];
|
||||||
JSBSim::FGColumnVector3 hook_root_struct;
|
JSBSim::FGColumnVector3 hook_root_struct;
|
||||||
|
|
|
@ -61,7 +61,7 @@ using namespace std;
|
||||||
|
|
||||||
namespace JSBSim {
|
namespace JSBSim {
|
||||||
|
|
||||||
static const char *IdSrc = "$Id: FGInitialCondition.cpp,v 1.59 2011/04/03 13:18:51 bcoconni Exp $";
|
static const char *IdSrc = "$Id: FGInitialCondition.cpp,v 1.61 2011/05/20 00:47:03 bcoconni Exp $";
|
||||||
static const char *IdHdr = ID_INITIALCONDITION;
|
static const char *IdHdr = ID_INITIALCONDITION;
|
||||||
|
|
||||||
//******************************************************************************
|
//******************************************************************************
|
||||||
|
@ -112,7 +112,7 @@ void FGInitialCondition::ResetIC(double u0, double v0, double w0,
|
||||||
FGQuaternion Quat(phi, theta, psi);
|
FGQuaternion Quat(phi, theta, psi);
|
||||||
Quat.Normalize();
|
Quat.Normalize();
|
||||||
Tl2b = Quat.GetT();
|
Tl2b = Quat.GetT();
|
||||||
Tb2l = Quat.GetTInv();
|
Tb2l = Tl2b.Transposed();
|
||||||
|
|
||||||
vUVW_NED = Tb2l * FGColumnVector3(u0, v0, w0);
|
vUVW_NED = Tb2l * FGColumnVector3(u0, v0, w0);
|
||||||
vt = vUVW_NED.Magnitude();
|
vt = vUVW_NED.Magnitude();
|
||||||
|
@ -322,20 +322,18 @@ void FGInitialCondition::SetClimbRateFpsIC(double hdot)
|
||||||
|
|
||||||
FGColumnVector3 _vt_NED = Tb2l * Tw2b * FGColumnVector3(vt, 0., 0.);
|
FGColumnVector3 _vt_NED = Tb2l * Tw2b * FGColumnVector3(vt, 0., 0.);
|
||||||
FGColumnVector3 _WIND_NED = _vt_NED - vUVW_NED;
|
FGColumnVector3 _WIND_NED = _vt_NED - vUVW_NED;
|
||||||
double hdot0 = _vt_NED(eW);
|
double hdot0 = -_vt_NED(eW);
|
||||||
|
|
||||||
if (fabs(hdot0) < vt) {
|
if (fabs(hdot0) < vt) {
|
||||||
double scale = sqrt((vt*vt-hdot*hdot)/(vt*vt-hdot0*hdot0));
|
double scale = sqrt((vt*vt-hdot*hdot)/(vt*vt-hdot0*hdot0));
|
||||||
_vt_NED(eU) *= scale;
|
_vt_NED(eU) *= scale;
|
||||||
_vt_NED(eV) *= scale;
|
_vt_NED(eV) *= scale;
|
||||||
}
|
}
|
||||||
_vt_NED(eW) = hdot;
|
_vt_NED(eW) = -hdot;
|
||||||
vUVW_NED = _vt_NED - _WIND_NED;
|
vUVW_NED = _vt_NED - _WIND_NED;
|
||||||
|
|
||||||
// The AoA is not modified here but the function SetAlphaRadIC is updating the
|
// Updating the angles theta and beta to keep the true airspeed amplitude
|
||||||
// same angles than SetClimbRateFpsIC needs to update.
|
calcThetaBeta(alpha, _vt_NED);
|
||||||
// TODO : create a subroutine that only shares the relevant code.
|
|
||||||
SetAlphaRadIC(alpha);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//******************************************************************************
|
//******************************************************************************
|
||||||
|
@ -346,7 +344,16 @@ void FGInitialCondition::SetClimbRateFpsIC(double hdot)
|
||||||
void FGInitialCondition::SetAlphaRadIC(double alfa)
|
void FGInitialCondition::SetAlphaRadIC(double alfa)
|
||||||
{
|
{
|
||||||
FGColumnVector3 _vt_NED = Tb2l * Tw2b * FGColumnVector3(vt, 0., 0.);
|
FGColumnVector3 _vt_NED = Tb2l * Tw2b * FGColumnVector3(vt, 0., 0.);
|
||||||
|
calcThetaBeta(alfa, _vt_NED);
|
||||||
|
}
|
||||||
|
|
||||||
|
//******************************************************************************
|
||||||
|
// When the AoA is modified, we need to update the angles theta and beta to
|
||||||
|
// keep the true airspeed amplitude, the climb rate and the heading unchanged.
|
||||||
|
// Beta will be modified if the aircraft roll angle is not null.
|
||||||
|
|
||||||
|
void FGInitialCondition::calcThetaBeta(double alfa, const FGColumnVector3& _vt_NED)
|
||||||
|
{
|
||||||
double calpha = cos(alfa), salpha = sin(alfa);
|
double calpha = cos(alfa), salpha = sin(alfa);
|
||||||
double cpsi = cos(psi), spsi = sin(psi);
|
double cpsi = cos(psi), spsi = sin(psi);
|
||||||
double cphi = cos(phi), sphi = sin(phi);
|
double cphi = cos(phi), sphi = sin(phi);
|
||||||
|
@ -398,11 +405,11 @@ void FGInitialCondition::SetAlphaRadIC(double alfa)
|
||||||
Tl2b = Quat.GetT();
|
Tl2b = Quat.GetT();
|
||||||
Tb2l = Quat.GetTInv();
|
Tb2l = Quat.GetTInv();
|
||||||
|
|
||||||
FGColumnVector3 v2 = Talpha * Quat.GetT() * _vt_NED;
|
FGColumnVector3 v2 = Talpha * Tl2b * _vt_NED;
|
||||||
|
|
||||||
alpha = alfa;
|
alpha = alfa;
|
||||||
beta = atan2(v2(eV), v2(eU));
|
beta = atan2(v2(eV), v2(eU));
|
||||||
double cbeta=0.0, sbeta=0.0;
|
double cbeta=1.0, sbeta=0.0;
|
||||||
if (vt != 0.0) {
|
if (vt != 0.0) {
|
||||||
cbeta = v2(eU) / vt;
|
cbeta = v2(eU) / vt;
|
||||||
sbeta = v2(eV) / vt;
|
sbeta = v2(eV) / vt;
|
||||||
|
@ -687,6 +694,8 @@ void FGInitialCondition::SetAltitudeASLFtIC(double alt)
|
||||||
double ve0 = vt * sqrt(rho/rhoSL);
|
double ve0 = vt * sqrt(rho/rhoSL);
|
||||||
|
|
||||||
altitudeASL=alt;
|
altitudeASL=alt;
|
||||||
|
position.SetRadius(alt + sea_level_radius);
|
||||||
|
|
||||||
temperature = fdmex->GetAtmosphere()->GetTemperature(altitudeASL);
|
temperature = fdmex->GetAtmosphere()->GetTemperature(altitudeASL);
|
||||||
soundSpeed = sqrt(SHRatio*Reng*temperature);
|
soundSpeed = sqrt(SHRatio*Reng*temperature);
|
||||||
rho = fdmex->GetAtmosphere()->GetDensity(altitudeASL);
|
rho = fdmex->GetAtmosphere()->GetDensity(altitudeASL);
|
||||||
|
@ -703,8 +712,6 @@ void FGInitialCondition::SetAltitudeASLFtIC(double alt)
|
||||||
default: // Make the compiler stop complaining about missing enums
|
default: // Make the compiler stop complaining about missing enums
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
position.SetRadius(alt + sea_level_radius);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//******************************************************************************
|
//******************************************************************************
|
||||||
|
|
|
@ -54,7 +54,7 @@ INCLUDES
|
||||||
DEFINITIONS
|
DEFINITIONS
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
#define ID_INITIALCONDITION "$Id: FGInitialCondition.h,v 1.26 2011/01/16 16:10:59 bcoconni Exp $"
|
#define ID_INITIALCONDITION "$Id: FGInitialCondition.h,v 1.27 2011/05/20 00:47:03 bcoconni Exp $"
|
||||||
|
|
||||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
FORWARD DECLARATIONS
|
FORWARD DECLARATIONS
|
||||||
|
@ -213,7 +213,7 @@ CLASS DOCUMENTATION
|
||||||
@property ic/r-rad_sec (read/write) Yaw rate initial condition in radians/second
|
@property ic/r-rad_sec (read/write) Yaw rate initial condition in radians/second
|
||||||
|
|
||||||
@author Tony Peden
|
@author Tony Peden
|
||||||
@version "$Id: FGInitialCondition.h,v 1.26 2011/01/16 16:10:59 bcoconni Exp $"
|
@version "$Id: FGInitialCondition.h,v 1.27 2011/05/20 00:47:03 bcoconni Exp $"
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
@ -666,6 +666,7 @@ private:
|
||||||
double getMachFromVcas(double vcas);
|
double getMachFromVcas(double vcas);
|
||||||
double calcVcas(double Mach) const;
|
double calcVcas(double Mach) const;
|
||||||
void calcAeroAngles(const FGColumnVector3& _vt_BODY);
|
void calcAeroAngles(const FGColumnVector3& _vt_BODY);
|
||||||
|
void calcThetaBeta(double alfa, const FGColumnVector3& _vt_NED);
|
||||||
void bind(void);
|
void bind(void);
|
||||||
void Debug(int from);
|
void Debug(int from);
|
||||||
|
|
||||||
|
|
|
@ -179,6 +179,15 @@ FGInterface::common_init ()
|
||||||
double slr = SGGeodesy::SGGeodToSeaLevelRadius(geodetic_position_v);
|
double slr = SGGeodesy::SGGeodToSeaLevelRadius(geodetic_position_v);
|
||||||
_set_Sea_level_radius( slr * SG_METER_TO_FEET );
|
_set_Sea_level_radius( slr * SG_METER_TO_FEET );
|
||||||
|
|
||||||
|
// Set initial Euler angles
|
||||||
|
SG_LOG( SG_FLIGHT, SG_INFO, "...initializing Euler angles..." );
|
||||||
|
set_Euler_Angles( fgGetDouble("/sim/presets/roll-deg")
|
||||||
|
* SGD_DEGREES_TO_RADIANS,
|
||||||
|
fgGetDouble("/sim/presets/pitch-deg")
|
||||||
|
* SGD_DEGREES_TO_RADIANS,
|
||||||
|
fgGetDouble("/sim/presets/heading-deg")
|
||||||
|
* SGD_DEGREES_TO_RADIANS );
|
||||||
|
|
||||||
// Set initial velocities
|
// Set initial velocities
|
||||||
SG_LOG( SG_FLIGHT, SG_INFO, "...initializing velocities..." );
|
SG_LOG( SG_FLIGHT, SG_INFO, "...initializing velocities..." );
|
||||||
if ( !fgHasNode("/sim/presets/speed-set") ) {
|
if ( !fgHasNode("/sim/presets/speed-set") ) {
|
||||||
|
@ -207,14 +216,11 @@ FGInterface::common_init ()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set initial Euler angles
|
if ( fgHasNode("/sim/presets/glideslope-deg") )
|
||||||
SG_LOG( SG_FLIGHT, SG_INFO, "...initializing Euler angles..." );
|
set_Gamma_vert_rad( fgGetDouble("/sim/presets/glideslope-deg")
|
||||||
set_Euler_Angles( fgGetDouble("/sim/presets/roll-deg")
|
|
||||||
* SGD_DEGREES_TO_RADIANS,
|
|
||||||
fgGetDouble("/sim/presets/pitch-deg")
|
|
||||||
* SGD_DEGREES_TO_RADIANS,
|
|
||||||
fgGetDouble("/sim/presets/heading-deg")
|
|
||||||
* SGD_DEGREES_TO_RADIANS );
|
* SGD_DEGREES_TO_RADIANS );
|
||||||
|
else if ( fgHasNode( "/velocities/vertical-speed-fps") )
|
||||||
|
set_Climb_Rate( fgGetDouble("/velocities/vertical-speed-fps") );
|
||||||
|
|
||||||
SG_LOG( SG_FLIGHT, SG_INFO, "End common FDM init" );
|
SG_LOG( SG_FLIGHT, SG_INFO, "End common FDM init" );
|
||||||
}
|
}
|
||||||
|
@ -251,7 +257,7 @@ FGInterface::bind ()
|
||||||
false);
|
false);
|
||||||
fgSetArchivable("/position/altitude-ft");
|
fgSetArchivable("/position/altitude-ft");
|
||||||
fgTie("/position/altitude-agl-ft", this,
|
fgTie("/position/altitude-agl-ft", this,
|
||||||
&FGInterface::get_Altitude_AGL, &FGInterface::set_AltitudeAGL);
|
&FGInterface::get_Altitude_AGL, &FGInterface::set_AltitudeAGL, false);
|
||||||
fgSetArchivable("/position/ground-elev-ft");
|
fgSetArchivable("/position/ground-elev-ft");
|
||||||
fgTie("/position/ground-elev-ft", this,
|
fgTie("/position/ground-elev-ft", this,
|
||||||
&FGInterface::get_Runway_altitude); // read-only
|
&FGInterface::get_Runway_altitude); // read-only
|
||||||
|
@ -263,7 +269,7 @@ FGInterface::bind ()
|
||||||
fgSetArchivable("/position/sea-level-radius-ft");
|
fgSetArchivable("/position/sea-level-radius-ft");
|
||||||
fgTie("/position/sea-level-radius-ft", this,
|
fgTie("/position/sea-level-radius-ft", this,
|
||||||
&FGInterface::get_Sea_level_radius,
|
&FGInterface::get_Sea_level_radius,
|
||||||
&FGInterface::_set_Sea_level_radius);
|
&FGInterface::_set_Sea_level_radius, false);
|
||||||
|
|
||||||
// Orientation
|
// Orientation
|
||||||
fgTie("/orientation/roll-deg", this,
|
fgTie("/orientation/roll-deg", this,
|
||||||
|
@ -279,24 +285,27 @@ FGInterface::bind ()
|
||||||
&FGInterface::set_Psi_deg, false);
|
&FGInterface::set_Psi_deg, false);
|
||||||
fgSetArchivable("/orientation/heading-deg");
|
fgSetArchivable("/orientation/heading-deg");
|
||||||
fgTie("/orientation/track-deg", this,
|
fgTie("/orientation/track-deg", this,
|
||||||
&FGInterface::get_Track);
|
&FGInterface::get_Track); // read-only
|
||||||
|
|
||||||
// Body-axis "euler rates" (rotation speed, but in a funny
|
// Body-axis "euler rates" (rotation speed, but in a funny
|
||||||
// representation).
|
// representation).
|
||||||
fgTie("/orientation/roll-rate-degps", this,
|
fgTie("/orientation/roll-rate-degps", this,
|
||||||
&FGInterface::get_Phi_dot_degps, &FGInterface::set_Phi_dot_degps);
|
&FGInterface::get_Phi_dot_degps,
|
||||||
|
&FGInterface::set_Phi_dot_degps, false);
|
||||||
fgTie("/orientation/pitch-rate-degps", this,
|
fgTie("/orientation/pitch-rate-degps", this,
|
||||||
&FGInterface::get_Theta_dot_degps, &FGInterface::set_Theta_dot_degps);
|
&FGInterface::get_Theta_dot_degps,
|
||||||
|
&FGInterface::set_Theta_dot_degps, false);
|
||||||
fgTie("/orientation/yaw-rate-degps", this,
|
fgTie("/orientation/yaw-rate-degps", this,
|
||||||
&FGInterface::get_Psi_dot_degps, &FGInterface::set_Psi_dot_degps);
|
&FGInterface::get_Psi_dot_degps,
|
||||||
|
&FGInterface::set_Psi_dot_degps, false);
|
||||||
|
|
||||||
fgTie("/orientation/p-body", this, &FGInterface::get_P_body);
|
fgTie("/orientation/p-body", this, &FGInterface::get_P_body); // read-only
|
||||||
fgTie("/orientation/q-body", this, &FGInterface::get_Q_body);
|
fgTie("/orientation/q-body", this, &FGInterface::get_Q_body); // read-only
|
||||||
fgTie("/orientation/r-body", this, &FGInterface::get_R_body);
|
fgTie("/orientation/r-body", this, &FGInterface::get_R_body); // read-only
|
||||||
|
|
||||||
// Ground speed knots
|
// Ground speed knots
|
||||||
fgTie("/velocities/groundspeed-kt", this,
|
fgTie("/velocities/groundspeed-kt", this,
|
||||||
&FGInterface::get_V_ground_speed_kt);
|
&FGInterface::get_V_ground_speed_kt); // read-only
|
||||||
|
|
||||||
// Calibrated airspeed
|
// Calibrated airspeed
|
||||||
fgTie("/velocities/airspeed-kt", this,
|
fgTie("/velocities/airspeed-kt", this,
|
||||||
|
@ -305,7 +314,7 @@ FGInterface::bind ()
|
||||||
false);
|
false);
|
||||||
|
|
||||||
fgTie("/velocities/equivalent-kt", this,
|
fgTie("/velocities/equivalent-kt", this,
|
||||||
&FGInterface::get_V_equiv_kts);
|
&FGInterface::get_V_equiv_kts); // read-only
|
||||||
|
|
||||||
// Mach number
|
// Mach number
|
||||||
fgTie("/velocities/mach", this,
|
fgTie("/velocities/mach", this,
|
||||||
|
@ -338,11 +347,11 @@ FGInterface::bind ()
|
||||||
&FGInterface::get_V_down, &FGInterface::set_V_down, false);
|
&FGInterface::get_V_down, &FGInterface::set_V_down, false);
|
||||||
|
|
||||||
fgTie("/velocities/north-relground-fps", this,
|
fgTie("/velocities/north-relground-fps", this,
|
||||||
&FGInterface::get_V_north_rel_ground);
|
&FGInterface::get_V_north_rel_ground); // read-only
|
||||||
fgTie("/velocities/east-relground-fps", this,
|
fgTie("/velocities/east-relground-fps", this,
|
||||||
&FGInterface::get_V_east_rel_ground);
|
&FGInterface::get_V_east_rel_ground); // read-only
|
||||||
fgTie("/velocities/down-relground-fps", this,
|
fgTie("/velocities/down-relground-fps", this,
|
||||||
&FGInterface::get_V_down_rel_ground);
|
&FGInterface::get_V_down_rel_ground); // read-only
|
||||||
|
|
||||||
|
|
||||||
// Relative wind
|
// Relative wind
|
||||||
|
@ -367,36 +376,37 @@ FGInterface::bind ()
|
||||||
// Climb and slip (read-only)
|
// Climb and slip (read-only)
|
||||||
fgTie("/velocities/vertical-speed-fps", this,
|
fgTie("/velocities/vertical-speed-fps", this,
|
||||||
&FGInterface::get_Climb_Rate,
|
&FGInterface::get_Climb_Rate,
|
||||||
&FGInterface::set_Climb_Rate );
|
&FGInterface::set_Climb_Rate, false );
|
||||||
fgTie("/velocities/glideslope", this,
|
fgTie("/velocities/glideslope", this,
|
||||||
&FGInterface::get_Gamma_vert_rad,
|
&FGInterface::get_Gamma_vert_rad,
|
||||||
&FGInterface::set_Gamma_vert_rad );
|
&FGInterface::set_Gamma_vert_rad, false );
|
||||||
fgTie("/orientation/side-slip-rad", this,
|
fgTie("/orientation/side-slip-rad", this,
|
||||||
&FGInterface::get_Beta, &FGInterface::_set_Beta);
|
&FGInterface::get_Beta, &FGInterface::_set_Beta, false);
|
||||||
fgTie("/orientation/side-slip-deg", this,
|
fgTie("/orientation/side-slip-deg", this,
|
||||||
&FGInterface::get_Beta_deg); // read-only
|
&FGInterface::get_Beta_deg); // read-only
|
||||||
fgTie("/orientation/alpha-deg", this,
|
fgTie("/orientation/alpha-deg", this,
|
||||||
&FGInterface::get_Alpha_deg, &FGInterface::set_Alpha_deg); // read-only
|
&FGInterface::get_Alpha_deg, &FGInterface::set_Alpha_deg, false);
|
||||||
fgTie("/accelerations/nlf", this,
|
fgTie("/accelerations/nlf", this,
|
||||||
&FGInterface::get_Nlf); // read-only
|
&FGInterface::get_Nlf); // read-only
|
||||||
|
|
||||||
// NED accelerations
|
// NED accelerations
|
||||||
fgTie("/accelerations/ned/north-accel-fps_sec",
|
fgTie("/accelerations/ned/north-accel-fps_sec",
|
||||||
this, &FGInterface::get_V_dot_north);
|
this, &FGInterface::get_V_dot_north); // read-only
|
||||||
fgTie("/accelerations/ned/east-accel-fps_sec",
|
fgTie("/accelerations/ned/east-accel-fps_sec",
|
||||||
this, &FGInterface::get_V_dot_east);
|
this, &FGInterface::get_V_dot_east); // read-only
|
||||||
fgTie("/accelerations/ned/down-accel-fps_sec",
|
fgTie("/accelerations/ned/down-accel-fps_sec",
|
||||||
this, &FGInterface::get_V_dot_down);
|
this, &FGInterface::get_V_dot_down); // read-only
|
||||||
|
|
||||||
// Pilot accelerations
|
// Pilot accelerations
|
||||||
fgTie("/accelerations/pilot/x-accel-fps_sec",
|
fgTie("/accelerations/pilot/x-accel-fps_sec",
|
||||||
this, &FGInterface::get_A_X_pilot, &FGInterface::set_A_X_pilot);
|
this, &FGInterface::get_A_X_pilot, &FGInterface::set_A_X_pilot, false);
|
||||||
fgTie("/accelerations/pilot/y-accel-fps_sec",
|
fgTie("/accelerations/pilot/y-accel-fps_sec",
|
||||||
this, &FGInterface::get_A_Y_pilot, &FGInterface::set_A_Y_pilot);
|
this, &FGInterface::get_A_Y_pilot, &FGInterface::set_A_Y_pilot, false);
|
||||||
fgTie("/accelerations/pilot/z-accel-fps_sec",
|
fgTie("/accelerations/pilot/z-accel-fps_sec",
|
||||||
this, &FGInterface::get_A_Z_pilot, &FGInterface::set_A_Z_pilot);
|
this, &FGInterface::get_A_Z_pilot, &FGInterface::set_A_Z_pilot, false);
|
||||||
|
|
||||||
fgTie("/accelerations/n-z-cg-fps_sec", this, &FGInterface::get_N_Z_cg);
|
fgTie("/accelerations/n-z-cg-fps_sec",
|
||||||
|
this, &FGInterface::get_N_Z_cg); // read-only
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,7 @@
|
||||||
# include <config.h>
|
# include <config.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <memory>
|
#include <cstring>
|
||||||
#include <simgear/math/SGMathFwd.hxx> // for SGVec3d
|
#include <simgear/math/SGMathFwd.hxx> // for SGVec3d
|
||||||
#include <simgear/math/SGMisc.hxx>
|
#include <simgear/math/SGMisc.hxx>
|
||||||
|
|
||||||
|
|
|
@ -386,6 +386,7 @@ MapWidget::MapWidget(int x, int y, int maxX, int maxY) :
|
||||||
_zoom = 6;
|
_zoom = 6;
|
||||||
_width = maxX - x;
|
_width = maxX - x;
|
||||||
_height = maxY - y;
|
_height = maxY - y;
|
||||||
|
_hasPanned = false;
|
||||||
|
|
||||||
MapData::setFont(legendFont);
|
MapData::setFont(legendFont);
|
||||||
MapData::setPalette(colour);
|
MapData::setPalette(colour);
|
||||||
|
@ -496,6 +497,7 @@ int MapWidget::checkKey (int key, int updown )
|
||||||
|
|
||||||
void MapWidget::pan(const SGVec2d& delta)
|
void MapWidget::pan(const SGVec2d& delta)
|
||||||
{
|
{
|
||||||
|
_hasPanned = true;
|
||||||
_projectionCenter = unproject(-delta);
|
_projectionCenter = unproject(-delta);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -525,6 +527,12 @@ void MapWidget::draw(int dx, int dy)
|
||||||
fgGetDouble("/position/latitude-deg"));
|
fgGetDouble("/position/latitude-deg"));
|
||||||
_magneticHeadings = _root->getBoolValue("magnetic-headings");
|
_magneticHeadings = _root->getBoolValue("magnetic-headings");
|
||||||
|
|
||||||
|
if (_hasPanned)
|
||||||
|
{
|
||||||
|
_root->setBoolValue("centre-on-aircraft", false);
|
||||||
|
_hasPanned = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
if (_root->getBoolValue("centre-on-aircraft")) {
|
if (_root->getBoolValue("centre-on-aircraft")) {
|
||||||
_projectionCenter = _aircraft;
|
_projectionCenter = _aircraft;
|
||||||
}
|
}
|
||||||
|
|
|
@ -85,6 +85,7 @@ private:
|
||||||
double _drawRangeNm;
|
double _drawRangeNm;
|
||||||
double _upHeading; // true heading corresponding to +ve y-axis
|
double _upHeading; // true heading corresponding to +ve y-axis
|
||||||
bool _magneticHeadings;
|
bool _magneticHeadings;
|
||||||
|
bool _hasPanned;
|
||||||
|
|
||||||
SGGeod _projectionCenter;
|
SGGeod _projectionCenter;
|
||||||
SGGeod _aircraft;
|
SGGeod _aircraft;
|
||||||
|
|
|
@ -42,6 +42,7 @@
|
||||||
#include <simgear/debug/logstream.hxx>
|
#include <simgear/debug/logstream.hxx>
|
||||||
#include <simgear/misc/sg_path.hxx>
|
#include <simgear/misc/sg_path.hxx>
|
||||||
#include <simgear/screen/screen-dump.hxx>
|
#include <simgear/screen/screen-dump.hxx>
|
||||||
|
#include <simgear/structure/event_mgr.hxx>
|
||||||
|
|
||||||
#include <Cockpit/panel.hxx>
|
#include <Cockpit/panel.hxx>
|
||||||
#include <Main/globals.hxx>
|
#include <Main/globals.hxx>
|
||||||
|
@ -49,8 +50,11 @@
|
||||||
#include <Main/fg_os.hxx>
|
#include <Main/fg_os.hxx>
|
||||||
#include <Main/renderer.hxx>
|
#include <Main/renderer.hxx>
|
||||||
#include <Main/viewmgr.hxx>
|
#include <Main/viewmgr.hxx>
|
||||||
|
#include <Main/WindowSystemAdapter.hxx>
|
||||||
|
#include <Main/CameraGroup.hxx>
|
||||||
#include <GUI/new_gui.hxx>
|
#include <GUI/new_gui.hxx>
|
||||||
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
# include <shellapi.h>
|
# include <shellapi.h>
|
||||||
#endif
|
#endif
|
||||||
|
@ -406,9 +410,134 @@ void fgHiResDumpWrapper () {
|
||||||
fgHiResDump();
|
fgHiResDump();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
using namespace flightgear;
|
||||||
|
|
||||||
|
class GUISnapShotOperation :
|
||||||
|
public GraphicsContextOperation
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
// start new snap shot
|
||||||
|
static bool start()
|
||||||
|
{
|
||||||
|
// allow only one snapshot at a time
|
||||||
|
if (_snapShotOp.valid())
|
||||||
|
return false;
|
||||||
|
_snapShotOp = new GUISnapShotOperation();
|
||||||
|
/* register with graphics context so actual snap shot is done
|
||||||
|
* in the graphics context (thread) */
|
||||||
|
osg::Camera* guiCamera = getGUICamera(CameraGroup::getDefault());
|
||||||
|
WindowSystemAdapter* wsa = WindowSystemAdapter::getWSA();
|
||||||
|
osg::GraphicsContext* gc = 0;
|
||||||
|
if (guiCamera)
|
||||||
|
gc = guiCamera->getGraphicsContext();
|
||||||
|
if (gc) {
|
||||||
|
gc->add(_snapShotOp.get());
|
||||||
|
} else {
|
||||||
|
wsa->windows[0]->gc->add(_snapShotOp.get());
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
// constructor to be executed in main loop's thread
|
||||||
|
GUISnapShotOperation() :
|
||||||
|
flightgear::GraphicsContextOperation(std::string("GUI snap shot")),
|
||||||
|
_master_freeze(fgGetNode("/sim/freeze/master", true)),
|
||||||
|
_freeze(_master_freeze->getBoolValue()),
|
||||||
|
_result(false),
|
||||||
|
_mouse(fgGetMouseCursor())
|
||||||
|
{
|
||||||
|
if (!_freeze)
|
||||||
|
_master_freeze->setBoolValue(true);
|
||||||
|
|
||||||
|
fgSetMouseCursor(MOUSE_CURSOR_NONE);
|
||||||
|
|
||||||
|
string dir = fgGetString("/sim/paths/screenshot-dir");
|
||||||
|
if (dir.empty())
|
||||||
|
dir = fgGetString("/sim/fg-current");
|
||||||
|
|
||||||
|
_path.set(dir + '/');
|
||||||
|
if (_path.create_dir( 0755 )) {
|
||||||
|
SG_LOG(SG_GENERAL, SG_ALERT, "Cannot create screenshot directory '"
|
||||||
|
<< dir << "'. Trying home directory.");
|
||||||
|
dir = fgGetString("/sim/fg-home");
|
||||||
|
}
|
||||||
|
|
||||||
|
char filename[24];
|
||||||
|
static int count = 1;
|
||||||
|
while (count < 1000) {
|
||||||
|
snprintf(filename, 24, "fgfs-screen-%03d.png", count++);
|
||||||
|
|
||||||
|
SGPath p(dir);
|
||||||
|
p.append(filename);
|
||||||
|
if (!p.exists()) {
|
||||||
|
_path.set(p.str());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_xsize = fgGetInt("/sim/startup/xsize");
|
||||||
|
_ysize = fgGetInt("/sim/startup/ysize");
|
||||||
|
|
||||||
|
FGRenderer *renderer = globals->get_renderer();
|
||||||
|
renderer->resize(_xsize, _ysize);
|
||||||
|
globals->get_event_mgr()->addTask("SnapShotTimer",
|
||||||
|
this, &GUISnapShotOperation::timerExpired,
|
||||||
|
0.1, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
// to be executed in graphics context (maybe separate thread)
|
||||||
|
void run(osg::GraphicsContext* gc)
|
||||||
|
{
|
||||||
|
_result = sg_glDumpWindow(_path.c_str(),
|
||||||
|
_xsize,
|
||||||
|
_ysize);
|
||||||
|
}
|
||||||
|
|
||||||
|
// timer method, to be executed in main loop's thread
|
||||||
|
virtual void timerExpired()
|
||||||
|
{
|
||||||
|
if (isFinished())
|
||||||
|
{
|
||||||
|
globals->get_event_mgr()->removeTask("SnapShotTimer");
|
||||||
|
|
||||||
|
fgSetString("/sim/paths/screenshot-last", _path.c_str());
|
||||||
|
fgSetBool("/sim/signals/screenshot", _result);
|
||||||
|
|
||||||
|
fgSetMouseCursor(_mouse);
|
||||||
|
|
||||||
|
if ( !_freeze )
|
||||||
|
_master_freeze->setBoolValue(false);
|
||||||
|
|
||||||
|
_snapShotOp = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static osg::ref_ptr<GUISnapShotOperation> _snapShotOp;
|
||||||
|
SGPropertyNode_ptr _master_freeze;
|
||||||
|
bool _freeze;
|
||||||
|
bool _result;
|
||||||
|
int _mouse;
|
||||||
|
int _xsize, _ysize;
|
||||||
|
SGPath _path;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
osg::ref_ptr<GUISnapShotOperation> GUISnapShotOperation::_snapShotOp;
|
||||||
|
|
||||||
// do a screen snap shot
|
// do a screen snap shot
|
||||||
bool fgDumpSnapShot () {
|
bool fgDumpSnapShot ()
|
||||||
|
{
|
||||||
|
#if 1
|
||||||
|
// start snap shot operation, while needs to be executed in
|
||||||
|
// graphics context
|
||||||
|
return GUISnapShotOperation::start();
|
||||||
|
#else
|
||||||
|
// obsolete code => remove when new code is stable
|
||||||
static SGConstPropertyNode_ptr master_freeze = fgGetNode("/sim/freeze/master");
|
static SGConstPropertyNode_ptr master_freeze = fgGetNode("/sim/freeze/master");
|
||||||
|
|
||||||
bool freeze = master_freeze->getBoolValue();
|
bool freeze = master_freeze->getBoolValue();
|
||||||
|
@ -455,7 +584,7 @@ bool fgDumpSnapShot () {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int result = sg_glDumpWindow(path.c_str(),
|
bool result = sg_glDumpWindow(path.c_str(),
|
||||||
fgGetInt("/sim/startup/xsize"),
|
fgGetInt("/sim/startup/xsize"),
|
||||||
fgGetInt("/sim/startup/ysize"));
|
fgGetInt("/sim/startup/ysize"));
|
||||||
|
|
||||||
|
@ -467,7 +596,8 @@ bool fgDumpSnapShot () {
|
||||||
if ( !freeze ) {
|
if ( !freeze ) {
|
||||||
fgSetBool("/sim/freeze/master", false);
|
fgSetBool("/sim/freeze/master", false);
|
||||||
}
|
}
|
||||||
return result != 0;
|
return result;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// do an entire scenegraph dump
|
// do an entire scenegraph dump
|
||||||
|
|
|
@ -49,7 +49,8 @@ FGJoystickInput::joystick::joystick ()
|
||||||
naxes(0),
|
naxes(0),
|
||||||
nbuttons(0),
|
nbuttons(0),
|
||||||
axes(0),
|
axes(0),
|
||||||
buttons(0)
|
buttons(0),
|
||||||
|
predefined(true)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,15 +74,18 @@ FGJoystickInput::FGJoystickInput()
|
||||||
|
|
||||||
FGJoystickInput::~FGJoystickInput()
|
FGJoystickInput::~FGJoystickInput()
|
||||||
{
|
{
|
||||||
_remove();
|
_remove(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FGJoystickInput::_remove()
|
void FGJoystickInput::_remove(bool all)
|
||||||
{
|
{
|
||||||
SGPropertyNode * js_nodes = fgGetNode("/input/joysticks", true);
|
SGPropertyNode * js_nodes = fgGetNode("/input/joysticks", true);
|
||||||
js_nodes->removeChildren("js", false);
|
|
||||||
for (int i = 0; i < MAX_JOYSTICKS; i++)
|
for (int i = 0; i < MAX_JOYSTICKS; i++)
|
||||||
{
|
{
|
||||||
|
// do not remove predefined joysticks info on reinit
|
||||||
|
if ((all)||(!bindings[i].predefined))
|
||||||
|
js_nodes->removeChild("js", i, false);
|
||||||
if (bindings[i].js)
|
if (bindings[i].js)
|
||||||
delete bindings[i].js;
|
delete bindings[i].js;
|
||||||
bindings[i].js = NULL;
|
bindings[i].js = NULL;
|
||||||
|
@ -92,7 +96,7 @@ void FGJoystickInput::init()
|
||||||
{
|
{
|
||||||
jsInit();
|
jsInit();
|
||||||
SG_LOG(SG_INPUT, SG_DEBUG, "Initializing joystick bindings");
|
SG_LOG(SG_INPUT, SG_DEBUG, "Initializing joystick bindings");
|
||||||
SGPropertyNode * js_nodes = fgGetNode("/input/joysticks", true);
|
SGPropertyNode_ptr js_nodes = fgGetNode("/input/joysticks", true);
|
||||||
|
|
||||||
FGDeviceConfigurationMap configMap("Input/Joysticks", js_nodes, "js-named");
|
FGDeviceConfigurationMap configMap("Input/Joysticks", js_nodes, "js-named");
|
||||||
|
|
||||||
|
@ -112,6 +116,7 @@ void FGJoystickInput::init()
|
||||||
SG_LOG(SG_INPUT, SG_INFO, "Using existing bindings for joystick " << i);
|
SG_LOG(SG_INPUT, SG_INFO, "Using existing bindings for joystick " << i);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
bindings[i].predefined = false;
|
||||||
SG_LOG(SG_INPUT, SG_INFO, "Looking for bindings for joystick \"" << name << '"');
|
SG_LOG(SG_INPUT, SG_INFO, "Looking for bindings for joystick \"" << name << '"');
|
||||||
SGPropertyNode_ptr named;
|
SGPropertyNode_ptr named;
|
||||||
|
|
||||||
|
@ -137,7 +142,7 @@ void FGJoystickInput::init()
|
||||||
|
|
||||||
void FGJoystickInput::reinit() {
|
void FGJoystickInput::reinit() {
|
||||||
SG_LOG(SG_INPUT, SG_DEBUG, "Re-Initializing joystick bindings");
|
SG_LOG(SG_INPUT, SG_DEBUG, "Re-Initializing joystick bindings");
|
||||||
_remove();
|
_remove(false);
|
||||||
FGJoystickInput::init();
|
FGJoystickInput::init();
|
||||||
FGJoystickInput::postinit();
|
FGJoystickInput::postinit();
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,7 +52,7 @@ public:
|
||||||
static const int MAX_JOYSTICK_BUTTONS = 32;
|
static const int MAX_JOYSTICK_BUTTONS = 32;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void _remove();
|
void _remove(bool all);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Settings for a single joystick axis.
|
* Settings for a single joystick axis.
|
||||||
|
@ -83,6 +83,7 @@ private:
|
||||||
int nbuttons;
|
int nbuttons;
|
||||||
axis * axes;
|
axis * axes;
|
||||||
FGButton * buttons;
|
FGButton * buttons;
|
||||||
|
bool predefined;
|
||||||
};
|
};
|
||||||
joystick bindings[MAX_JOYSTICKS];
|
joystick bindings[MAX_JOYSTICKS];
|
||||||
|
|
||||||
|
|
|
@ -23,8 +23,8 @@
|
||||||
// $Id$
|
// $Id$
|
||||||
|
|
||||||
#include "FGMouseInput.hxx"
|
#include "FGMouseInput.hxx"
|
||||||
|
#include "Main/globals.hxx"
|
||||||
|
|
||||||
|
|
||||||
void ActivePickCallbacks::init( int b, const osgGA::GUIEventAdapter* ea )
|
void ActivePickCallbacks::init( int b, const osgGA::GUIEventAdapter* ea )
|
||||||
{
|
{
|
||||||
// Get the list of hit callbacks. Take the first callback that
|
// Get the list of hit callbacks. Take the first callback that
|
||||||
|
@ -33,7 +33,7 @@ void ActivePickCallbacks::init( int b, const osgGA::GUIEventAdapter* ea )
|
||||||
// The nearest one is the first one and the deepest
|
// The nearest one is the first one and the deepest
|
||||||
// (the most specialized one in the scenegraph) is the first.
|
// (the most specialized one in the scenegraph) is the first.
|
||||||
std::vector<SGSceneryPick> pickList;
|
std::vector<SGSceneryPick> pickList;
|
||||||
if (FGRenderer::pick(pickList, ea)) {
|
if (globals->get_renderer()->pick(pickList, ea)) {
|
||||||
std::vector<SGSceneryPick>::const_iterator i;
|
std::vector<SGSceneryPick>::const_iterator i;
|
||||||
for (i = pickList.begin(); i != pickList.end(); ++i) {
|
for (i = pickList.begin(); i != pickList.end(); ++i) {
|
||||||
if (i->callback->buttonPressed(b, i->info)) {
|
if (i->callback->buttonPressed(b, i->info)) {
|
||||||
|
|
|
@ -269,7 +269,7 @@ public:
|
||||||
_offset = n->getFloatValue("offset", offset);
|
_offset = n->getFloatValue("offset", offset);
|
||||||
_min = n->getFloatValue("min", min);
|
_min = n->getFloatValue("min", min);
|
||||||
_max = n->getFloatValue("max", max);
|
_max = n->getFloatValue("max", max);
|
||||||
_coeff = 1.0 - 1.0 / powf(10, fabsf(n->getFloatValue("damp", 0.0)));
|
_coeff = 1.0 - 1.0 / powf(10, fabs(n->getFloatValue("damp", 0.0)));
|
||||||
SGPropertyNode *p = ((SGPropertyNode *)n)->getNode("property", false);
|
SGPropertyNode *p = ((SGPropertyNode *)n)->getNode("property", false);
|
||||||
if (p) {
|
if (p) {
|
||||||
const char *path = p->getStringValue();
|
const char *path = p->getStringValue();
|
||||||
|
|
|
@ -89,7 +89,7 @@ void HUD::Label::draw(void)
|
||||||
|
|
||||||
l = _center_x - pw;
|
l = _center_x - pw;
|
||||||
r = _center_x + pw;
|
r = _center_x + pw;
|
||||||
bool draw_parallel = fabsf(_pointer_width - _w) > 2.0; // draw lines left and right of arrow?
|
bool draw_parallel = fabs(_pointer_width - _w) > 2.0; // draw lines left and right of arrow?
|
||||||
|
|
||||||
if (option_bottom()) {
|
if (option_bottom()) {
|
||||||
if (draw_parallel) {
|
if (draw_parallel) {
|
||||||
|
@ -115,7 +115,7 @@ void HUD::Label::draw(void)
|
||||||
|
|
||||||
l = _center_y - pw;
|
l = _center_y - pw;
|
||||||
r = _center_y + pw;
|
r = _center_y + pw;
|
||||||
draw_parallel = fabsf(_pointer_width - _h) > 2.0;
|
draw_parallel = fabs(_pointer_width - _h) > 2.0;
|
||||||
|
|
||||||
if (option_left()) {
|
if (option_left()) {
|
||||||
if (draw_parallel) {
|
if (draw_parallel) {
|
||||||
|
|
|
@ -48,7 +48,7 @@ HUD::Ladder::Ladder(HUD *hud, const SGPropertyNode *n, float x, float y) :
|
||||||
_roll(n->getNode("roll-input", false)),
|
_roll(n->getNode("roll-input", false)),
|
||||||
_width_units(int(n->getFloatValue("display-span"))),
|
_width_units(int(n->getFloatValue("display-span"))),
|
||||||
_div_units(int(fabs(n->getFloatValue("divisions")))),
|
_div_units(int(fabs(n->getFloatValue("divisions")))),
|
||||||
_scr_hole(fabsf(n->getFloatValue("screen-hole")) * 0.5f),
|
_scr_hole(fabs(n->getFloatValue("screen-hole")) * 0.5f),
|
||||||
_zero_bar_overlength(n->getFloatValue("zero-bar-overlength", 10)),
|
_zero_bar_overlength(n->getFloatValue("zero-bar-overlength", 10)),
|
||||||
_dive_bar_angle(n->getBoolValue("enable-dive-bar-angle")),
|
_dive_bar_angle(n->getBoolValue("enable-dive-bar-angle")),
|
||||||
_tick_length(n->getFloatValue("tick-length")),
|
_tick_length(n->getFloatValue("tick-length")),
|
||||||
|
|
|
@ -534,7 +534,7 @@ void HUD::Tape::draw_horizontal(float value)
|
||||||
|
|
||||||
char *HUD::Tape::format_value(float v)
|
char *HUD::Tape::format_value(float v)
|
||||||
{
|
{
|
||||||
if (fabsf(v) < 1e-8) // avoid -0.0
|
if (fabs(v) < 1e-8) // avoid -0.0
|
||||||
v = 0.0f;
|
v = 0.0f;
|
||||||
|
|
||||||
if (_label_fmt == INT)
|
if (_label_fmt == INT)
|
||||||
|
|
|
@ -129,12 +129,12 @@ void HUD::TurnBankIndicator::draw_scale()
|
||||||
|
|
||||||
int dir = bank > 0 ? 1 : -1;
|
int dir = bank > 0 ? 1 : -1;
|
||||||
|
|
||||||
if (fabsf(bank) > 25) {
|
if (fabs(bank) > 25) {
|
||||||
draw_tick(45, r, minor, dir);
|
draw_tick(45, r, minor, dir);
|
||||||
draw_tick(60, r, major, dir);
|
draw_tick(60, r, major, dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fabsf(bank) > 55) {
|
if (fabs(bank) > 55) {
|
||||||
draw_tick(90, r, major, dir);
|
draw_tick(90, r, major, dir);
|
||||||
draw_tick(135, r, major, dir);
|
draw_tick(135, r, major, dir);
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,7 +38,6 @@
|
||||||
|
|
||||||
#include <simgear/constants.h>
|
#include <simgear/constants.h>
|
||||||
#include <simgear/misc/sg_path.hxx>
|
#include <simgear/misc/sg_path.hxx>
|
||||||
#include <simgear/environment/visual_enviro.hxx>
|
|
||||||
#include <simgear/scene/model/model.hxx>
|
#include <simgear/scene/model/model.hxx>
|
||||||
#include <simgear/structure/exception.hxx>
|
#include <simgear/structure/exception.hxx>
|
||||||
#include <simgear/misc/sg_path.hxx>
|
#include <simgear/misc/sg_path.hxx>
|
||||||
|
@ -137,7 +136,7 @@ wxRadarBg::init ()
|
||||||
SGPath tpath = globals->resolve_aircraft_path(path);
|
SGPath tpath = globals->resolve_aircraft_path(path);
|
||||||
|
|
||||||
// no mipmap or else alpha will mix with pixels on the border of shapes, ruining the effect
|
// no mipmap or else alpha will mix with pixels on the border of shapes, ruining the effect
|
||||||
_wxEcho = SGLoadTexture2D(tpath, false, false);
|
_wxEcho = SGLoadTexture2D(tpath, NULL, false, false);
|
||||||
|
|
||||||
|
|
||||||
_Instrument->setFloatValue("trk", 0.0);
|
_Instrument->setFloatValue("trk", 0.0);
|
||||||
|
@ -379,15 +378,22 @@ wxRadarBg::update (double delta_time_sec)
|
||||||
_texCoords->clear();
|
_texCoords->clear();
|
||||||
_textGeode->removeDrawables(0, _textGeode->getNumDrawables());
|
_textGeode->removeDrawables(0, _textGeode->getNumDrawables());
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
//TODO FIXME Mask below (only used for ARC mode) isn't properly aligned, i.e.
|
||||||
|
// it assumes the a/c position at the center of the display - though it's somewhere at
|
||||||
|
// bottom part for ARC mode.
|
||||||
|
// The mask hadn't worked at all for a while (probably since the OSG port) due to
|
||||||
|
// another bug (which is fixed now). Now, the mask is disabled completely until s.o.
|
||||||
|
// adapted the coordinates below. And the mask is only really useful to limit displayed
|
||||||
|
// weather blobs (not support yet).
|
||||||
|
// Aircraft echos are already limited properly through wxradar's "limit-deg" property.
|
||||||
|
{
|
||||||
|
osg::DrawArrays *maskPSet
|
||||||
|
= static_cast<osg::DrawArrays*>(_geom->getPrimitiveSet(1));
|
||||||
|
osg::DrawArrays *trimaskPSet
|
||||||
|
= static_cast<osg::DrawArrays*>(_geom->getPrimitiveSet(2));
|
||||||
|
|
||||||
update_weather();
|
if (_display_mode == ARC) {
|
||||||
|
|
||||||
|
|
||||||
osg::DrawArrays *quadPSet
|
|
||||||
= static_cast<osg::DrawArrays*>(_geom->getPrimitiveSet(0));
|
|
||||||
quadPSet->set(osg::PrimitiveSet::QUADS, 0, _vertices->size());
|
|
||||||
quadPSet->dirty();
|
|
||||||
|
|
||||||
// erase what is out of sight of antenna
|
// erase what is out of sight of antenna
|
||||||
/*
|
/*
|
||||||
|\ /|
|
|\ /|
|
||||||
|
@ -398,13 +404,6 @@ wxRadarBg::update (double delta_time_sec)
|
||||||
| |
|
| |
|
||||||
---------
|
---------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
osg::DrawArrays *maskPSet
|
|
||||||
= static_cast<osg::DrawArrays*>(_geom->getPrimitiveSet(1));
|
|
||||||
osg::DrawArrays *trimaskPSet
|
|
||||||
= static_cast<osg::DrawArrays*>(_geom->getPrimitiveSet(2));
|
|
||||||
|
|
||||||
if (_display_mode == ARC) {
|
|
||||||
float xOffset = 256.0f;
|
float xOffset = 256.0f;
|
||||||
float yOffset = 200.0f;
|
float yOffset = 200.0f;
|
||||||
|
|
||||||
|
@ -418,6 +417,7 @@ wxRadarBg::update (double delta_time_sec)
|
||||||
_texCoords->push_back(osg::Vec2f(0.5f, 0.5f));
|
_texCoords->push_back(osg::Vec2f(0.5f, 0.5f));
|
||||||
_vertices->push_back(osg::Vec2f(-xOffset, 256.0 + yOffset));
|
_vertices->push_back(osg::Vec2f(-xOffset, 256.0 + yOffset));
|
||||||
maskPSet->set(osg::PrimitiveSet::QUADS, firstQuadVert, 4);
|
maskPSet->set(osg::PrimitiveSet::QUADS, firstQuadVert, 4);
|
||||||
|
firstQuadVert += 4;
|
||||||
|
|
||||||
// The triangles aren't supposed to be textured, but there's
|
// The triangles aren't supposed to be textured, but there's
|
||||||
// no need to set up a different Geometry, switch modes,
|
// no need to set up a different Geometry, switch modes,
|
||||||
|
@ -444,25 +444,33 @@ wxRadarBg::update (double delta_time_sec)
|
||||||
for (int i = 0; i < 3 * 4; i++)
|
for (int i = 0; i < 3 * 4; i++)
|
||||||
_texCoords->push_back(whiteSpot);
|
_texCoords->push_back(whiteSpot);
|
||||||
|
|
||||||
trimaskPSet->set(osg::PrimitiveSet::TRIANGLES, firstQuadVert + 4, 3 * 4);
|
trimaskPSet->set(osg::PrimitiveSet::TRIANGLES, firstQuadVert, 3 * 4);
|
||||||
|
|
||||||
} else {
|
} else
|
||||||
|
{
|
||||||
maskPSet->set(osg::PrimitiveSet::QUADS, 0, 0);
|
maskPSet->set(osg::PrimitiveSet::QUADS, 0, 0);
|
||||||
trimaskPSet->set(osg::PrimitiveSet::TRIANGLES, 0, 0);
|
trimaskPSet->set(osg::PrimitiveSet::TRIANGLES, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
maskPSet->dirty();
|
maskPSet->dirty();
|
||||||
trimaskPSet->dirty();
|
trimaskPSet->dirty();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// draw without mask
|
// remember index of next vertex
|
||||||
_vertices->clear();
|
int vIndex = _vertices->size();
|
||||||
_texCoords->clear();
|
|
||||||
|
update_weather();
|
||||||
|
|
||||||
|
osg::DrawArrays *quadPSet
|
||||||
|
= static_cast<osg::DrawArrays*>(_geom->getPrimitiveSet(0));
|
||||||
|
|
||||||
update_aircraft();
|
update_aircraft();
|
||||||
update_tacan();
|
update_tacan();
|
||||||
update_heading_marker();
|
update_heading_marker();
|
||||||
|
|
||||||
quadPSet->set(osg::PrimitiveSet::QUADS, 0, _vertices->size());
|
// draw all new vertices are quads
|
||||||
|
quadPSet->set(osg::PrimitiveSet::QUADS, vIndex, _vertices->size()-vIndex);
|
||||||
quadPSet->dirty();
|
quadPSet->dirty();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -472,13 +480,16 @@ void
|
||||||
wxRadarBg::update_weather()
|
wxRadarBg::update_weather()
|
||||||
{
|
{
|
||||||
string modeButton = _Instrument->getStringValue("mode", "WX");
|
string modeButton = _Instrument->getStringValue("mode", "WX");
|
||||||
_radarEchoBuffer = *sgEnviro.get_radar_echo();
|
// FIXME: implementation of radar echoes missing
|
||||||
|
// _radarEchoBuffer = *sgEnviro.get_radar_echo();
|
||||||
|
|
||||||
// pretend we have a scan angle bigger then the FOV
|
// pretend we have a scan angle bigger then the FOV
|
||||||
// TODO:check real fov, enlarge if < nn, and do clipping if > mm
|
// TODO:check real fov, enlarge if < nn, and do clipping if > mm
|
||||||
// const float fovFactor = 1.45f;
|
// const float fovFactor = 1.45f;
|
||||||
_Instrument->setStringValue("status", modeButton.c_str());
|
_Instrument->setStringValue("status", modeButton.c_str());
|
||||||
|
|
||||||
|
// FIXME: implementation of radar echoes missing
|
||||||
|
#if 0
|
||||||
list_of_SGWxRadarEcho *radarEcho = &_radarEchoBuffer;
|
list_of_SGWxRadarEcho *radarEcho = &_radarEchoBuffer;
|
||||||
list_of_SGWxRadarEcho::iterator iradarEcho, end = radarEcho->end();
|
list_of_SGWxRadarEcho::iterator iradarEcho, end = radarEcho->end();
|
||||||
const float LWClevel[] = { 0.1f, 0.5f, 2.1f };
|
const float LWClevel[] = { 0.1f, 0.5f, 2.1f };
|
||||||
|
@ -558,6 +569,7 @@ wxRadarBg::update_weather()
|
||||||
addQuad(_vertices, _texCoords, m, texBase);
|
addQuad(_vertices, _texCoords, m, texBase);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,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/environment/visual_enviro.hxx>
|
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
@ -148,7 +147,8 @@ private:
|
||||||
float _font_size;
|
float _font_size;
|
||||||
float _font_spacing;
|
float _font_spacing;
|
||||||
|
|
||||||
list_of_SGWxRadarEcho _radarEchoBuffer;
|
// FIXME: implementation of radar echoes missing
|
||||||
|
// list_of_SGWxRadarEcho _radarEchoBuffer;
|
||||||
|
|
||||||
void update_weather();
|
void update_weather();
|
||||||
void update_aircraft();
|
void update_aircraft();
|
||||||
|
|
|
@ -91,12 +91,13 @@ WindowBuilder::makeDefaultTraits(bool stencil)
|
||||||
traits->windowDecoration = true;
|
traits->windowDecoration = true;
|
||||||
traits->width = w;
|
traits->width = w;
|
||||||
traits->height = h;
|
traits->height = h;
|
||||||
#if defined(WIN32) || defined(__APPLE__)
|
unsigned screenwidth = 0;
|
||||||
|
unsigned screenheight = 0;
|
||||||
|
wsi->getScreenResolution(*traits, screenwidth, screenheight);
|
||||||
// Ugly Hack, why does CW_USEDEFAULT works like phase of the moon?
|
// Ugly Hack, why does CW_USEDEFAULT works like phase of the moon?
|
||||||
// Mac also needs this to show window frame, menubar and Docks
|
// Mac also needs this to show window frame, menubar and Docks
|
||||||
traits->x = 100;
|
traits->x = (w>screenwidth) ? 0 : (screenwidth-w)/3;
|
||||||
traits->y = 100;
|
traits->y = (h>screenheight) ? 0 : (screenheight-h)/3;
|
||||||
#endif
|
|
||||||
traits->supportsResize = true;
|
traits->supportsResize = true;
|
||||||
}
|
}
|
||||||
return traits;
|
return traits;
|
||||||
|
|
|
@ -33,7 +33,7 @@
|
||||||
#include <Scenery/scenery.hxx>
|
#include <Scenery/scenery.hxx>
|
||||||
#include <Scripting/NasalSys.hxx>
|
#include <Scripting/NasalSys.hxx>
|
||||||
#include <Sound/sample_queue.hxx>
|
#include <Sound/sample_queue.hxx>
|
||||||
#include <Time/sunsolver.hxx>
|
#include <Airports/xmlloader.hxx>
|
||||||
|
|
||||||
#include "fg_init.hxx"
|
#include "fg_init.hxx"
|
||||||
#include "fg_io.hxx"
|
#include "fg_io.hxx"
|
||||||
|
@ -314,6 +314,16 @@ do_resume (const SGPropertyNode * arg)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static bool
|
||||||
|
do_pause (const SGPropertyNode * arg)
|
||||||
|
{
|
||||||
|
bool paused = fgGetBool("/sim/freeze/master",true) || fgGetBool("/sim/freeze/clock",true);
|
||||||
|
fgSetBool("/sim/freeze/master",!paused);
|
||||||
|
fgSetBool("/sim/freeze/clock",!paused);
|
||||||
|
if (fgGetBool("/sim/freeze/replay-state",false))
|
||||||
|
fgSetBool("/sim/replay/disable",true);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Built-in command: load flight.
|
* Built-in command: load flight.
|
||||||
|
@ -688,85 +698,6 @@ do_set_dewpoint_degc (const SGPropertyNode * arg)
|
||||||
return do_set_dewpoint_sea_level_degc(dummy.get_dewpoint_sea_level_degc());
|
return do_set_dewpoint_sea_level_degc(dummy.get_dewpoint_sea_level_degc());
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
/**
|
|
||||||
* Update the lighting manually.
|
|
||||||
*/
|
|
||||||
static bool
|
|
||||||
do_timeofday (const SGPropertyNode * arg)
|
|
||||||
{
|
|
||||||
const string &offset_type = arg->getStringValue("timeofday", "noon");
|
|
||||||
|
|
||||||
static const SGPropertyNode *longitude
|
|
||||||
= fgGetNode("/position/longitude-deg");
|
|
||||||
static const SGPropertyNode *latitude
|
|
||||||
= fgGetNode("/position/latitude-deg");
|
|
||||||
|
|
||||||
int orig_warp = globals->get_warp();
|
|
||||||
SGTime *t = globals->get_time_params();
|
|
||||||
time_t cur_time = t->get_cur_time();
|
|
||||||
// cout << "cur_time = " << cur_time << endl;
|
|
||||||
// cout << "orig_warp = " << orig_warp << endl;
|
|
||||||
|
|
||||||
int warp = 0;
|
|
||||||
if ( offset_type == "real" ) {
|
|
||||||
warp = -orig_warp;
|
|
||||||
} else if ( offset_type == "dawn" ) {
|
|
||||||
warp = fgTimeSecondsUntilSunAngle( cur_time,
|
|
||||||
longitude->getDoubleValue()
|
|
||||||
* SGD_DEGREES_TO_RADIANS,
|
|
||||||
latitude->getDoubleValue()
|
|
||||||
* SGD_DEGREES_TO_RADIANS,
|
|
||||||
90.0, true );
|
|
||||||
} else if ( offset_type == "morning" ) {
|
|
||||||
warp = fgTimeSecondsUntilSunAngle( cur_time,
|
|
||||||
longitude->getDoubleValue()
|
|
||||||
* SGD_DEGREES_TO_RADIANS,
|
|
||||||
latitude->getDoubleValue()
|
|
||||||
* SGD_DEGREES_TO_RADIANS,
|
|
||||||
75.0, true );
|
|
||||||
} else if ( offset_type == "noon" ) {
|
|
||||||
warp = fgTimeSecondsUntilSunAngle( cur_time,
|
|
||||||
longitude->getDoubleValue()
|
|
||||||
* SGD_DEGREES_TO_RADIANS,
|
|
||||||
latitude->getDoubleValue()
|
|
||||||
* SGD_DEGREES_TO_RADIANS,
|
|
||||||
0.0, true );
|
|
||||||
} else if ( offset_type == "afternoon" ) {
|
|
||||||
warp = fgTimeSecondsUntilSunAngle( cur_time,
|
|
||||||
longitude->getDoubleValue()
|
|
||||||
* SGD_DEGREES_TO_RADIANS,
|
|
||||||
latitude->getDoubleValue()
|
|
||||||
* SGD_DEGREES_TO_RADIANS,
|
|
||||||
60.0, false );
|
|
||||||
} else if ( offset_type == "dusk" ) {
|
|
||||||
warp = fgTimeSecondsUntilSunAngle( cur_time,
|
|
||||||
longitude->getDoubleValue()
|
|
||||||
* SGD_DEGREES_TO_RADIANS,
|
|
||||||
latitude->getDoubleValue()
|
|
||||||
* SGD_DEGREES_TO_RADIANS,
|
|
||||||
90.0, false );
|
|
||||||
} else if ( offset_type == "evening" ) {
|
|
||||||
warp = fgTimeSecondsUntilSunAngle( cur_time,
|
|
||||||
longitude->getDoubleValue()
|
|
||||||
* SGD_DEGREES_TO_RADIANS,
|
|
||||||
latitude->getDoubleValue()
|
|
||||||
* SGD_DEGREES_TO_RADIANS,
|
|
||||||
100.0, false );
|
|
||||||
} else if ( offset_type == "midnight" ) {
|
|
||||||
warp = fgTimeSecondsUntilSunAngle( cur_time,
|
|
||||||
longitude->getDoubleValue()
|
|
||||||
* SGD_DEGREES_TO_RADIANS,
|
|
||||||
latitude->getDoubleValue()
|
|
||||||
* SGD_DEGREES_TO_RADIANS,
|
|
||||||
180.0, false );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
fgSetInt("/sim/time/warp", orig_warp + warp);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Built-in command: toggle a bool property value.
|
* Built-in command: toggle a bool property value.
|
||||||
|
@ -1247,17 +1178,7 @@ do_replay (const SGPropertyNode * arg)
|
||||||
fgSetInt( "/sim/freeze/replay-state", 1 );
|
fgSetInt( "/sim/freeze/replay-state", 1 );
|
||||||
fgSetBool("/sim/freeze/master", 0 );
|
fgSetBool("/sim/freeze/master", 0 );
|
||||||
fgSetBool("/sim/freeze/clock", 0 );
|
fgSetBool("/sim/freeze/clock", 0 );
|
||||||
|
fgSetDouble( "/sim/replay/time", -1 );
|
||||||
FGReplay *r = (FGReplay *)(globals->get_subsystem( "replay" ));
|
|
||||||
|
|
||||||
fgSetDouble( "/sim/replay/start-time", r->get_start_time() );
|
|
||||||
fgSetDouble( "/sim/replay/end-time", r->get_end_time() );
|
|
||||||
double duration = fgGetDouble( "/sim/replay/duration" );
|
|
||||||
if( duration && duration < (r->get_end_time() - r->get_start_time()) ) {
|
|
||||||
fgSetDouble( "/sim/replay/time", r->get_end_time() - duration );
|
|
||||||
} else {
|
|
||||||
fgSetDouble( "/sim/replay/time", r->get_start_time() );
|
|
||||||
}
|
|
||||||
|
|
||||||
// cout << "start = " << r->get_start_time()
|
// cout << "start = " << r->get_start_time()
|
||||||
// << " end = " << r->get_end_time() << endl;
|
// << " end = " << r->get_end_time() << endl;
|
||||||
|
@ -1302,9 +1223,18 @@ do_load_xml_to_proptree(const SGPropertyNode * arg)
|
||||||
if (file.extension() != "xml")
|
if (file.extension() != "xml")
|
||||||
file.concat(".xml");
|
file.concat(".xml");
|
||||||
|
|
||||||
|
std::string icao = arg->getStringValue("icao");
|
||||||
|
if (icao.empty()) {
|
||||||
if (file.isRelative()) {
|
if (file.isRelative()) {
|
||||||
file = globals->resolve_maybe_aircraft_path(file.str());
|
file = globals->resolve_maybe_aircraft_path(file.str());
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
if (!XMLLoader::findAirportData(icao, file.str(), file)) {
|
||||||
|
SG_LOG(SG_IO, SG_INFO, "loadxml: failed to find airport data for "
|
||||||
|
<< file.str() << " at ICAO:" << icao);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!fgValidatePath(file.c_str(), false)) {
|
if (!fgValidatePath(file.c_str(), false)) {
|
||||||
SG_LOG(SG_IO, SG_ALERT, "loadxml: reading '" << file.str() << "' denied "
|
SG_LOG(SG_IO, SG_ALERT, "loadxml: reading '" << file.str() << "' denied "
|
||||||
|
@ -1442,6 +1372,7 @@ static struct {
|
||||||
{ "reinit", do_reinit },
|
{ "reinit", do_reinit },
|
||||||
{ "suspend", do_reinit },
|
{ "suspend", do_reinit },
|
||||||
{ "resume", do_reinit },
|
{ "resume", do_reinit },
|
||||||
|
{ "pause", do_pause },
|
||||||
{ "load", do_load },
|
{ "load", do_load },
|
||||||
{ "save", do_save },
|
{ "save", do_save },
|
||||||
{ "panel-load", do_panel_load },
|
{ "panel-load", do_panel_load },
|
||||||
|
@ -1457,7 +1388,6 @@ static struct {
|
||||||
{ "set-dewpoint-sea-level-air-temp-degc", do_set_dewpoint_sea_level_degc },
|
{ "set-dewpoint-sea-level-air-temp-degc", do_set_dewpoint_sea_level_degc },
|
||||||
{ "set-dewpoint-temp-degc", do_set_dewpoint_degc },
|
{ "set-dewpoint-temp-degc", do_set_dewpoint_degc },
|
||||||
*/
|
*/
|
||||||
{ "timeofday", do_timeofday },
|
|
||||||
{ "property-toggle", do_property_toggle },
|
{ "property-toggle", do_property_toggle },
|
||||||
{ "property-assign", do_property_assign },
|
{ "property-assign", do_property_assign },
|
||||||
{ "property-adjust", do_property_adjust },
|
{ "property-adjust", do_property_adjust },
|
||||||
|
|
|
@ -46,6 +46,7 @@
|
||||||
#include <Network/atlas.hxx>
|
#include <Network/atlas.hxx>
|
||||||
#include <Network/AV400.hxx>
|
#include <Network/AV400.hxx>
|
||||||
#include <Network/AV400Sim.hxx>
|
#include <Network/AV400Sim.hxx>
|
||||||
|
#include <Network/AV400WSim.hxx>
|
||||||
#include <Network/garmin.hxx>
|
#include <Network/garmin.hxx>
|
||||||
#include <Network/httpd.hxx>
|
#include <Network/httpd.hxx>
|
||||||
#ifdef FG_JPEG_SERVER
|
#ifdef FG_JPEG_SERVER
|
||||||
|
@ -64,7 +65,7 @@
|
||||||
#include <Network/ray.hxx>
|
#include <Network/ray.hxx>
|
||||||
#include <Network/rul.hxx>
|
#include <Network/rul.hxx>
|
||||||
#include <Network/generic.hxx>
|
#include <Network/generic.hxx>
|
||||||
#include <Network/multiplay.hxx>
|
|
||||||
#ifdef FG_HAVE_HLA
|
#ifdef FG_HAVE_HLA
|
||||||
#include <Network/HLA/hla.hxx>
|
#include <Network/HLA/hla.hxx>
|
||||||
#endif
|
#endif
|
||||||
|
@ -142,6 +143,12 @@ FGIO::parse_port_config( const string& config )
|
||||||
} else if ( protocol == "AV400Sim" ) {
|
} else if ( protocol == "AV400Sim" ) {
|
||||||
FGAV400Sim *av400sim = new FGAV400Sim;
|
FGAV400Sim *av400sim = new FGAV400Sim;
|
||||||
io = av400sim;
|
io = av400sim;
|
||||||
|
} else if ( protocol == "AV400WSimA" ) {
|
||||||
|
FGAV400WSimA *av400wsima = new FGAV400WSimA;
|
||||||
|
io = av400wsima;
|
||||||
|
} else if ( protocol == "AV400WSimB" ) {
|
||||||
|
FGAV400WSimB *av400wsimb = new FGAV400WSimB;
|
||||||
|
io = av400wsimb;
|
||||||
} else if ( protocol == "garmin" ) {
|
} else if ( protocol == "garmin" ) {
|
||||||
FGGarmin *garmin = new FGGarmin;
|
FGGarmin *garmin = new FGGarmin;
|
||||||
io = garmin;
|
io = garmin;
|
||||||
|
@ -212,10 +219,23 @@ FGIO::parse_port_config( const string& config )
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
string dir = tokens[1];
|
string dir = tokens[1];
|
||||||
string rate = tokens[2];
|
int rate = atoi(tokens[2].c_str());
|
||||||
string host = tokens[3];
|
string host = tokens[3];
|
||||||
string port = tokens[4];
|
|
||||||
return new FGMultiplay(dir, atoi(rate.c_str()), host, atoi(port.c_str()));
|
short port = atoi(tokens[4].c_str());
|
||||||
|
|
||||||
|
// multiplay used to be handled by an FGProtocol, but no longer. This code
|
||||||
|
// retains compatability with existing command-line syntax
|
||||||
|
fgSetInt("/sim/multiplay/tx-rate-hz", rate);
|
||||||
|
if (dir == "in") {
|
||||||
|
fgSetInt("/sim/multiplay/rxport", port);
|
||||||
|
fgSetString("/sim/multiplay/rxhost", host.c_str());
|
||||||
|
} else if (dir == "out") {
|
||||||
|
fgSetInt("/sim/multiplay/txport", port);
|
||||||
|
fgSetString("/sim/multiplay/txhost", host.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
#ifdef FG_HAVE_HLA
|
#ifdef FG_HAVE_HLA
|
||||||
} else if ( protocol == "hla" ) {
|
} else if ( protocol == "hla" ) {
|
||||||
return new FGHLA(tokens);
|
return new FGHLA(tokens);
|
||||||
|
@ -263,6 +283,17 @@ FGIO::parse_port_config( const string& config )
|
||||||
|
|
||||||
SGSerial *ch = new SGSerial( device, baud );
|
SGSerial *ch = new SGSerial( device, baud );
|
||||||
io->set_io_channel( ch );
|
io->set_io_channel( ch );
|
||||||
|
|
||||||
|
if ( protocol == "AV400WSimB" ) {
|
||||||
|
if ( tokens.size() < 7 ) {
|
||||||
|
SG_LOG( SG_IO, SG_ALERT, "Missing second hz for AV400WSimB.");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
FGAV400WSimB *fgavb = static_cast<FGAV400WSimB*>(io);
|
||||||
|
string hz2_str = tokens[6];
|
||||||
|
double hz2 = atof(hz2_str.c_str());
|
||||||
|
fgavb->set_hz2(hz2);
|
||||||
|
}
|
||||||
} else if ( medium == "file" ) {
|
} else if ( medium == "file" ) {
|
||||||
// file name
|
// file name
|
||||||
if ( tokens.size() < 4) {
|
if ( tokens.size() < 4) {
|
||||||
|
@ -325,20 +356,20 @@ FGIO::init()
|
||||||
// appropriate FGIOChannel structures
|
// appropriate FGIOChannel structures
|
||||||
string_list::iterator i = globals->get_channel_options_list()->begin();
|
string_list::iterator i = globals->get_channel_options_list()->begin();
|
||||||
string_list::iterator end = globals->get_channel_options_list()->end();
|
string_list::iterator end = globals->get_channel_options_list()->end();
|
||||||
for (; i != end; ++i )
|
for (; i != end; ++i ) {
|
||||||
{
|
|
||||||
p = parse_port_config( *i );
|
p = parse_port_config( *i );
|
||||||
if ( p != NULL ) {
|
if (!p) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
p->open();
|
p->open();
|
||||||
io_channels.push_back( p );
|
|
||||||
if ( !p->is_enabled() ) {
|
if ( !p->is_enabled() ) {
|
||||||
SG_LOG( SG_IO, SG_ALERT, "I/O Channel config failed." );
|
SG_LOG( SG_IO, SG_ALERT, "I/O Channel config failed." );
|
||||||
exit(-1);
|
delete p;
|
||||||
}
|
|
||||||
} else {
|
|
||||||
SG_LOG( SG_IO, SG_INFO, "I/O Channel parse failed." );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
io_channels.push_back( p );
|
||||||
|
} // of channel options iteration
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -306,6 +306,7 @@ void fgWarpMouse(int x, int y)
|
||||||
|
|
||||||
void fgOSInit(int* argc, char** argv)
|
void fgOSInit(int* argc, char** argv)
|
||||||
{
|
{
|
||||||
|
globals->get_renderer()->init();
|
||||||
WindowSystemAdapter::setWSA(new WindowSystemAdapter);
|
WindowSystemAdapter::setWSA(new WindowSystemAdapter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -241,6 +241,7 @@ void FGGlobals::set_fg_scenery (const string &scenery)
|
||||||
|
|
||||||
string_list path_list = sgPathSplit( s.str() );
|
string_list path_list = sgPathSplit( s.str() );
|
||||||
fg_scenery.clear();
|
fg_scenery.clear();
|
||||||
|
SGPropertyNode* sim = fgGetNode("/sim", true);
|
||||||
|
|
||||||
for (unsigned i = 0; i < path_list.size(); i++) {
|
for (unsigned i = 0; i < path_list.size(); i++) {
|
||||||
SGPath path(path_list[i]);
|
SGPath path(path_list[i]);
|
||||||
|
@ -271,6 +272,12 @@ void FGGlobals::set_fg_scenery (const string &scenery)
|
||||||
// FG_SCENERY=A:B becomes list ["A/Terrain", "A/Objects", "",
|
// FG_SCENERY=A:B becomes list ["A/Terrain", "A/Objects", "",
|
||||||
// "B/Terrain", "B/Objects", ""]
|
// "B/Terrain", "B/Objects", ""]
|
||||||
fg_scenery.push_back("");
|
fg_scenery.push_back("");
|
||||||
|
|
||||||
|
// make scenery dirs available to Nasal
|
||||||
|
sim->removeChild("fg-scenery", i, false);
|
||||||
|
SGPropertyNode* n = sim->getChild("fg-scenery", i, true);
|
||||||
|
n->setStringValue(path.str());
|
||||||
|
n->setAttribute(SGPropertyNode::WRITE, false);
|
||||||
} // of path list iteration
|
} // of path list iteration
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -203,6 +203,7 @@ static void fgMainLoop( void ) {
|
||||||
if (globals->get_tile_mgr()->isSceneryLoaded()
|
if (globals->get_tile_mgr()->isSceneryLoaded()
|
||||||
&& fgGetBool("sim/fdm-initialized")) {
|
&& fgGetBool("sim/fdm-initialized")) {
|
||||||
fgSetBool("sim/sceneryloaded",true);
|
fgSetBool("sim/sceneryloaded",true);
|
||||||
|
fgSplashProgress("");
|
||||||
if (fgGetBool("/sim/sound/working")) {
|
if (fgGetBool("/sim/sound/working")) {
|
||||||
globals->get_soundmgr()->activate();
|
globals->get_soundmgr()->activate();
|
||||||
}
|
}
|
||||||
|
@ -211,6 +212,7 @@ static void fgMainLoop( void ) {
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
fgSplashProgress("loading scenery");
|
||||||
// be nice to loader threads while waiting for initial scenery, reduce to 2fps
|
// be nice to loader threads while waiting for initial scenery, reduce to 2fps
|
||||||
simgear::sleepForMSec(500);
|
simgear::sleepForMSec(500);
|
||||||
}
|
}
|
||||||
|
@ -313,7 +315,7 @@ SGPath resolve_path(const std::string& s)
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is the top level master main function that is registered as
|
// This is the top level master main function that is registered as
|
||||||
// our idle funciton
|
// our idle function
|
||||||
|
|
||||||
// The first few passes take care of initialization things (a couple
|
// The first few passes take care of initialization things (a couple
|
||||||
// per pass) and once everything has been initialized fgMainLoop from
|
// per pass) and once everything has been initialized fgMainLoop from
|
||||||
|
@ -347,20 +349,17 @@ static void fgIdleFunction ( void ) {
|
||||||
if (!guiFinishInit())
|
if (!guiFinishInit())
|
||||||
return;
|
return;
|
||||||
idle_state++;
|
idle_state++;
|
||||||
fgSplashProgress("reading aircraft list");
|
fgSplashProgress("loading aircraft list");
|
||||||
|
|
||||||
|
|
||||||
} else if ( idle_state == 2 ) {
|
} else if ( idle_state == 2 ) {
|
||||||
idle_state++;
|
idle_state++;
|
||||||
|
fgSplashProgress("loading navigation data");
|
||||||
fgSplashProgress("reading airport & navigation data");
|
|
||||||
|
|
||||||
|
|
||||||
} else if ( idle_state == 3 ) {
|
} else if ( idle_state == 3 ) {
|
||||||
idle_state++;
|
idle_state++;
|
||||||
fgInitNav();
|
fgInitNav();
|
||||||
fgSplashProgress("setting up scenery");
|
|
||||||
|
|
||||||
|
fgSplashProgress("initializing scenery system");
|
||||||
|
|
||||||
} else if ( idle_state == 4 ) {
|
} else if ( idle_state == 4 ) {
|
||||||
idle_state++;
|
idle_state++;
|
||||||
|
@ -385,7 +384,6 @@ static void fgIdleFunction ( void ) {
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
fgInitCommands();
|
fgInitCommands();
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Initialize the material manager
|
// Initialize the material manager
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
|
@ -401,15 +399,12 @@ static void fgIdleFunction ( void ) {
|
||||||
globals->get_scenery()->bind();
|
globals->get_scenery()->bind();
|
||||||
globals->set_tile_mgr( new FGTileMgr );
|
globals->set_tile_mgr( new FGTileMgr );
|
||||||
|
|
||||||
|
|
||||||
fgSplashProgress("loading aircraft");
|
fgSplashProgress("loading aircraft");
|
||||||
|
|
||||||
|
|
||||||
} else if ( idle_state == 5 ) {
|
} else if ( idle_state == 5 ) {
|
||||||
idle_state++;
|
idle_state++;
|
||||||
|
|
||||||
fgSplashProgress("generating sky elements");
|
fgSplashProgress("initializing sky elements");
|
||||||
|
|
||||||
|
|
||||||
} else if ( idle_state == 6 ) {
|
} else if ( idle_state == 6 ) {
|
||||||
idle_state++;
|
idle_state++;
|
||||||
|
@ -470,10 +465,8 @@ static void fgIdleFunction ( void ) {
|
||||||
// airport->setName( "Airport Lighting" );
|
// airport->setName( "Airport Lighting" );
|
||||||
// lighting->addKid( airport );
|
// lighting->addKid( airport );
|
||||||
|
|
||||||
// build our custom render states
|
|
||||||
fgSplashProgress("initializing subsystems");
|
fgSplashProgress("initializing subsystems");
|
||||||
|
|
||||||
|
|
||||||
} else if ( idle_state == 7 ) {
|
} else if ( idle_state == 7 ) {
|
||||||
idle_state++;
|
idle_state++;
|
||||||
// Initialize audio support
|
// Initialize audio support
|
||||||
|
@ -530,18 +523,18 @@ static void fgIdleFunction ( void ) {
|
||||||
fgSetPosFromAirportIDandHdg( apt, hdg );
|
fgSetPosFromAirportIDandHdg( apt, hdg );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fgSplashProgress("setting up time & renderer");
|
|
||||||
|
fgSplashProgress("initializing graphics engine");
|
||||||
|
|
||||||
} else if ( idle_state == 8 ) {
|
} else if ( idle_state == 8 ) {
|
||||||
idle_state = 1000;
|
idle_state = 1000;
|
||||||
|
|
||||||
// setup OpenGL view parameters
|
// setup OpenGL view parameters
|
||||||
globals->get_renderer()->init();
|
globals->get_renderer()->setupView();
|
||||||
|
|
||||||
globals->get_renderer()->resize( fgGetInt("/sim/startup/xsize"),
|
globals->get_renderer()->resize( fgGetInt("/sim/startup/xsize"),
|
||||||
fgGetInt("/sim/startup/ysize") );
|
fgGetInt("/sim/startup/ysize") );
|
||||||
|
|
||||||
fgSplashProgress("loading scenery objects");
|
|
||||||
int session = fgGetInt("/sim/session",0);
|
int session = fgGetInt("/sim/session",0);
|
||||||
session++;
|
session++;
|
||||||
fgSetInt("/sim/session",session);
|
fgSetInt("/sim/session",session);
|
||||||
|
@ -555,6 +548,10 @@ static void fgIdleFunction ( void ) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void fgWinResizeFunction(int width, int height)
|
||||||
|
{
|
||||||
|
globals->get_renderer()->resize(width, height);
|
||||||
|
}
|
||||||
|
|
||||||
static void upper_case_property(const char *name)
|
static void upper_case_property(const char *name)
|
||||||
{
|
{
|
||||||
|
@ -644,7 +641,7 @@ int fgMainInit( int argc, char **argv ) {
|
||||||
fgOSInit(&argc, argv);
|
fgOSInit(&argc, argv);
|
||||||
_bootstrap_OSInit++;
|
_bootstrap_OSInit++;
|
||||||
|
|
||||||
fgRegisterWindowResizeHandler( &FGRenderer::resize );
|
fgRegisterWindowResizeHandler( &fgWinResizeFunction );
|
||||||
fgRegisterIdleHandler( &fgIdleFunction );
|
fgRegisterIdleHandler( &fgIdleFunction );
|
||||||
fgRegisterDrawHandler( &FGRenderer::update );
|
fgRegisterDrawHandler( &FGRenderer::update );
|
||||||
|
|
||||||
|
@ -668,5 +665,3 @@ int fgMainInit( int argc, char **argv ) {
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -555,54 +555,6 @@ add_channel( const string& type, const string& channel_str ) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// The parse wp and parse flight-plan options don't work anymore, because
|
|
||||||
// the route manager and the airport subsystems have not yet been initialized
|
|
||||||
// at this stage.
|
|
||||||
|
|
||||||
// Parse --wp=ID[@alt]
|
|
||||||
static void
|
|
||||||
parse_wp( const string& arg ) {
|
|
||||||
string_list *waypoints = globals->get_initial_waypoints();
|
|
||||||
if (!waypoints) {
|
|
||||||
waypoints = new string_list;
|
|
||||||
globals->set_initial_waypoints(waypoints);
|
|
||||||
}
|
|
||||||
waypoints->push_back(arg);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Parse --flight-plan=[file]
|
|
||||||
static bool
|
|
||||||
parse_flightplan(const string& arg)
|
|
||||||
{
|
|
||||||
string_list *waypoints = globals->get_initial_waypoints();
|
|
||||||
if (!waypoints) {
|
|
||||||
waypoints = new string_list;
|
|
||||||
globals->set_initial_waypoints(waypoints);
|
|
||||||
}
|
|
||||||
|
|
||||||
sg_gzifstream in(arg.c_str());
|
|
||||||
if ( !in.is_open() )
|
|
||||||
return false;
|
|
||||||
|
|
||||||
while ( true ) {
|
|
||||||
string line;
|
|
||||||
getline( in, line, '\n' );
|
|
||||||
|
|
||||||
// catch extraneous (DOS) line ending character
|
|
||||||
if ( line[line.length() - 1] < 32 )
|
|
||||||
line = line.substr( 0, line.length()-1 );
|
|
||||||
|
|
||||||
if ( in.eof() )
|
|
||||||
break;
|
|
||||||
|
|
||||||
waypoints->push_back(line);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
fgOptLanguage( const char *arg )
|
fgOptLanguage( const char *arg )
|
||||||
{
|
{
|
||||||
|
@ -1067,14 +1019,12 @@ fgOptCeiling( const char *arg )
|
||||||
static int
|
static int
|
||||||
fgOptWp( const char *arg )
|
fgOptWp( const char *arg )
|
||||||
{
|
{
|
||||||
parse_wp( arg );
|
string_list *waypoints = globals->get_initial_waypoints();
|
||||||
return FG_OPTIONS_OK;
|
if (!waypoints) {
|
||||||
}
|
waypoints = new string_list;
|
||||||
|
globals->set_initial_waypoints(waypoints);
|
||||||
static int
|
}
|
||||||
fgOptFlightPlan( const char *arg )
|
waypoints->push_back(arg);
|
||||||
{
|
|
||||||
parse_flightplan ( arg );
|
|
||||||
return FG_OPTIONS_OK;
|
return FG_OPTIONS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1467,6 +1417,8 @@ struct OptionDesc {
|
||||||
{"opengc", true, OPTION_CHANNEL, "", false, "", 0 },
|
{"opengc", true, OPTION_CHANNEL, "", false, "", 0 },
|
||||||
{"AV400", true, OPTION_CHANNEL, "", false, "", 0 },
|
{"AV400", true, OPTION_CHANNEL, "", false, "", 0 },
|
||||||
{"AV400Sim", true, OPTION_CHANNEL, "", false, "", 0 },
|
{"AV400Sim", true, OPTION_CHANNEL, "", false, "", 0 },
|
||||||
|
{"AV400WSimA", true, OPTION_CHANNEL, "", false, "", 0 },
|
||||||
|
{"AV400WSimB", true, OPTION_CHANNEL, "", false, "", 0 },
|
||||||
{"garmin", true, OPTION_CHANNEL, "", false, "", 0 },
|
{"garmin", true, OPTION_CHANNEL, "", false, "", 0 },
|
||||||
{"nmea", true, OPTION_CHANNEL, "", false, "", 0 },
|
{"nmea", true, OPTION_CHANNEL, "", false, "", 0 },
|
||||||
{"generic", true, OPTION_CHANNEL, "", false, "", 0 },
|
{"generic", true, OPTION_CHANNEL, "", false, "", 0 },
|
||||||
|
@ -1494,7 +1446,7 @@ struct OptionDesc {
|
||||||
{"turbulence", true, OPTION_FUNC, "", false, "", fgOptTurbulence },
|
{"turbulence", true, OPTION_FUNC, "", false, "", fgOptTurbulence },
|
||||||
{"ceiling", true, OPTION_FUNC, "", false, "", fgOptCeiling },
|
{"ceiling", true, OPTION_FUNC, "", false, "", fgOptCeiling },
|
||||||
{"wp", true, OPTION_FUNC, "", false, "", fgOptWp },
|
{"wp", true, OPTION_FUNC, "", false, "", fgOptWp },
|
||||||
{"flight-plan", true, OPTION_FUNC, "", false, "", fgOptFlightPlan },
|
{"flight-plan", true, OPTION_STRING, "/autopilot/route-manager/file-path", false, "", NULL },
|
||||||
{"config", true, OPTION_FUNC, "", false, "", fgOptConfig },
|
{"config", true, OPTION_FUNC, "", false, "", fgOptConfig },
|
||||||
{"aircraft", true, OPTION_STRING, "/sim/aircraft", false, "", 0 },
|
{"aircraft", true, OPTION_STRING, "/sim/aircraft", false, "", 0 },
|
||||||
{"vehicle", true, OPTION_STRING, "/sim/aircraft", false, "", 0 },
|
{"vehicle", true, OPTION_STRING, "/sim/aircraft", false, "", 0 },
|
||||||
|
@ -1886,7 +1838,7 @@ fgUsage (bool verbose)
|
||||||
|
|
||||||
while ( t_str.size() > 47 ) {
|
while ( t_str.size() > 47 ) {
|
||||||
|
|
||||||
unsigned int m = t_str.rfind(' ', 47);
|
string::size_type m = t_str.rfind(' ', 47);
|
||||||
msg += t_str.substr(0, m) + '\n';
|
msg += t_str.substr(0, m) + '\n';
|
||||||
msg.append( 32, ' ');
|
msg.append( 32, ' ');
|
||||||
|
|
||||||
|
|
|
@ -82,8 +82,6 @@
|
||||||
#include <simgear/screen/jpgfactory.hxx>
|
#include <simgear/screen/jpgfactory.hxx>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <simgear/environment/visual_enviro.hxx>
|
|
||||||
|
|
||||||
#include <Time/light.hxx>
|
#include <Time/light.hxx>
|
||||||
#include <Time/light.hxx>
|
#include <Time/light.hxx>
|
||||||
#include <Cockpit/panel.hxx>
|
#include <Cockpit/panel.hxx>
|
||||||
|
@ -130,7 +128,7 @@ public:
|
||||||
hint->setMode(GL_DONT_CARE);
|
hint->setMode(GL_DONT_CARE);
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
SGSharedPtr<SGPropertyNode> mConfigNode;
|
SGPropertyNode_ptr mConfigNode;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -274,7 +272,7 @@ private:
|
||||||
class FGWireFrameModeUpdateCallback : public osg::StateAttribute::Callback {
|
class FGWireFrameModeUpdateCallback : public osg::StateAttribute::Callback {
|
||||||
public:
|
public:
|
||||||
FGWireFrameModeUpdateCallback() :
|
FGWireFrameModeUpdateCallback() :
|
||||||
mWireframe(fgGetNode("/sim/rendering/wireframe"))
|
mWireframe(fgGetNode("/sim/rendering/wireframe", true))
|
||||||
{ }
|
{ }
|
||||||
virtual void operator()(osg::StateAttribute* stateAttribute,
|
virtual void operator()(osg::StateAttribute* stateAttribute,
|
||||||
osg::NodeVisitor*)
|
osg::NodeVisitor*)
|
||||||
|
@ -291,13 +289,13 @@ public:
|
||||||
osg::PolygonMode::FILL);
|
osg::PolygonMode::FILL);
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
SGSharedPtr<SGPropertyNode> mWireframe;
|
SGPropertyNode_ptr mWireframe;
|
||||||
};
|
};
|
||||||
|
|
||||||
class FGLightModelUpdateCallback : public osg::StateAttribute::Callback {
|
class FGLightModelUpdateCallback : public osg::StateAttribute::Callback {
|
||||||
public:
|
public:
|
||||||
FGLightModelUpdateCallback() :
|
FGLightModelUpdateCallback() :
|
||||||
mHighlights(fgGetNode("/sim/rendering/specular-highlight"))
|
mHighlights(fgGetNode("/sim/rendering/specular-highlight", true))
|
||||||
{ }
|
{ }
|
||||||
virtual void operator()(osg::StateAttribute* stateAttribute,
|
virtual void operator()(osg::StateAttribute* stateAttribute,
|
||||||
osg::NodeVisitor*)
|
osg::NodeVisitor*)
|
||||||
|
@ -322,13 +320,13 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
SGSharedPtr<SGPropertyNode> mHighlights;
|
SGPropertyNode_ptr mHighlights;
|
||||||
};
|
};
|
||||||
|
|
||||||
class FGFogEnableUpdateCallback : public osg::StateSet::Callback {
|
class FGFogEnableUpdateCallback : public osg::StateSet::Callback {
|
||||||
public:
|
public:
|
||||||
FGFogEnableUpdateCallback() :
|
FGFogEnableUpdateCallback() :
|
||||||
mFogEnabled(fgGetNode("/sim/rendering/fog"))
|
mFogEnabled(fgGetNode("/sim/rendering/fog", true))
|
||||||
{ }
|
{ }
|
||||||
virtual void operator()(osg::StateSet* stateSet, osg::NodeVisitor*)
|
virtual void operator()(osg::StateSet* stateSet, osg::NodeVisitor*)
|
||||||
{
|
{
|
||||||
|
@ -339,7 +337,7 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
SGSharedPtr<SGPropertyNode> mFogEnabled;
|
SGPropertyNode_ptr mFogEnabled;
|
||||||
};
|
};
|
||||||
|
|
||||||
class FGFogUpdateCallback : public osg::StateAttribute::Callback {
|
class FGFogUpdateCallback : public osg::StateAttribute::Callback {
|
||||||
|
@ -364,15 +362,18 @@ public:
|
||||||
assert(dynamic_cast<osg::Switch*>(node));
|
assert(dynamic_cast<osg::Switch*>(node));
|
||||||
osg::Switch* sw = static_cast<osg::Switch*>(node);
|
osg::Switch* sw = static_cast<osg::Switch*>(node);
|
||||||
|
|
||||||
double t = globals->get_sim_time_sec();
|
bool enabled = scenery_enabled;
|
||||||
bool enabled = 0 < t;
|
|
||||||
sw->setValue(0, enabled);
|
sw->setValue(0, enabled);
|
||||||
if (!enabled)
|
if (!enabled)
|
||||||
return;
|
return;
|
||||||
traverse(node, nv);
|
traverse(node, nv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool scenery_enabled;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
bool FGScenerySwitchCallback::scenery_enabled = false;
|
||||||
|
|
||||||
// Sky structures
|
// Sky structures
|
||||||
SGSky *thesky;
|
SGSky *thesky;
|
||||||
|
|
||||||
|
@ -411,10 +412,38 @@ FGRenderer::splashinit( void ) {
|
||||||
// visitor automatically.
|
// visitor automatically.
|
||||||
mUpdateVisitor->setFrameStamp(mFrameStamp.get());
|
mUpdateVisitor->setFrameStamp(mFrameStamp.get());
|
||||||
viewer->setUpdateVisitor(mUpdateVisitor.get());
|
viewer->setUpdateVisitor(mUpdateVisitor.get());
|
||||||
|
fgSetDouble("/sim/startup/splash-alpha", 1.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
FGRenderer::init( void )
|
FGRenderer::init( void )
|
||||||
|
{
|
||||||
|
_scenery_loaded = fgGetNode("/sim/sceneryloaded", true);
|
||||||
|
_scenery_override = fgGetNode("/sim/sceneryloaded-override", true);
|
||||||
|
_panel_hotspots = fgGetNode("/sim/panel-hotspots", true);
|
||||||
|
_virtual_cockpit = fgGetNode("/sim/virtual-cockpit", true);
|
||||||
|
|
||||||
|
_sim_delta_sec = fgGetNode("/sim/time/delta-sec", true);
|
||||||
|
|
||||||
|
_xsize = fgGetNode("/sim/startup/xsize", true);
|
||||||
|
_ysize = fgGetNode("/sim/startup/ysize", true);
|
||||||
|
_splash_alpha = fgGetNode("/sim/startup/splash-alpha", true);
|
||||||
|
|
||||||
|
_skyblend = fgGetNode("/sim/rendering/skyblend", true);
|
||||||
|
_point_sprites = fgGetNode("/sim/rendering/point-sprites", true);
|
||||||
|
_enhanced_lighting = fgGetNode("/sim/rendering/enhanced-lighting", true);
|
||||||
|
_distance_attenuation = fgGetNode("/sim/rendering/distance-attenuation", true);
|
||||||
|
_horizon_effect = fgGetNode("/sim/rendering/horizon-effect", true);
|
||||||
|
_textures = fgGetNode("/sim/rendering/textures", true);
|
||||||
|
|
||||||
|
_altitude_ft = fgGetNode("/position/altitude-ft", true);
|
||||||
|
|
||||||
|
_cloud_status = fgGetNode("/environment/clouds/status", true);
|
||||||
|
_visibility_m = fgGetNode("/environment/visibility-m", true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
FGRenderer::setupView( void )
|
||||||
{
|
{
|
||||||
osgViewer::Viewer* viewer = globals->get_renderer()->getViewer();
|
osgViewer::Viewer* viewer = globals->get_renderer()->getViewer();
|
||||||
osg::initNotifyLevel();
|
osg::initNotifyLevel();
|
||||||
|
@ -559,27 +588,42 @@ FGRenderer::init( void )
|
||||||
stateSet->setAttributeAndModes(new osg::Program, osg::StateAttribute::ON);
|
stateSet->setAttributeAndModes(new osg::Program, osg::StateAttribute::ON);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
FGRenderer::update()
|
||||||
|
{
|
||||||
|
globals->get_renderer()->update(true);
|
||||||
|
}
|
||||||
|
|
||||||
// Update all Visuals (redraws anything graphics related)
|
// Update all Visuals (redraws anything graphics related)
|
||||||
void
|
void
|
||||||
FGRenderer::update( bool refresh_camera_settings ) {
|
FGRenderer::update( bool refresh_camera_settings ) {
|
||||||
bool scenery_loaded = fgGetBool("sim/sceneryloaded", false)
|
if (!(_scenery_loaded->getBoolValue() ||
|
||||||
|| fgGetBool("sim/sceneryloaded-override");
|
_scenery_override->getBoolValue()))
|
||||||
osgViewer::Viewer* viewer = globals->get_renderer()->getViewer();
|
{
|
||||||
if (!scenery_loaded) {
|
_splash_alpha->setDoubleValue(1.0);
|
||||||
fgSetDouble("/sim/startup/splash-alpha", 1.0);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
osgViewer::Viewer* viewer = globals->get_renderer()->getViewer();
|
||||||
|
|
||||||
// Fade out the splash screen over the first three seconds.
|
if (_splash_alpha->getDoubleValue()>0.0)
|
||||||
double sAlpha = SGMiscd::max(0, (2.5 - globals->get_sim_time_sec()) / 2.5);
|
{
|
||||||
fgSetDouble("/sim/startup/splash-alpha", sAlpha);
|
// Fade out the splash screen
|
||||||
|
const double fade_time = 0.8;
|
||||||
|
const double fade_steps_per_sec = 20;
|
||||||
|
double delay_time = SGMiscd::min(fade_time/fade_steps_per_sec,
|
||||||
|
(SGTimeStamp::now() - _splash_time).toSecs());
|
||||||
|
_splash_time = SGTimeStamp::now();
|
||||||
|
double sAlpha = _splash_alpha->getDoubleValue();
|
||||||
|
sAlpha -= SGMiscd::max(0.0,delay_time/fade_time);
|
||||||
|
FGScenerySwitchCallback::scenery_enabled = (sAlpha<1.0);
|
||||||
|
_splash_alpha->setDoubleValue(sAlpha);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool skyblend = _skyblend->getBoolValue();
|
||||||
|
bool use_point_sprites = _point_sprites->getBoolValue();
|
||||||
|
bool enhanced_lighting = _enhanced_lighting->getBoolValue();
|
||||||
|
bool distance_attenuation = _distance_attenuation->getBoolValue();
|
||||||
|
|
||||||
bool skyblend = fgGetBool("/sim/rendering/skyblend");
|
|
||||||
bool use_point_sprites = fgGetBool("/sim/rendering/point-sprites");
|
|
||||||
bool enhanced_lighting = fgGetBool("/sim/rendering/enhanced-lighting");
|
|
||||||
bool distance_attenuation
|
|
||||||
= fgGetBool("/sim/rendering/distance-attenuation");
|
|
||||||
// OSGFIXME
|
// OSGFIXME
|
||||||
SGConfigureDirectionalLights( use_point_sprites, enhanced_lighting,
|
SGConfigureDirectionalLights( use_point_sprites, enhanced_lighting,
|
||||||
distance_attenuation );
|
distance_attenuation );
|
||||||
|
@ -588,10 +632,10 @@ FGRenderer::update( bool refresh_camera_settings ) {
|
||||||
|
|
||||||
// update fog params
|
// update fog params
|
||||||
double actual_visibility;
|
double actual_visibility;
|
||||||
if (fgGetBool("/environment/clouds/status")) {
|
if (_cloud_status->getBoolValue()) {
|
||||||
actual_visibility = thesky->get_visibility();
|
actual_visibility = thesky->get_visibility();
|
||||||
} else {
|
} else {
|
||||||
actual_visibility = fgGetDouble("/environment/visibility-m");
|
actual_visibility = _visibility_m->getDoubleValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
// idle_state is now 1000 meaning we've finished all our
|
// idle_state is now 1000 meaning we've finished all our
|
||||||
|
@ -604,27 +648,27 @@ FGRenderer::update( bool refresh_camera_settings ) {
|
||||||
|
|
||||||
if ( refresh_camera_settings ) {
|
if ( refresh_camera_settings ) {
|
||||||
// update view port
|
// update view port
|
||||||
resize( fgGetInt("/sim/startup/xsize"),
|
resize( _xsize->getIntValue(),
|
||||||
fgGetInt("/sim/startup/ysize") );
|
_ysize->getIntValue() );
|
||||||
}
|
}
|
||||||
osg::Camera *camera = viewer->getCamera();
|
osg::Camera *camera = viewer->getCamera();
|
||||||
|
|
||||||
if ( skyblend ) {
|
if ( skyblend ) {
|
||||||
|
|
||||||
if ( fgGetBool("/sim/rendering/textures") ) {
|
if ( _textures->getBoolValue() ) {
|
||||||
SGVec4f clearColor(l->adj_fog_color());
|
SGVec4f clearColor(l->adj_fog_color());
|
||||||
camera->setClearColor(osg::Vec4(0.0, 0.0, 0.0, 1.0));
|
camera->setClearColor(toOsg(clearColor));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
SGVec4f clearColor(l->sky_color());
|
SGVec4f clearColor(l->sky_color());
|
||||||
camera->setClearColor(osg::Vec4(0.0, 0.0, 0.0, 1.0));
|
camera->setClearColor(toOsg(clearColor));
|
||||||
}
|
}
|
||||||
|
|
||||||
// update fog params if visibility has changed
|
// update fog params if visibility has changed
|
||||||
double visibility_meters = fgGetDouble("/environment/visibility-m");
|
double visibility_meters = _visibility_m->getDoubleValue();
|
||||||
thesky->set_visibility(visibility_meters);
|
thesky->set_visibility(visibility_meters);
|
||||||
|
|
||||||
double altitude_m = fgGetDouble("/position/altitude-ft") * SG_FEET_TO_METER;
|
double altitude_m = _altitude_ft->getDoubleValue() * SG_FEET_TO_METER;
|
||||||
thesky->modify_vis( altitude_m, 0.0 /* time factor, now unused */);
|
thesky->modify_vis( altitude_m, 0.0 /* time factor, now unused */);
|
||||||
|
|
||||||
// update the sky dome
|
// update the sky dome
|
||||||
|
@ -637,7 +681,7 @@ FGRenderer::update( bool refresh_camera_settings ) {
|
||||||
// Sun distance: 150,000,000 kilometers
|
// Sun distance: 150,000,000 kilometers
|
||||||
|
|
||||||
double sun_horiz_eff, moon_horiz_eff;
|
double sun_horiz_eff, moon_horiz_eff;
|
||||||
if (fgGetBool("/sim/rendering/horizon-effect")) {
|
if (_horizon_effect->getBoolValue()) {
|
||||||
sun_horiz_eff
|
sun_horiz_eff
|
||||||
= 0.67 + pow(osg::clampAbove(0.5 + cos(l->get_sun_angle()),
|
= 0.67 + pow(osg::clampAbove(0.5 + cos(l->get_sun_angle()),
|
||||||
0.0),
|
0.0),
|
||||||
|
@ -668,7 +712,7 @@ FGRenderer::update( bool refresh_camera_settings ) {
|
||||||
scolor.sun_angle = l->get_sun_angle();
|
scolor.sun_angle = l->get_sun_angle();
|
||||||
scolor.moon_angle = l->get_moon_angle();
|
scolor.moon_angle = l->get_moon_angle();
|
||||||
|
|
||||||
double delta_time_sec = fgGetDouble("/sim/time/delta-sec");
|
double delta_time_sec = _sim_delta_sec->getDoubleValue();
|
||||||
thesky->reposition( sstate, *globals->get_ephem(), delta_time_sec );
|
thesky->reposition( sstate, *globals->get_ephem(), delta_time_sec );
|
||||||
thesky->repaint( scolor, *globals->get_ephem() );
|
thesky->repaint( scolor, *globals->get_ephem() );
|
||||||
|
|
||||||
|
@ -714,11 +758,10 @@ FGRenderer::update( bool refresh_camera_settings ) {
|
||||||
l->get_sun_angle()*SGD_RADIANS_TO_DEGREES);
|
l->get_sun_angle()*SGD_RADIANS_TO_DEGREES);
|
||||||
mUpdateVisitor->setVisibility(actual_visibility);
|
mUpdateVisitor->setVisibility(actual_visibility);
|
||||||
simgear::GroundLightManager::instance()->update(mUpdateVisitor.get());
|
simgear::GroundLightManager::instance()->update(mUpdateVisitor.get());
|
||||||
bool hotspots = fgGetBool("/sim/panel-hotspots");
|
|
||||||
osg::Node::NodeMask cullMask = ~simgear::LIGHTS_BITS & ~simgear::PICK_BIT;
|
osg::Node::NodeMask cullMask = ~simgear::LIGHTS_BITS & ~simgear::PICK_BIT;
|
||||||
cullMask |= simgear::GroundLightManager::instance()
|
cullMask |= simgear::GroundLightManager::instance()
|
||||||
->getLightNodeMask(mUpdateVisitor.get());
|
->getLightNodeMask(mUpdateVisitor.get());
|
||||||
if (hotspots)
|
if (_panel_hotspots->getBoolValue())
|
||||||
cullMask |= simgear::PICK_BIT;
|
cullMask |= simgear::PICK_BIT;
|
||||||
CameraGroup::getDefault()->setCameraCullMasks(cullMask);
|
CameraGroup::getDefault()->setCameraCullMasks(cullMask);
|
||||||
}
|
}
|
||||||
|
@ -729,29 +772,33 @@ FGRenderer::update( bool refresh_camera_settings ) {
|
||||||
// Handle new window size or exposure
|
// Handle new window size or exposure
|
||||||
void
|
void
|
||||||
FGRenderer::resize( int width, int height ) {
|
FGRenderer::resize( int width, int height ) {
|
||||||
int view_h;
|
|
||||||
|
|
||||||
if ( (!fgGetBool("/sim/virtual-cockpit"))
|
// the following breaks aspect-ratio of the main 3D scenery window when 2D panels are moved
|
||||||
&& fgPanelVisible() && idle_state == 1000 ) {
|
// in y direction - causing issues for aircraft with 2D panels (/sim/virtual_cockpit=false).
|
||||||
view_h = (int)(height * (globals->get_current_panel()->getViewHeight() -
|
// Disabling for now. Seems this useful for the pre-OSG time only.
|
||||||
globals->get_current_panel()->getYOffset()) / 768.0);
|
// if ( (!_virtual_cockpit->getBoolValue())
|
||||||
} else {
|
// && fgPanelVisible() && idle_state == 1000 ) {
|
||||||
view_h = height;
|
// view_h = (int)(height * (globals->get_current_panel()->getViewHeight() -
|
||||||
|
// globals->get_current_panel()->getYOffset()) / 768.0);
|
||||||
|
// }
|
||||||
|
|
||||||
|
int curWidth = _xsize->getIntValue(),
|
||||||
|
curHeight = _ysize->getIntValue();
|
||||||
|
if ((curHeight != height) || (curWidth != width)) {
|
||||||
|
// must guard setting these, or PLIB-PUI fails with too many live interfaces
|
||||||
|
_xsize->setIntValue(width);
|
||||||
|
_ysize->setIntValue(height);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int lastwidth = 0;
|
// must set view aspect ratio each frame, or initial values are wrong.
|
||||||
static int lastheight = 0;
|
// should probably be fixed 'smarter' during view setup.
|
||||||
if (width != lastwidth)
|
double aspect = height / (double) width;
|
||||||
fgSetInt("/sim/startup/xsize", lastwidth = width);
|
|
||||||
if (height != lastheight)
|
|
||||||
fgSetInt("/sim/startup/ysize", lastheight = height);
|
|
||||||
|
|
||||||
// for all views
|
// for all views
|
||||||
FGViewMgr *viewmgr = globals->get_viewmgr();
|
FGViewMgr *viewmgr = globals->get_viewmgr();
|
||||||
if (viewmgr) {
|
if (viewmgr) {
|
||||||
for ( int i = 0; i < viewmgr->size(); ++i ) {
|
for ( int i = 0; i < viewmgr->size(); ++i ) {
|
||||||
viewmgr->get_view(i)->
|
viewmgr->get_view(i)->set_aspect_ratio(aspect);
|
||||||
set_aspect_ratio((float)view_h / (float)width);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,8 @@
|
||||||
#define __FG_RENDERER_HXX 1
|
#define __FG_RENDERER_HXX 1
|
||||||
|
|
||||||
#include <simgear/scene/util/SGPickCallback.hxx>
|
#include <simgear/scene/util/SGPickCallback.hxx>
|
||||||
|
#include <simgear/props/props.hxx>
|
||||||
|
#include <simgear/timing/timestamp.hxx>
|
||||||
|
|
||||||
#include <osg/ref_ptr>
|
#include <osg/ref_ptr>
|
||||||
|
|
||||||
|
@ -45,17 +47,19 @@ public:
|
||||||
void splashinit();
|
void splashinit();
|
||||||
void init();
|
void init();
|
||||||
|
|
||||||
static void resize(int width, int height );
|
void setupView();
|
||||||
|
|
||||||
|
void resize(int width, int height );
|
||||||
|
|
||||||
// calling update( refresh_camera_settings = false ) will not
|
// calling update( refresh_camera_settings = false ) will not
|
||||||
// touch window or camera settings. This is useful for the tiled
|
// touch window or camera settings. This is useful for the tiled
|
||||||
// renderer which needs to set the view frustum itself.
|
// renderer which needs to set the view frustum itself.
|
||||||
static void update( bool refresh_camera_settings );
|
void update( bool refresh_camera_settings);
|
||||||
inline static void update() { update( true ); }
|
static void update();
|
||||||
|
|
||||||
/** Just pick into the scene and return the pick callbacks on the way ...
|
/** Just pick into the scene and return the pick callbacks on the way ...
|
||||||
*/
|
*/
|
||||||
static bool pick( std::vector<SGSceneryPick>& pickList,
|
bool pick( std::vector<SGSceneryPick>& pickList,
|
||||||
const osgGA::GUIEventAdapter* ea );
|
const osgGA::GUIEventAdapter* ea );
|
||||||
|
|
||||||
/** Get and set the OSG Viewer object, if any.
|
/** Get and set the OSG Viewer object, if any.
|
||||||
|
@ -76,6 +80,15 @@ public:
|
||||||
protected:
|
protected:
|
||||||
osg::ref_ptr<osgViewer::Viewer> viewer;
|
osg::ref_ptr<osgViewer::Viewer> viewer;
|
||||||
osg::ref_ptr<flightgear::FGEventHandler> eventHandler;
|
osg::ref_ptr<flightgear::FGEventHandler> eventHandler;
|
||||||
|
SGPropertyNode_ptr _scenery_loaded,_scenery_override;
|
||||||
|
SGPropertyNode_ptr _skyblend, _splash_alpha;
|
||||||
|
SGPropertyNode_ptr _point_sprites, _enhanced_lighting, _distance_attenuation;
|
||||||
|
SGPropertyNode_ptr _textures;
|
||||||
|
SGPropertyNode_ptr _cloud_status, _visibility_m;
|
||||||
|
SGPropertyNode_ptr _xsize, _ysize;
|
||||||
|
SGPropertyNode_ptr _panel_hotspots, _sim_delta_sec, _horizon_effect, _altitude_ft;
|
||||||
|
SGPropertyNode_ptr _virtual_cockpit;
|
||||||
|
SGTimeStamp _splash_time;
|
||||||
};
|
};
|
||||||
|
|
||||||
bool fgDumpSceneGraphToFile(const char* filename);
|
bool fgDumpSceneGraphToFile(const char* filename);
|
||||||
|
|
|
@ -295,6 +295,7 @@ static osg::Node* fgCreateSplashCamera()
|
||||||
text->setPosition(osg::Vec3(0, -0.92, 0));
|
text->setPosition(osg::Vec3(0, -0.92, 0));
|
||||||
text->setAlignment(osgText::Text::CENTER_CENTER);
|
text->setAlignment(osgText::Text::CENTER_CENTER);
|
||||||
SGPropertyNode* prop = fgGetNode("/sim/startup/splash-progress-text", true);
|
SGPropertyNode* prop = fgGetNode("/sim/startup/splash-progress-text", true);
|
||||||
|
prop->setStringValue("initializing");
|
||||||
text->setUpdateCallback(new FGSplashTextUpdateCallback(prop));
|
text->setUpdateCallback(new FGSplashTextUpdateCallback(prop));
|
||||||
geode->addDrawable(text);
|
geode->addDrawable(text);
|
||||||
|
|
||||||
|
|
|
@ -356,7 +356,7 @@ FGViewMgr::update (double dt)
|
||||||
abs_viewer_position = loop_view->getViewPosition();
|
abs_viewer_position = loop_view->getViewPosition();
|
||||||
|
|
||||||
// update audio listener values
|
// update audio listener values
|
||||||
// set the viewer posotion in Cartesian coordinates in meters
|
// set the viewer position in Cartesian coordinates in meters
|
||||||
smgr->set_position( abs_viewer_position, loop_view->getPosition() );
|
smgr->set_position( abs_viewer_position, loop_view->getPosition() );
|
||||||
smgr->set_orientation( current_view_orientation );
|
smgr->set_orientation( current_view_orientation );
|
||||||
|
|
||||||
|
|
|
@ -164,7 +164,7 @@ struct FGExternalMotionData {
|
||||||
// the earth centered frame
|
// the earth centered frame
|
||||||
SGVec3f angularAccel;
|
SGVec3f angularAccel;
|
||||||
|
|
||||||
// The set of properties recieved for this timeslot
|
// The set of properties received for this timeslot
|
||||||
std::vector<FGPropertyData*> properties;
|
std::vector<FGPropertyData*> properties;
|
||||||
|
|
||||||
~FGExternalMotionData()
|
~FGExternalMotionData()
|
||||||
|
|
|
@ -42,9 +42,11 @@
|
||||||
#include <simgear/props/props.hxx>
|
#include <simgear/props/props.hxx>
|
||||||
|
|
||||||
#include <AIModel/AIManager.hxx>
|
#include <AIModel/AIManager.hxx>
|
||||||
|
#include <AIModel/AIMultiplayer.hxx>
|
||||||
#include <Main/fg_props.hxx>
|
#include <Main/fg_props.hxx>
|
||||||
#include "multiplaymgr.hxx"
|
#include "multiplaymgr.hxx"
|
||||||
#include "mpmessages.hxx"
|
#include "mpmessages.hxx"
|
||||||
|
#include <FDM/flightProperties.hxx>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
@ -56,11 +58,18 @@ using namespace std;
|
||||||
const char sMULTIPLAYMGR_BID[] = "$Id$";
|
const char sMULTIPLAYMGR_BID[] = "$Id$";
|
||||||
const char sMULTIPLAYMGR_HID[] = MULTIPLAYTXMGR_HID;
|
const char sMULTIPLAYMGR_HID[] = MULTIPLAYTXMGR_HID;
|
||||||
|
|
||||||
|
struct IdPropertyList {
|
||||||
|
unsigned id;
|
||||||
|
const char* name;
|
||||||
|
simgear::props::Type type;
|
||||||
|
};
|
||||||
|
|
||||||
|
static const IdPropertyList* findProperty(unsigned id);
|
||||||
|
|
||||||
// A static map of protocol property id values to property paths,
|
// A static map of protocol property id values to property paths,
|
||||||
// This should be extendable dynamically for every specific aircraft ...
|
// This should be extendable dynamically for every specific aircraft ...
|
||||||
// For now only that static list
|
// For now only that static list
|
||||||
const FGMultiplayMgr::IdPropertyList
|
static const IdPropertyList sIdPropertyList[] = {
|
||||||
FGMultiplayMgr::sIdPropertyList[] = {
|
|
||||||
{100, "surface-positions/left-aileron-pos-norm", simgear::props::FLOAT},
|
{100, "surface-positions/left-aileron-pos-norm", simgear::props::FLOAT},
|
||||||
{101, "surface-positions/right-aileron-pos-norm", simgear::props::FLOAT},
|
{101, "surface-positions/right-aileron-pos-norm", simgear::props::FLOAT},
|
||||||
{102, "surface-positions/elevator-pos-norm", simgear::props::FLOAT},
|
{102, "surface-positions/elevator-pos-norm", simgear::props::FLOAT},
|
||||||
|
@ -229,34 +238,33 @@ FGMultiplayMgr::sIdPropertyList[] = {
|
||||||
{10319, "sim/multiplay/generic/int[19]", simgear::props::INT}
|
{10319, "sim/multiplay/generic/int[19]", simgear::props::INT}
|
||||||
};
|
};
|
||||||
|
|
||||||
const unsigned
|
const unsigned int numProperties = (sizeof(sIdPropertyList)
|
||||||
FGMultiplayMgr::numProperties = (sizeof(FGMultiplayMgr::sIdPropertyList)
|
/ sizeof(sIdPropertyList[0]));
|
||||||
/ sizeof(FGMultiplayMgr::sIdPropertyList[0]));
|
|
||||||
|
|
||||||
// Look up a property ID using binary search.
|
// Look up a property ID using binary search.
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
struct ComparePropertyId
|
struct ComparePropertyId
|
||||||
{
|
{
|
||||||
bool operator()(const FGMultiplayMgr::IdPropertyList& lhs,
|
bool operator()(const IdPropertyList& lhs,
|
||||||
const FGMultiplayMgr::IdPropertyList& rhs)
|
const IdPropertyList& rhs)
|
||||||
{
|
{
|
||||||
return lhs.id < rhs.id;
|
return lhs.id < rhs.id;
|
||||||
}
|
}
|
||||||
bool operator()(const FGMultiplayMgr::IdPropertyList& lhs,
|
bool operator()(const IdPropertyList& lhs,
|
||||||
unsigned id)
|
unsigned id)
|
||||||
{
|
{
|
||||||
return lhs.id < id;
|
return lhs.id < id;
|
||||||
}
|
}
|
||||||
bool operator()(unsigned id,
|
bool operator()(unsigned id,
|
||||||
const FGMultiplayMgr::IdPropertyList& rhs)
|
const IdPropertyList& rhs)
|
||||||
{
|
{
|
||||||
return id < rhs.id;
|
return id < rhs.id;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
const FGMultiplayMgr::IdPropertyList* FGMultiplayMgr::findProperty(unsigned id)
|
|
||||||
|
const IdPropertyList* findProperty(unsigned id)
|
||||||
{
|
{
|
||||||
std::pair<const IdPropertyList*, const IdPropertyList*> result
|
std::pair<const IdPropertyList*, const IdPropertyList*> result
|
||||||
= std::equal_range(sIdPropertyList, sIdPropertyList + numProperties, id,
|
= std::equal_range(sIdPropertyList, sIdPropertyList + numProperties, id,
|
||||||
|
@ -276,8 +284,7 @@ namespace
|
||||||
const xdr_data_t* xdr = data;
|
const xdr_data_t* xdr = data;
|
||||||
while (xdr < end) {
|
while (xdr < end) {
|
||||||
unsigned id = XDR_decode_uint32(*xdr);
|
unsigned id = XDR_decode_uint32(*xdr);
|
||||||
const FGMultiplayMgr::IdPropertyList* plist
|
const IdPropertyList* plist = findProperty(id);
|
||||||
= FGMultiplayMgr::findProperty(id);
|
|
||||||
|
|
||||||
if (plist) {
|
if (plist) {
|
||||||
xdr++;
|
xdr++;
|
||||||
|
@ -336,6 +343,24 @@ namespace
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class MPPropertyListener : public SGPropertyChangeListener
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
MPPropertyListener(FGMultiplayMgr* mp) :
|
||||||
|
_multiplay(mp)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void childAdded(SGPropertyNode*, SGPropertyNode*)
|
||||||
|
{
|
||||||
|
_multiplay->setPropertiesChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
FGMultiplayMgr* _multiplay;
|
||||||
|
};
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
// MultiplayMgr constructor
|
// MultiplayMgr constructor
|
||||||
|
@ -343,9 +368,9 @@ namespace
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
FGMultiplayMgr::FGMultiplayMgr()
|
FGMultiplayMgr::FGMultiplayMgr()
|
||||||
{
|
{
|
||||||
mSocket = 0;
|
|
||||||
mInitialised = false;
|
mInitialised = false;
|
||||||
mHaveServer = false;
|
mHaveServer = false;
|
||||||
|
mListener = NULL;
|
||||||
} // FGMultiplayMgr::FGMultiplayMgr()
|
} // FGMultiplayMgr::FGMultiplayMgr()
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
@ -356,7 +381,7 @@ FGMultiplayMgr::FGMultiplayMgr()
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
FGMultiplayMgr::~FGMultiplayMgr()
|
FGMultiplayMgr::~FGMultiplayMgr()
|
||||||
{
|
{
|
||||||
Close();
|
|
||||||
} // FGMultiplayMgr::~FGMultiplayMgr()
|
} // FGMultiplayMgr::~FGMultiplayMgr()
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
@ -375,22 +400,36 @@ FGMultiplayMgr::init (void)
|
||||||
SG_LOG(SG_NETWORK, SG_WARN, "FGMultiplayMgr::init - already initialised");
|
SG_LOG(SG_NETWORK, SG_WARN, "FGMultiplayMgr::init - already initialised");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fgSetBool("/sim/multiplay/online", false);
|
||||||
|
|
||||||
//////////////////////////////////////////////////
|
//////////////////////////////////////////////////
|
||||||
// Set members from property values
|
// Set members from property values
|
||||||
//////////////////////////////////////////////////
|
//////////////////////////////////////////////////
|
||||||
short rxPort = fgGetInt("/sim/multiplay/rxport");
|
short rxPort = fgGetInt("/sim/multiplay/rxport");
|
||||||
string rxAddress = fgGetString("/sim/multiplay/rxhost");
|
string rxAddress = fgGetString("/sim/multiplay/rxhost");
|
||||||
short txPort = fgGetInt("/sim/multiplay/txport");
|
short txPort = fgGetInt("/sim/multiplay/txport", 5000);
|
||||||
string txAddress = fgGetString("/sim/multiplay/txhost");
|
string txAddress = fgGetString("/sim/multiplay/txhost");
|
||||||
|
|
||||||
|
int hz = fgGetInt("/sim/multiplay/tx-rate-hz", 10);
|
||||||
|
if (hz < 1) {
|
||||||
|
hz = 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
mDt = 1.0 / hz;
|
||||||
|
mTimeUntilSend = 0.0;
|
||||||
|
|
||||||
mCallsign = fgGetString("/sim/multiplay/callsign");
|
mCallsign = fgGetString("/sim/multiplay/callsign");
|
||||||
if (txPort > 0 && !txAddress.empty()) {
|
if (!txAddress.empty()) {
|
||||||
mServer.set(txAddress.c_str(), txPort);
|
mServer.set(txAddress.c_str(), txPort);
|
||||||
if (strncmp (mServer.getHost(), "0.0.0.0", 8) == 0) {
|
if (strncmp (mServer.getHost(), "0.0.0.0", 8) == 0) {
|
||||||
mHaveServer = false;
|
mHaveServer = false;
|
||||||
SG_LOG(SG_NETWORK, SG_DEBUG,
|
SG_LOG(SG_NETWORK, SG_WARN,
|
||||||
"FGMultiplayMgr - could not resolve '"
|
"FGMultiplayMgr - could not resolve '"
|
||||||
<< txAddress << "', Multiplayermode disabled");
|
<< txAddress << "', Multiplayermode disabled");
|
||||||
|
return;
|
||||||
} else {
|
} else {
|
||||||
|
SG_LOG(SG_NETWORK, SG_INFO, "have server");
|
||||||
mHaveServer = true;
|
mHaveServer = true;
|
||||||
}
|
}
|
||||||
if (rxPort <= 0)
|
if (rxPort <= 0)
|
||||||
|
@ -408,11 +447,10 @@ FGMultiplayMgr::init (void)
|
||||||
SG_LOG(SG_NETWORK,SG_INFO,"FGMultiplayMgr::init-rxaddress="<<rxAddress );
|
SG_LOG(SG_NETWORK,SG_INFO,"FGMultiplayMgr::init-rxaddress="<<rxAddress );
|
||||||
SG_LOG(SG_NETWORK,SG_INFO,"FGMultiplayMgr::init-rxport= "<<rxPort);
|
SG_LOG(SG_NETWORK,SG_INFO,"FGMultiplayMgr::init-rxport= "<<rxPort);
|
||||||
SG_LOG(SG_NETWORK,SG_INFO,"FGMultiplayMgr::init-callsign= "<<mCallsign);
|
SG_LOG(SG_NETWORK,SG_INFO,"FGMultiplayMgr::init-callsign= "<<mCallsign);
|
||||||
Close(); // Should Init be called twice, close Socket first
|
|
||||||
// A memory leak was reported here by valgrind
|
mSocket.reset(new simgear::Socket());
|
||||||
mSocket = new simgear::Socket();
|
|
||||||
if (!mSocket->open(false)) {
|
if (!mSocket->open(false)) {
|
||||||
SG_LOG( SG_NETWORK, SG_DEBUG,
|
SG_LOG( SG_NETWORK, SG_WARN,
|
||||||
"FGMultiplayMgr::init - Failed to create data socket" );
|
"FGMultiplayMgr::init - Failed to create data socket" );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -424,6 +462,11 @@ FGMultiplayMgr::init (void)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mPropertiesChanged = true;
|
||||||
|
mListener = new MPPropertyListener(this);
|
||||||
|
globals->get_props()->addChangeListener(mListener, false);
|
||||||
|
|
||||||
|
fgSetBool("/sim/multiplay/online", true);
|
||||||
mInitialised = true;
|
mInitialised = true;
|
||||||
} // FGMultiplayMgr::init()
|
} // FGMultiplayMgr::init()
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
@ -435,19 +478,39 @@ FGMultiplayMgr::init (void)
|
||||||
//
|
//
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
void
|
void
|
||||||
FGMultiplayMgr::Close (void)
|
FGMultiplayMgr::shutdown (void)
|
||||||
{
|
{
|
||||||
|
fgSetBool("/sim/multiplay/online", false);
|
||||||
|
|
||||||
|
if (mSocket.get()) {
|
||||||
|
mSocket->close();
|
||||||
|
mSocket.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
MultiPlayerMap::iterator it = mMultiPlayerMap.begin(),
|
||||||
|
end = mMultiPlayerMap.end();
|
||||||
|
for (; it != end; ++it) {
|
||||||
|
it->second->setDie(true);
|
||||||
|
}
|
||||||
mMultiPlayerMap.clear();
|
mMultiPlayerMap.clear();
|
||||||
|
|
||||||
if (mSocket) {
|
if (mListener) {
|
||||||
mSocket->close();
|
globals->get_props()->removeChangeListener(mListener);
|
||||||
delete mSocket;
|
delete mListener;
|
||||||
mSocket = 0;
|
mListener = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
mInitialised = false;
|
mInitialised = false;
|
||||||
} // FGMultiplayMgr::Close(void)
|
} // FGMultiplayMgr::Close(void)
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void
|
||||||
|
FGMultiplayMgr::reinit()
|
||||||
|
{
|
||||||
|
shutdown();
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
// Description: Sends the position data for the local position.
|
// Description: Sends the position data for the local position.
|
||||||
|
@ -757,7 +820,7 @@ FGMultiplayMgr::SendTextMessage(const string &MsgText)
|
||||||
//
|
//
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
void
|
void
|
||||||
FGMultiplayMgr::update(double)
|
FGMultiplayMgr::update(double dt)
|
||||||
{
|
{
|
||||||
if (!mInitialised)
|
if (!mInitialised)
|
||||||
return;
|
return;
|
||||||
|
@ -765,6 +828,14 @@ FGMultiplayMgr::update(double)
|
||||||
/// Just for expiry
|
/// Just for expiry
|
||||||
long stamp = SGTimeStamp::now().getSeconds();
|
long stamp = SGTimeStamp::now().getSeconds();
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////
|
||||||
|
// Send if required
|
||||||
|
//////////////////////////////////////////////////
|
||||||
|
mTimeUntilSend -= dt;
|
||||||
|
if (mTimeUntilSend <= 0.0) {
|
||||||
|
Send();
|
||||||
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////
|
//////////////////////////////////////////////////
|
||||||
// Read the receive socket and process any data
|
// Read the receive socket and process any data
|
||||||
//////////////////////////////////////////////////
|
//////////////////////////////////////////////////
|
||||||
|
@ -813,7 +884,7 @@ FGMultiplayMgr::update(double)
|
||||||
<< "message has invalid protocol number!" );
|
<< "message has invalid protocol number!" );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (MsgHdr->MsgLen != bytes) {
|
if (static_cast<ssize_t>(MsgHdr->MsgLen) != bytes) {
|
||||||
SG_LOG(SG_NETWORK, SG_DEBUG, "FGMultiplayMgr::MP_ProcessData - "
|
SG_LOG(SG_NETWORK, SG_DEBUG, "FGMultiplayMgr::MP_ProcessData - "
|
||||||
<< "message from " << MsgHdr->Callsign << " has invalid length!");
|
<< "message from " << MsgHdr->Callsign << " has invalid length!");
|
||||||
break;
|
break;
|
||||||
|
@ -854,6 +925,140 @@ FGMultiplayMgr::update(double)
|
||||||
} // FGMultiplayMgr::ProcessData(void)
|
} // FGMultiplayMgr::ProcessData(void)
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void
|
||||||
|
FGMultiplayMgr::Send()
|
||||||
|
{
|
||||||
|
using namespace simgear;
|
||||||
|
|
||||||
|
findProperties();
|
||||||
|
|
||||||
|
// smooth the send rate, by adjusting based on the 'remainder' time, which
|
||||||
|
// is how -ve mTimeUntilSend is. Watch for large values and ignore them,
|
||||||
|
// however.
|
||||||
|
if ((mTimeUntilSend < 0.0) && (fabs(mTimeUntilSend) < mDt)) {
|
||||||
|
mTimeUntilSend = mDt + mTimeUntilSend;
|
||||||
|
} else {
|
||||||
|
mTimeUntilSend = mDt;
|
||||||
|
}
|
||||||
|
|
||||||
|
double sim_time = globals->get_sim_time_sec();
|
||||||
|
static double lastTime = 0.0;
|
||||||
|
|
||||||
|
// SG_LOG(SG_GENERAL, SG_INFO, "actual dt=" << sim_time - lastTime);
|
||||||
|
lastTime = sim_time;
|
||||||
|
|
||||||
|
FlightProperties ifce;
|
||||||
|
|
||||||
|
// put together a motion info struct, you will get that later
|
||||||
|
// from FGInterface directly ...
|
||||||
|
FGExternalMotionData motionInfo;
|
||||||
|
|
||||||
|
// The current simulation time we need to update for,
|
||||||
|
// note that the simulation time is updated before calling all the
|
||||||
|
// update methods. Thus it contains the time intervals *end* time.
|
||||||
|
// The FDM is already run, so the states belong to that time.
|
||||||
|
motionInfo.time = sim_time;
|
||||||
|
motionInfo.lag = mDt;
|
||||||
|
|
||||||
|
// These are for now converted from lat/lon/alt and euler angles.
|
||||||
|
// But this should change in FGInterface ...
|
||||||
|
double lon = ifce.get_Longitude();
|
||||||
|
double lat = ifce.get_Latitude();
|
||||||
|
// first the aprioriate structure for the geodetic one
|
||||||
|
SGGeod geod = SGGeod::fromRadFt(lon, lat, ifce.get_Altitude());
|
||||||
|
// Convert to cartesion coordinate
|
||||||
|
motionInfo.position = SGVec3d::fromGeod(geod);
|
||||||
|
|
||||||
|
// The quaternion rotating from the earth centered frame to the
|
||||||
|
// horizontal local frame
|
||||||
|
SGQuatf qEc2Hl = SGQuatf::fromLonLatRad((float)lon, (float)lat);
|
||||||
|
// The orientation wrt the horizontal local frame
|
||||||
|
float heading = ifce.get_Psi();
|
||||||
|
float pitch = ifce.get_Theta();
|
||||||
|
float roll = ifce.get_Phi();
|
||||||
|
SGQuatf hlOr = SGQuatf::fromYawPitchRoll(heading, pitch, roll);
|
||||||
|
// The orientation of the vehicle wrt the earth centered frame
|
||||||
|
motionInfo.orientation = qEc2Hl*hlOr;
|
||||||
|
|
||||||
|
if (!globals->get_subsystem("flight")->is_suspended()) {
|
||||||
|
// velocities
|
||||||
|
motionInfo.linearVel = SG_FEET_TO_METER*SGVec3f(ifce.get_uBody(),
|
||||||
|
ifce.get_vBody(),
|
||||||
|
ifce.get_wBody());
|
||||||
|
motionInfo.angularVel = SGVec3f(ifce.get_P_body(),
|
||||||
|
ifce.get_Q_body(),
|
||||||
|
ifce.get_R_body());
|
||||||
|
|
||||||
|
// accels, set that to zero for now.
|
||||||
|
// Angular accelerations are missing from the interface anyway,
|
||||||
|
// linear accelerations are screwed up at least for JSBSim.
|
||||||
|
// motionInfo.linearAccel = SG_FEET_TO_METER*SGVec3f(ifce.get_U_dot_body(),
|
||||||
|
// ifce.get_V_dot_body(),
|
||||||
|
// ifce.get_W_dot_body());
|
||||||
|
motionInfo.linearAccel = SGVec3f::zeros();
|
||||||
|
motionInfo.angularAccel = SGVec3f::zeros();
|
||||||
|
} else {
|
||||||
|
// if the interface is suspendend, prevent the client from
|
||||||
|
// wild extrapolations
|
||||||
|
motionInfo.linearVel = SGVec3f::zeros();
|
||||||
|
motionInfo.angularVel = SGVec3f::zeros();
|
||||||
|
motionInfo.linearAccel = SGVec3f::zeros();
|
||||||
|
motionInfo.angularAccel = SGVec3f::zeros();
|
||||||
|
}
|
||||||
|
|
||||||
|
// now send the properties
|
||||||
|
PropertyMap::iterator it;
|
||||||
|
for (it = mPropertyMap.begin(); it != mPropertyMap.end(); ++it) {
|
||||||
|
FGPropertyData* pData = new FGPropertyData;
|
||||||
|
pData->id = it->first;
|
||||||
|
pData->type = it->second->getType();
|
||||||
|
|
||||||
|
switch (pData->type) {
|
||||||
|
case props::INT:
|
||||||
|
case props::LONG:
|
||||||
|
case props::BOOL:
|
||||||
|
pData->int_value = it->second->getIntValue();
|
||||||
|
break;
|
||||||
|
case props::FLOAT:
|
||||||
|
case props::DOUBLE:
|
||||||
|
pData->float_value = it->second->getFloatValue();
|
||||||
|
break;
|
||||||
|
case props::STRING:
|
||||||
|
case props::UNSPECIFIED:
|
||||||
|
{
|
||||||
|
// FIXME: We assume unspecified are strings for the moment.
|
||||||
|
|
||||||
|
const char* cstr = it->second->getStringValue();
|
||||||
|
int len = strlen(cstr);
|
||||||
|
|
||||||
|
if (len > 0)
|
||||||
|
{
|
||||||
|
pData->string_value = new char[len + 1];
|
||||||
|
strcpy(pData->string_value, cstr);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Size 0 - ignore
|
||||||
|
pData->string_value = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//cout << " Sending property " << pData->id << " " << pData->type << " " << pData->string_value << "\n";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
// FIXME Currently default to a float.
|
||||||
|
//cout << "Unknown type when iterating through props: " << pData->type << "\n";
|
||||||
|
pData->float_value = it->second->getFloatValue();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
motionInfo.properties.push_back(pData);
|
||||||
|
}
|
||||||
|
|
||||||
|
SendMyPosition(motionInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
// handle a position message
|
// handle a position message
|
||||||
|
@ -1101,3 +1306,29 @@ FGMultiplayMgr::getMultiplayer(const std::string& callsign)
|
||||||
else
|
else
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
FGMultiplayMgr::findProperties()
|
||||||
|
{
|
||||||
|
if (!mPropertiesChanged) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mPropertiesChanged = false;
|
||||||
|
|
||||||
|
for (unsigned i = 0; i < numProperties; ++i) {
|
||||||
|
const char* name = sIdPropertyList[i].name;
|
||||||
|
SGPropertyNode* pNode = globals->get_props()->getNode(name);
|
||||||
|
if (!pNode) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
int id = sIdPropertyList[i].id;
|
||||||
|
if (mPropertyMap.find(id) != mPropertyMap.end()) {
|
||||||
|
continue; // already activated
|
||||||
|
}
|
||||||
|
|
||||||
|
mPropertyMap[id] = pNode;
|
||||||
|
SG_LOG(SG_NETWORK, SG_DEBUG, "activating MP property:" << pNode->getPath());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -31,48 +31,51 @@
|
||||||
|
|
||||||
#define MULTIPLAYTXMGR_HID "$Id$"
|
#define MULTIPLAYTXMGR_HID "$Id$"
|
||||||
|
|
||||||
#include "mpmessages.hxx"
|
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
#include <simgear/compiler.h>
|
#include <simgear/compiler.h>
|
||||||
#include <simgear/props/props.hxx>
|
#include <simgear/props/props.hxx>
|
||||||
#include <Main/globals.hxx>
|
|
||||||
#include <simgear/io/raw_socket.hxx>
|
#include <simgear/io/raw_socket.hxx>
|
||||||
#include <simgear/structure/subsystem_mgr.hxx>
|
#include <simgear/structure/subsystem_mgr.hxx>
|
||||||
|
|
||||||
#include <AIModel/AIMultiplayer.hxx>
|
struct FGExternalMotionData;
|
||||||
|
class MPPropertyListener;
|
||||||
struct FGExternalMotionInfo;
|
struct T_MsgHdr;
|
||||||
|
class FGAIMultiplayer;
|
||||||
|
|
||||||
class FGMultiplayMgr : public SGSubsystem
|
class FGMultiplayMgr : public SGSubsystem
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
struct IdPropertyList {
|
|
||||||
unsigned id;
|
|
||||||
const char* name;
|
|
||||||
simgear::props::Type type;
|
|
||||||
};
|
|
||||||
static const IdPropertyList sIdPropertyList[];
|
|
||||||
static const unsigned numProperties;
|
|
||||||
|
|
||||||
static const IdPropertyList* findProperty(unsigned id);
|
|
||||||
|
|
||||||
FGMultiplayMgr();
|
FGMultiplayMgr();
|
||||||
~FGMultiplayMgr();
|
~FGMultiplayMgr();
|
||||||
|
|
||||||
virtual void init(void);
|
virtual void init(void);
|
||||||
virtual void update(double dt);
|
virtual void update(double dt);
|
||||||
|
|
||||||
void Close(void);
|
virtual void shutdown(void);
|
||||||
|
virtual void reinit();
|
||||||
|
|
||||||
// transmitter
|
// transmitter
|
||||||
void SendMyPosition(const FGExternalMotionData& motionInfo);
|
|
||||||
void SendTextMessage(const string &sMsgText);
|
void SendTextMessage(const string &sMsgText);
|
||||||
// receiver
|
// receiver
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
friend class MPPropertyListener;
|
||||||
|
|
||||||
|
void setPropertiesChanged()
|
||||||
|
{
|
||||||
|
mPropertiesChanged = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void findProperties();
|
||||||
|
|
||||||
|
void Send();
|
||||||
|
void SendMyPosition(const FGExternalMotionData& motionInfo);
|
||||||
|
|
||||||
union MsgBuf;
|
union MsgBuf;
|
||||||
FGAIMultiplayer* addMultiplayer(const std::string& callsign,
|
FGAIMultiplayer* addMultiplayer(const std::string& callsign,
|
||||||
const std::string& modelName);
|
const std::string& modelName);
|
||||||
|
@ -87,11 +90,22 @@ private:
|
||||||
typedef std::map<std::string, SGSharedPtr<FGAIMultiplayer> > MultiPlayerMap;
|
typedef std::map<std::string, SGSharedPtr<FGAIMultiplayer> > MultiPlayerMap;
|
||||||
MultiPlayerMap mMultiPlayerMap;
|
MultiPlayerMap mMultiPlayerMap;
|
||||||
|
|
||||||
simgear::Socket* mSocket;
|
std::auto_ptr<simgear::Socket> mSocket;
|
||||||
simgear::IPAddress mServer;
|
simgear::IPAddress mServer;
|
||||||
bool mHaveServer;
|
bool mHaveServer;
|
||||||
bool mInitialised;
|
bool mInitialised;
|
||||||
std::string mCallsign;
|
std::string mCallsign;
|
||||||
|
|
||||||
|
// Map between the property id's from the multiplayers network packets
|
||||||
|
// and the property nodes
|
||||||
|
typedef std::map<unsigned int, SGSharedPtr<SGPropertyNode> > PropertyMap;
|
||||||
|
PropertyMap mPropertyMap;
|
||||||
|
|
||||||
|
bool mPropertiesChanged;
|
||||||
|
MPPropertyListener* mListener;
|
||||||
|
|
||||||
|
double mDt; // reciprocal of /sim/multiplay/tx-rate-hz
|
||||||
|
double mTimeUntilSend;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
1046
src/Network/AV400WSim.cxx
Normal file
1046
src/Network/AV400WSim.cxx
Normal file
File diff suppressed because it is too large
Load diff
144
src/Network/AV400WSim.hxx
Normal file
144
src/Network/AV400WSim.hxx
Normal file
|
@ -0,0 +1,144 @@
|
||||||
|
// AV400Sim.hxx -- Garmin 400 series protocal class. This AV400Sim
|
||||||
|
// protocol generates the set of "simulator" commands a garmin 400
|
||||||
|
// series gps would expect as input in simulator mode. The AV400
|
||||||
|
// protocol generates the set of commands that a garmin 400 series gps
|
||||||
|
// would emit.
|
||||||
|
//
|
||||||
|
// Written by Curtis Olson, started Januar 2009.
|
||||||
|
//
|
||||||
|
// Copyright (C) 2009 Curtis L. Olson - http://www.flightgear.org/~curt
|
||||||
|
//
|
||||||
|
// This program is free software; you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU General Public License as
|
||||||
|
// published by 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.
|
||||||
|
//
|
||||||
|
// $Id$
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef _FG_AV400WSIM_HXX
|
||||||
|
#define _FG_AV400WSIM_HXX
|
||||||
|
|
||||||
|
|
||||||
|
#include <simgear/compiler.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "protocol.hxx"
|
||||||
|
|
||||||
|
using std::string;
|
||||||
|
|
||||||
|
class FlightProperties;
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Class FGAV400WSimA handles the input/output over the first serial port.
|
||||||
|
// This is very similar to the way previous Garmin non-WAAS models communicated
|
||||||
|
// but some items have been stripped out and just a minimal amount of
|
||||||
|
// info is necessary to be transmitted over this port.
|
||||||
|
|
||||||
|
class FGAV400WSimA : public FGProtocol {
|
||||||
|
|
||||||
|
char buf[ FG_MAX_MSG_SIZE ];
|
||||||
|
int length;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
FGAV400WSimA();
|
||||||
|
~FGAV400WSimA();
|
||||||
|
|
||||||
|
bool gen_message();
|
||||||
|
bool parse_message();
|
||||||
|
|
||||||
|
// open hailing frequencies
|
||||||
|
bool open();
|
||||||
|
|
||||||
|
// process work for this port
|
||||||
|
bool process();
|
||||||
|
|
||||||
|
// close the channel
|
||||||
|
bool close();
|
||||||
|
};
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Class FGAV400WSimB handles the input/output over the second serial port
|
||||||
|
// which Garmin refers to as the "GPS Port". Some messages are handled on
|
||||||
|
// fixed cycle (usually 1 and 5 Hz) and some immediate responses are needed
|
||||||
|
// to certain messages upon requet by the GPS unit
|
||||||
|
|
||||||
|
class FGAV400WSimB : public FGProtocol {
|
||||||
|
|
||||||
|
char buf[ FG_MAX_MSG_SIZE ];
|
||||||
|
int length;
|
||||||
|
double hz2;
|
||||||
|
int hz2count;
|
||||||
|
int hz2cycles;
|
||||||
|
char flight_phase;
|
||||||
|
string hal;
|
||||||
|
string val;
|
||||||
|
string sbas_sel;
|
||||||
|
bool req_hostid;
|
||||||
|
bool req_raimap;
|
||||||
|
bool req_sbas;
|
||||||
|
int outputctr;
|
||||||
|
|
||||||
|
FlightProperties* fdm;
|
||||||
|
|
||||||
|
static const int SOM_SIZE = 2;
|
||||||
|
static const int DEG_TO_MILLIARCSECS = ( 60.0 * 60.0 * 1000 );
|
||||||
|
|
||||||
|
// Flight Phases
|
||||||
|
static const int PHASE_OCEANIC = 4;
|
||||||
|
static const int PHASE_ENROUTE = 5;
|
||||||
|
static const int PHASE_TERM = 6;
|
||||||
|
static const int PHASE_NONPREC = 7;
|
||||||
|
static const int PHASE_LNAVVNAV = 8;
|
||||||
|
static const int PHASE_LPVLP = 9;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
FGAV400WSimB();
|
||||||
|
~FGAV400WSimB();
|
||||||
|
|
||||||
|
bool gen_hostid_message();
|
||||||
|
bool gen_sbas_message();
|
||||||
|
|
||||||
|
bool gen_Wh_message();
|
||||||
|
bool gen_Wx_message();
|
||||||
|
|
||||||
|
bool gen_Wt_message();
|
||||||
|
bool gen_Wm_message();
|
||||||
|
bool gen_Wv_message();
|
||||||
|
|
||||||
|
bool verify_checksum( string message, int datachars );
|
||||||
|
string asciitize_message( string message );
|
||||||
|
string buffer_to_string();
|
||||||
|
bool parse_message();
|
||||||
|
|
||||||
|
// open hailing frequencies
|
||||||
|
bool open();
|
||||||
|
|
||||||
|
// process work for this port
|
||||||
|
bool process();
|
||||||
|
|
||||||
|
// close the channel
|
||||||
|
bool close();
|
||||||
|
|
||||||
|
inline double get_hz2() const { return hz2; }
|
||||||
|
inline void set_hz2( double t ) { hz2 = t, hz2cycles = get_hz() / hz2; }
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif // _FG_AV400WSIM_HXX
|
|
@ -6,6 +6,7 @@ set(SOURCES
|
||||||
ATC-Outputs.cxx
|
ATC-Outputs.cxx
|
||||||
AV400.cxx
|
AV400.cxx
|
||||||
AV400Sim.cxx
|
AV400Sim.cxx
|
||||||
|
AV400WSim.cxx
|
||||||
atlas.cxx
|
atlas.cxx
|
||||||
garmin.cxx
|
garmin.cxx
|
||||||
generic.cxx
|
generic.cxx
|
||||||
|
@ -14,7 +15,6 @@ set(SOURCES
|
||||||
jpg-httpd.cxx
|
jpg-httpd.cxx
|
||||||
jsclient.cxx
|
jsclient.cxx
|
||||||
lfsglass.cxx
|
lfsglass.cxx
|
||||||
multiplay.cxx
|
|
||||||
native.cxx
|
native.cxx
|
||||||
native_ctrls.cxx
|
native_ctrls.cxx
|
||||||
native_fdm.cxx
|
native_fdm.cxx
|
||||||
|
|
|
@ -9,8 +9,6 @@ else
|
||||||
JPEG_SERVER =
|
JPEG_SERVER =
|
||||||
endif
|
endif
|
||||||
|
|
||||||
MPLAYER_AS = multiplay.cxx multiplay.hxx
|
|
||||||
|
|
||||||
libNetwork_a_SOURCES = \
|
libNetwork_a_SOURCES = \
|
||||||
protocol.cxx protocol.hxx \
|
protocol.cxx protocol.hxx \
|
||||||
ATC-Main.cxx ATC-Main.hxx \
|
ATC-Main.cxx ATC-Main.hxx \
|
||||||
|
@ -19,6 +17,7 @@ libNetwork_a_SOURCES = \
|
||||||
atlas.cxx atlas.hxx \
|
atlas.cxx atlas.hxx \
|
||||||
AV400.cxx AV400.hxx \
|
AV400.cxx AV400.hxx \
|
||||||
AV400Sim.cxx AV400Sim.hxx \
|
AV400Sim.cxx AV400Sim.hxx \
|
||||||
|
AV400WSim.cxx AV400WSim.hxx \
|
||||||
garmin.cxx garmin.hxx \
|
garmin.cxx garmin.hxx \
|
||||||
lfsglass.cxx lfsglass.hxx lfsglass_data.hxx \
|
lfsglass.cxx lfsglass.hxx lfsglass_data.hxx \
|
||||||
httpd.cxx httpd.hxx \
|
httpd.cxx httpd.hxx \
|
||||||
|
@ -32,7 +31,6 @@ libNetwork_a_SOURCES = \
|
||||||
net_ctrls.hxx net_fdm.hxx net_fdm_mini.hxx net_gui.hxx \
|
net_ctrls.hxx net_fdm.hxx net_fdm_mini.hxx net_gui.hxx \
|
||||||
nmea.cxx nmea.hxx \
|
nmea.cxx nmea.hxx \
|
||||||
opengc.cxx opengc.hxx opengc_data.hxx \
|
opengc.cxx opengc.hxx opengc_data.hxx \
|
||||||
$(MPLAYER_AS) \
|
|
||||||
props.cxx props.hxx \
|
props.cxx props.hxx \
|
||||||
pve.cxx pve.hxx \
|
pve.cxx pve.hxx \
|
||||||
ray.cxx ray.hxx \
|
ray.cxx ray.hxx \
|
||||||
|
|
|
@ -1,319 +0,0 @@
|
||||||
// multiplay.cxx -- protocol object for multiplay in Flightgear
|
|
||||||
//
|
|
||||||
// Written by Diarmuid Tyson, started February 2003.
|
|
||||||
// diarmuid.tyson@airservicesaustralia.com
|
|
||||||
//
|
|
||||||
// With addtions by Vivian Meazza, January 2006
|
|
||||||
//
|
|
||||||
// Copyright (C) 2003 Airservices Australia
|
|
||||||
//
|
|
||||||
// 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 <cstring>
|
|
||||||
#include <iostream>
|
|
||||||
#include <map>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
#include <simgear/debug/logstream.hxx>
|
|
||||||
#include <simgear/math/SGMath.hxx>
|
|
||||||
|
|
||||||
#include <FDM/flightProperties.hxx>
|
|
||||||
#include <MultiPlayer/mpmessages.hxx>
|
|
||||||
|
|
||||||
#include "multiplay.hxx"
|
|
||||||
|
|
||||||
using std::string;
|
|
||||||
|
|
||||||
|
|
||||||
// These constants are provided so that the ident command can list file versions.
|
|
||||||
const char sFG_MULTIPLAY_BID[] = "$Id$";
|
|
||||||
const char sFG_MULTIPLAY_HID[] = FG_MULTIPLAY_HID;
|
|
||||||
|
|
||||||
typedef std::set<std::string> string_set;
|
|
||||||
|
|
||||||
class MPPropertyListener : public SGPropertyChangeListener
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
MPPropertyListener(FGMultiplay* mp) :
|
|
||||||
_multiplay(mp)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void childAdded(SGPropertyNode*, SGPropertyNode*)
|
|
||||||
{
|
|
||||||
_multiplay->setPropertiesChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
FGMultiplay* _multiplay;
|
|
||||||
};
|
|
||||||
|
|
||||||
/******************************************************************
|
|
||||||
* Name: FGMultiplay
|
|
||||||
* Description: Constructor. Initialises the protocol and stores
|
|
||||||
* host and port information.
|
|
||||||
******************************************************************/
|
|
||||||
FGMultiplay::FGMultiplay (const string &dir, const int rate, const string &host, const int port) {
|
|
||||||
|
|
||||||
set_hz(rate);
|
|
||||||
|
|
||||||
set_direction(dir);
|
|
||||||
|
|
||||||
if (get_direction() == SG_IO_IN) {
|
|
||||||
|
|
||||||
fgSetInt("/sim/multiplay/rxport", port);
|
|
||||||
fgSetString("/sim/multiplay/rxhost", host.c_str());
|
|
||||||
|
|
||||||
} else if (get_direction() == SG_IO_OUT) {
|
|
||||||
|
|
||||||
fgSetInt("/sim/multiplay/txport", port);
|
|
||||||
fgSetString("/sim/multiplay/txhost", host.c_str());
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
mPropertiesChanged = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/******************************************************************
|
|
||||||
* Name: ~FGMultiplay
|
|
||||||
* Description: Destructor.
|
|
||||||
******************************************************************/
|
|
||||||
FGMultiplay::~FGMultiplay () {
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/******************************************************************
|
|
||||||
* Name: open
|
|
||||||
* Description: Enables the protocol.
|
|
||||||
******************************************************************/
|
|
||||||
bool FGMultiplay::open() {
|
|
||||||
|
|
||||||
if ( is_enabled() ) {
|
|
||||||
SG_LOG( SG_IO, SG_ALERT, "This shouldn't happen, but the channel "
|
|
||||||
<< "is already in use, ignoring" );
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
set_enabled(true);
|
|
||||||
|
|
||||||
mPropertiesChanged = true;
|
|
||||||
|
|
||||||
MPPropertyListener* pl = new MPPropertyListener(this);
|
|
||||||
globals->get_props()->addChangeListener(pl, false);
|
|
||||||
return is_enabled();
|
|
||||||
}
|
|
||||||
|
|
||||||
void FGMultiplay::findProperties()
|
|
||||||
{
|
|
||||||
if (!mPropertiesChanged) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
mPropertiesChanged = false;
|
|
||||||
|
|
||||||
for (unsigned i = 0; i < FGMultiplayMgr::numProperties; ++i) {
|
|
||||||
const char* name = FGMultiplayMgr::sIdPropertyList[i].name;
|
|
||||||
SGPropertyNode* pNode = globals->get_props()->getNode(name);
|
|
||||||
if (!pNode) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
int id = FGMultiplayMgr::sIdPropertyList[i].id;
|
|
||||||
if (mPropertyMap.find(id) != mPropertyMap.end()) {
|
|
||||||
continue; // already activated
|
|
||||||
}
|
|
||||||
|
|
||||||
mPropertyMap[id] = pNode;
|
|
||||||
SG_LOG(SG_NETWORK, SG_INFO, "activating MP property:" << pNode->getPath());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/******************************************************************
|
|
||||||
* Name: process
|
|
||||||
* Description: Prompts the multiplayer mgr to either send
|
|
||||||
* or receive data over the network
|
|
||||||
******************************************************************/
|
|
||||||
bool FGMultiplay::process() {
|
|
||||||
using namespace simgear;
|
|
||||||
if (get_direction() == SG_IO_OUT) {
|
|
||||||
findProperties();
|
|
||||||
|
|
||||||
// check if we have left initialization phase. That will not provide
|
|
||||||
// interresting data, also the freeze in simulation time hurts the
|
|
||||||
// multiplayer clients
|
|
||||||
double sim_time = globals->get_sim_time_sec();
|
|
||||||
// if (sim_time < 20)
|
|
||||||
// return true;
|
|
||||||
|
|
||||||
FlightProperties ifce;
|
|
||||||
|
|
||||||
// put together a motion info struct, you will get that later
|
|
||||||
// from FGInterface directly ...
|
|
||||||
FGExternalMotionData motionInfo;
|
|
||||||
|
|
||||||
// The current simulation time we need to update for,
|
|
||||||
// note that the simulation time is updated before calling all the
|
|
||||||
// update methods. Thus it contains the time intervals *end* time.
|
|
||||||
// The FDM is already run, so the states belong to that time.
|
|
||||||
motionInfo.time = sim_time;
|
|
||||||
|
|
||||||
// The typical lag will be the reciprocal of the output frequency
|
|
||||||
double hz = get_hz();
|
|
||||||
if (hz != 0) // I guess we can test a double for exact zero in this case
|
|
||||||
motionInfo.lag = 1/get_hz();
|
|
||||||
else
|
|
||||||
motionInfo.lag = 0.1; //??
|
|
||||||
|
|
||||||
// These are for now converted from lat/lon/alt and euler angles.
|
|
||||||
// But this should change in FGInterface ...
|
|
||||||
double lon = ifce.get_Longitude();
|
|
||||||
double lat = ifce.get_Latitude();
|
|
||||||
// first the aprioriate structure for the geodetic one
|
|
||||||
SGGeod geod = SGGeod::fromRadFt(lon, lat, ifce.get_Altitude());
|
|
||||||
// Convert to cartesion coordinate
|
|
||||||
motionInfo.position = SGVec3d::fromGeod(geod);
|
|
||||||
|
|
||||||
// The quaternion rotating from the earth centered frame to the
|
|
||||||
// horizontal local frame
|
|
||||||
SGQuatf qEc2Hl = SGQuatf::fromLonLatRad((float)lon, (float)lat);
|
|
||||||
// The orientation wrt the horizontal local frame
|
|
||||||
float heading = ifce.get_Psi();
|
|
||||||
float pitch = ifce.get_Theta();
|
|
||||||
float roll = ifce.get_Phi();
|
|
||||||
SGQuatf hlOr = SGQuatf::fromYawPitchRoll(heading, pitch, roll);
|
|
||||||
// The orientation of the vehicle wrt the earth centered frame
|
|
||||||
motionInfo.orientation = qEc2Hl*hlOr;
|
|
||||||
|
|
||||||
if (!globals->get_subsystem("flight")->is_suspended()) {
|
|
||||||
// velocities
|
|
||||||
motionInfo.linearVel = SG_FEET_TO_METER*SGVec3f(ifce.get_uBody(),
|
|
||||||
ifce.get_vBody(),
|
|
||||||
ifce.get_wBody());
|
|
||||||
motionInfo.angularVel = SGVec3f(ifce.get_P_body(),
|
|
||||||
ifce.get_Q_body(),
|
|
||||||
ifce.get_R_body());
|
|
||||||
|
|
||||||
// accels, set that to zero for now.
|
|
||||||
// Angular accelerations are missing from the interface anyway,
|
|
||||||
// linear accelerations are screwed up at least for JSBSim.
|
|
||||||
// motionInfo.linearAccel = SG_FEET_TO_METER*SGVec3f(ifce.get_U_dot_body(),
|
|
||||||
// ifce.get_V_dot_body(),
|
|
||||||
// ifce.get_W_dot_body());
|
|
||||||
motionInfo.linearAccel = SGVec3f::zeros();
|
|
||||||
motionInfo.angularAccel = SGVec3f::zeros();
|
|
||||||
} else {
|
|
||||||
// if the interface is suspendend, prevent the client from
|
|
||||||
// wild extrapolations
|
|
||||||
motionInfo.linearVel = SGVec3f::zeros();
|
|
||||||
motionInfo.angularVel = SGVec3f::zeros();
|
|
||||||
motionInfo.linearAccel = SGVec3f::zeros();
|
|
||||||
motionInfo.angularAccel = SGVec3f::zeros();
|
|
||||||
}
|
|
||||||
|
|
||||||
// now send the properties
|
|
||||||
PropertyMap::iterator it;
|
|
||||||
for (it = mPropertyMap.begin(); it != mPropertyMap.end(); ++it) {
|
|
||||||
FGPropertyData* pData = new FGPropertyData;
|
|
||||||
pData->id = it->first;
|
|
||||||
pData->type = it->second->getType();
|
|
||||||
|
|
||||||
switch (pData->type) {
|
|
||||||
case props::INT:
|
|
||||||
case props::LONG:
|
|
||||||
case props::BOOL:
|
|
||||||
pData->int_value = it->second->getIntValue();
|
|
||||||
break;
|
|
||||||
case props::FLOAT:
|
|
||||||
case props::DOUBLE:
|
|
||||||
pData->float_value = it->second->getFloatValue();
|
|
||||||
break;
|
|
||||||
case props::STRING:
|
|
||||||
case props::UNSPECIFIED:
|
|
||||||
{
|
|
||||||
// FIXME: We assume unspecified are strings for the moment.
|
|
||||||
|
|
||||||
const char* cstr = it->second->getStringValue();
|
|
||||||
int len = strlen(cstr);
|
|
||||||
|
|
||||||
if (len > 0)
|
|
||||||
{
|
|
||||||
pData->string_value = new char[len + 1];
|
|
||||||
strcpy(pData->string_value, cstr);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Size 0 - ignore
|
|
||||||
pData->string_value = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
//cout << " Sending property " << pData->id << " " << pData->type << " " << pData->string_value << "\n";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
// FIXME Currently default to a float.
|
|
||||||
//cout << "Unknown type when iterating through props: " << pData->type << "\n";
|
|
||||||
pData->float_value = it->second->getFloatValue();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
motionInfo.properties.push_back(pData);
|
|
||||||
}
|
|
||||||
|
|
||||||
FGMultiplayMgr* mpmgr = (FGMultiplayMgr*) globals->get_subsystem("mp");
|
|
||||||
mpmgr->SendMyPosition(motionInfo);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/******************************************************************
|
|
||||||
* Name: close
|
|
||||||
* Description: Closes the multiplayer mgrs to stop any further
|
|
||||||
* network processing
|
|
||||||
******************************************************************/
|
|
||||||
bool FGMultiplay::close()
|
|
||||||
{
|
|
||||||
mPropertyMap.clear();
|
|
||||||
|
|
||||||
FGMultiplayMgr* mgr = (FGMultiplayMgr*) globals->get_subsystem("mp");
|
|
||||||
|
|
||||||
if (mgr == 0) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (get_direction() == SG_IO_IN) {
|
|
||||||
|
|
||||||
mgr->Close();
|
|
||||||
|
|
||||||
} else if (get_direction() == SG_IO_OUT) {
|
|
||||||
|
|
||||||
mgr->Close();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,97 +0,0 @@
|
||||||
// multiplay.hxx -- protocol object for multiplay in Flightgear
|
|
||||||
//
|
|
||||||
// Written by Diarmuid Tyson, started February 2003.
|
|
||||||
// diarmuid.tyson@airservicesaustralia.com
|
|
||||||
//
|
|
||||||
// With additions by Vivian Meazza, January 2006
|
|
||||||
//
|
|
||||||
// Copyright (C) 2003 Airservices Australia
|
|
||||||
//
|
|
||||||
// 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 _FG_MULTIPLAY_HXX
|
|
||||||
#define _FG_MULTIPLAY_HXX
|
|
||||||
|
|
||||||
#define FG_MULTIPLAY_HID "$Id$"
|
|
||||||
|
|
||||||
#include <simgear/compiler.h>
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
#include <simgear/props/props.hxx>
|
|
||||||
|
|
||||||
#include <Main/globals.hxx>
|
|
||||||
#include <Main/fg_props.hxx>
|
|
||||||
#include <Model/acmodel.hxx>
|
|
||||||
#include <MultiPlayer/multiplaymgr.hxx>
|
|
||||||
|
|
||||||
#include "protocol.hxx"
|
|
||||||
|
|
||||||
using std::string;
|
|
||||||
|
|
||||||
|
|
||||||
/****************************************************************
|
|
||||||
* @version $Id$
|
|
||||||
*
|
|
||||||
* Description: FGMultiplay is an FGProtocol object used as the basic
|
|
||||||
* interface for the multiplayer code into FlightGears generic IO
|
|
||||||
* subsystem. It only implements the basic FGProtocol methods: open(),
|
|
||||||
* process() and close(). It does not use Sim Gear's IO channels, as
|
|
||||||
* the MultiplayMgrs creates their own sockets through plib.
|
|
||||||
*
|
|
||||||
* It will set up it's direction and rate protocol properties when
|
|
||||||
* created. Subsequent calls to process will prompt the
|
|
||||||
* MultiplayMgr to either send or receive data over the network.
|
|
||||||
*
|
|
||||||
******************************************************************/
|
|
||||||
|
|
||||||
class FGMultiplay : public FGProtocol {
|
|
||||||
public:
|
|
||||||
|
|
||||||
/** Constructor */
|
|
||||||
FGMultiplay (const string &dir, const int rate, const string &host, const int port);
|
|
||||||
|
|
||||||
/** Destructor. */
|
|
||||||
~FGMultiplay ();
|
|
||||||
|
|
||||||
/** Enables the FGMultiplay object. */
|
|
||||||
bool open();
|
|
||||||
|
|
||||||
/** Tells the multiplayer_mgr to send/receive data.
|
|
||||||
*/
|
|
||||||
bool process();
|
|
||||||
|
|
||||||
/** Closes the multiplayer_mgr.
|
|
||||||
*/
|
|
||||||
bool close();
|
|
||||||
|
|
||||||
void setPropertiesChanged()
|
|
||||||
{
|
|
||||||
mPropertiesChanged = true;
|
|
||||||
}
|
|
||||||
private:
|
|
||||||
bool mPropertiesChanged;
|
|
||||||
|
|
||||||
void findProperties();
|
|
||||||
|
|
||||||
// Map between the property id's from the multiplayers network packets
|
|
||||||
// and the property nodes
|
|
||||||
typedef std::map<unsigned, SGSharedPtr<SGPropertyNode> > PropertyMap;
|
|
||||||
PropertyMap mPropertyMap;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#endif // _FG_MULTIPLAY_HXX
|
|
|
@ -805,10 +805,19 @@ void FGNasalSys::update(double)
|
||||||
_context = naNewContext();
|
_context = naNewContext();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool pathSortPredicate(const SGPath& p1, const SGPath& p2)
|
||||||
|
{
|
||||||
|
return p1.file() < p2.file();
|
||||||
|
}
|
||||||
|
|
||||||
// Loads all scripts in given directory
|
// Loads all scripts in given directory
|
||||||
void FGNasalSys::loadScriptDirectory(simgear::Dir nasalDir)
|
void FGNasalSys::loadScriptDirectory(simgear::Dir nasalDir)
|
||||||
{
|
{
|
||||||
simgear::PathList scripts = nasalDir.children(simgear::Dir::TYPE_FILE, ".nas");
|
simgear::PathList scripts = nasalDir.children(simgear::Dir::TYPE_FILE, ".nas");
|
||||||
|
// sort scripts, avoid loading sequence effects due to file system's
|
||||||
|
// random directory order
|
||||||
|
std::sort(scripts.begin(), scripts.end(), pathSortPredicate);
|
||||||
|
|
||||||
for (unsigned int i=0; i<scripts.size(); ++i) {
|
for (unsigned int i=0; i<scripts.size(); ++i) {
|
||||||
SGPath fullpath(scripts[i]);
|
SGPath fullpath(scripts[i]);
|
||||||
SGPath file = fullpath.file();
|
SGPath file = fullpath.file();
|
||||||
|
|
|
@ -80,7 +80,7 @@ FGSampleQueue::update (double dt)
|
||||||
last_volume = volume;
|
last_volume = volume;
|
||||||
}
|
}
|
||||||
|
|
||||||
// process mesage queue
|
// process message queue
|
||||||
const string msgid = "Sequential Audio Message";
|
const string msgid = "Sequential Audio Message";
|
||||||
bool now_playing = false;
|
bool now_playing = false;
|
||||||
if ( exists( msgid ) ) {
|
if ( exists( msgid ) ) {
|
||||||
|
|
|
@ -35,16 +35,32 @@
|
||||||
#include <simgear/structure/event_mgr.hxx>
|
#include <simgear/structure/event_mgr.hxx>
|
||||||
#include <simgear/misc/sg_path.hxx>
|
#include <simgear/misc/sg_path.hxx>
|
||||||
#include <simgear/timing/lowleveltime.h>
|
#include <simgear/timing/lowleveltime.h>
|
||||||
|
#include <simgear/structure/commands.hxx>
|
||||||
|
|
||||||
#include <Main/fg_props.hxx>
|
#include <Main/fg_props.hxx>
|
||||||
#include <Main/globals.hxx>
|
#include <Main/globals.hxx>
|
||||||
#include <Time/sunsolver.hxx>
|
#include <Time/sunsolver.hxx>
|
||||||
|
|
||||||
|
static bool do_timeofday (const SGPropertyNode * arg)
|
||||||
|
{
|
||||||
|
const string &offset_type = arg->getStringValue("timeofday", "noon");
|
||||||
|
int offset = arg->getIntValue("offset", 0);
|
||||||
|
TimeManager* self = (TimeManager*) globals->get_subsystem("time");
|
||||||
|
if (offset_type == "real") {
|
||||||
|
// without this, setting 'real' time is a no-op, since the current
|
||||||
|
// wrap value (orig_warp) is retained in setTimeOffset. Ick.
|
||||||
|
fgSetInt("/sim/time/warp", 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
self->setTimeOffset(offset_type, offset);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
TimeManager::TimeManager() :
|
TimeManager::TimeManager() :
|
||||||
_inited(false),
|
_inited(false),
|
||||||
_impl(NULL)
|
_impl(NULL)
|
||||||
{
|
{
|
||||||
|
SGCommandMgr::instance()->addCommand("timeofday", do_timeofday);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TimeManager::init()
|
void TimeManager::init()
|
||||||
|
@ -345,6 +361,14 @@ void TimeManager::updateLocalTime()
|
||||||
}
|
}
|
||||||
|
|
||||||
void TimeManager::initTimeOffset()
|
void TimeManager::initTimeOffset()
|
||||||
|
{
|
||||||
|
|
||||||
|
int offset = fgGetInt("/sim/startup/time-offset");
|
||||||
|
string offset_type = fgGetString("/sim/startup/time-offset-type");
|
||||||
|
setTimeOffset(offset_type, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TimeManager::setTimeOffset(const std::string& offset_type, int offset)
|
||||||
{
|
{
|
||||||
// Handle potential user specified time offsets
|
// Handle potential user specified time offsets
|
||||||
int orig_warp = _warp->getIntValue();
|
int orig_warp = _warp->getIntValue();
|
||||||
|
@ -355,8 +379,6 @@ void TimeManager::initTimeOffset()
|
||||||
sgTimeGetGMT( fgLocaltime(&cur_time, _impl->get_zonename() ) );
|
sgTimeGetGMT( fgLocaltime(&cur_time, _impl->get_zonename() ) );
|
||||||
|
|
||||||
// Okay, we now have several possible scenarios
|
// Okay, we now have several possible scenarios
|
||||||
int offset = fgGetInt("/sim/startup/time-offset");
|
|
||||||
string offset_type = fgGetString("/sim/startup/time-offset-type");
|
|
||||||
double lon = _longitudeDeg->getDoubleValue() * SG_DEGREES_TO_RADIANS;
|
double lon = _longitudeDeg->getDoubleValue() * SG_DEGREES_TO_RADIANS;
|
||||||
double lat = _latitudeDeg->getDoubleValue() * SG_DEGREES_TO_RADIANS;
|
double lat = _latitudeDeg->getDoubleValue() * SG_DEGREES_TO_RADIANS;
|
||||||
int warp = 0;
|
int warp = 0;
|
||||||
|
@ -394,12 +416,12 @@ void TimeManager::initTimeOffset()
|
||||||
warp = offset - (aircraftLocalTime - currGMT)- cur_time;
|
warp = offset - (aircraftLocalTime - currGMT)- cur_time;
|
||||||
} else {
|
} else {
|
||||||
SG_LOG( SG_GENERAL, SG_ALERT,
|
SG_LOG( SG_GENERAL, SG_ALERT,
|
||||||
"TimeManager::initTimeOffset: unsupported offset: " << offset_type );
|
"TimeManager::setTimeOffset: unsupported offset: " << offset_type );
|
||||||
warp = 0;
|
warp = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
_warp->setIntValue( orig_warp + warp );
|
_warp->setIntValue( orig_warp + warp );
|
||||||
|
|
||||||
SG_LOG( SG_GENERAL, SG_INFO, "After fgInitTimeOffset(): warp = "
|
SG_LOG( SG_GENERAL, SG_INFO, "After TimeManager::setTimeOffset(): warp = "
|
||||||
<< _warp->getIntValue() );
|
<< _warp->getIntValue() );
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,6 +43,8 @@ public:
|
||||||
|
|
||||||
// SGPropertyChangeListener overrides
|
// SGPropertyChangeListener overrides
|
||||||
virtual void valueChanged(SGPropertyNode *);
|
virtual void valueChanged(SGPropertyNode *);
|
||||||
|
|
||||||
|
void setTimeOffset(const std::string& offset_type, int offset);
|
||||||
private:
|
private:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -345,7 +345,7 @@ void FGLight::update_adj_fog_color () {
|
||||||
else
|
else
|
||||||
hor_rotation = fmod(hor_rotation, SGD_2PI);
|
hor_rotation = fmod(hor_rotation, SGD_2PI);
|
||||||
|
|
||||||
// revert to unmodified values before usign them.
|
// revert to unmodified values before using them.
|
||||||
//
|
//
|
||||||
SGVec4f color = thesky->get_scene_color();
|
SGVec4f color = thesky->get_scene_color();
|
||||||
|
|
||||||
|
@ -359,7 +359,7 @@ void FGLight::update_adj_fog_color () {
|
||||||
float s_green = color[1]*color[1]*color[1];
|
float s_green = color[1]*color[1]*color[1];
|
||||||
float s_blue = color[2]*color[2];
|
float s_blue = color[2]*color[2];
|
||||||
|
|
||||||
// interpolate beween the sunrise/sunset color and the color
|
// interpolate between the sunrise/sunset color and the color
|
||||||
// at the opposite direction of this effect. Take in account
|
// at the opposite direction of this effect. Take in account
|
||||||
// the current visibility.
|
// the current visibility.
|
||||||
//
|
//
|
||||||
|
|
4
utils/fgpanel/.cvsignore
Normal file
4
utils/fgpanel/.cvsignore
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
.deps
|
||||||
|
Makefile
|
||||||
|
Makefile.in
|
||||||
|
fgpanel
|
|
@ -17,7 +17,12 @@
|
||||||
# include <config.h>
|
# include <config.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
using namespace std;
|
#include "FGGLApplication.hxx"
|
||||||
|
#ifdef HAVE_WINDOWS_H
|
||||||
|
#include <windows.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include "ApplicationProperties.hxx"
|
#include "ApplicationProperties.hxx"
|
||||||
|
@ -93,7 +98,7 @@ inline bool FGFontCache::FntParamsLess::operator()(const FntParams& f1,
|
||||||
struct FGFontCache::fnt *
|
struct FGFontCache::fnt *
|
||||||
FGFontCache::getfnt(const char *name, float size, float slant)
|
FGFontCache::getfnt(const char *name, float size, float slant)
|
||||||
{
|
{
|
||||||
string fontName(name);
|
std::string fontName(name);
|
||||||
FntParams fntParams(fontName, size, slant);
|
FntParams fntParams(fontName, size, slant);
|
||||||
PuFontMap::iterator i = _puFonts.find(fntParams);
|
PuFontMap::iterator i = _puFonts.find(fntParams);
|
||||||
if (i != _puFonts.end())
|
if (i != _puFonts.end())
|
||||||
|
@ -183,7 +188,7 @@ FGFontCache::getfntpath(const char *name)
|
||||||
|
|
||||||
bool FGFontCache::initializeFonts()
|
bool FGFontCache::initializeFonts()
|
||||||
{
|
{
|
||||||
static string fontext("txf");
|
static std::string fontext("txf");
|
||||||
init();
|
init();
|
||||||
ulDir* fontdir = ulOpenDir(_path.c_str());
|
ulDir* fontdir = ulOpenDir(_path.c_str());
|
||||||
if (!fontdir)
|
if (!fontdir)
|
||||||
|
@ -195,7 +200,7 @@ bool FGFontCache::initializeFonts()
|
||||||
if (path.extension() == fontext) {
|
if (path.extension() == fontext) {
|
||||||
fntTexFont* f = new fntTexFont;
|
fntTexFont* f = new fntTexFont;
|
||||||
if (f->load((char *)path.c_str()))
|
if (f->load((char *)path.c_str()))
|
||||||
_texFonts[string(dirEntry->d_name)] = f;
|
_texFonts[std::string(dirEntry->d_name)] = f;
|
||||||
else
|
else
|
||||||
delete f;
|
delete f;
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
//
|
//
|
||||||
#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 <simgear/props/props.hxx>
|
#include <simgear/props/props.hxx>
|
||||||
#include <plib/pu.h>
|
#include <plib/pu.h>
|
||||||
|
@ -55,8 +56,8 @@ private:
|
||||||
// Path to the font directory
|
// Path to the font directory
|
||||||
SGPath _path;
|
SGPath _path;
|
||||||
|
|
||||||
typedef map<const string, fntTexFont*> TexFontMap;
|
typedef std::map<const std::string, fntTexFont*> TexFontMap;
|
||||||
typedef map<const FntParams, fnt*, FntParamsLess> PuFontMap;
|
typedef std::map<const FntParams, fnt*, FntParamsLess> PuFontMap;
|
||||||
TexFontMap _texFonts;
|
TexFontMap _texFonts;
|
||||||
PuFontMap _puFonts;
|
PuFontMap _puFonts;
|
||||||
|
|
||||||
|
|
|
@ -15,9 +15,18 @@
|
||||||
// along with this program; if not, write to the Free Software
|
// along with this program; if not, write to the Free Software
|
||||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
# include <config.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "FGGLApplication.hxx"
|
#include "FGGLApplication.hxx"
|
||||||
#include "GL/gl.h"
|
#ifdef HAVE_WINDOWS_H
|
||||||
#include "GL/glut.h"
|
#include <windows.h>
|
||||||
|
#define snprintf sprintf_s
|
||||||
|
#endif
|
||||||
|
#include <GL/gl.h>
|
||||||
|
#include <GL/glut.h>
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <exception>
|
#include <exception>
|
||||||
|
|
|
@ -13,6 +13,13 @@
|
||||||
// along with this program; if not, write to the Free Software
|
// along with this program; if not, write to the Free Software
|
||||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
//
|
//
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
# include <config.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_WINDOWS_H
|
||||||
|
#include <windows.h>
|
||||||
|
#endif
|
||||||
#include "FGPNGTextureLoader.hxx"
|
#include "FGPNGTextureLoader.hxx"
|
||||||
|
|
||||||
#include <GL/glu.h>
|
#include <GL/glu.h>
|
||||||
|
|
|
@ -15,6 +15,16 @@
|
||||||
// along with this program; if not, write to the Free Software
|
// along with this program; if not, write to the Free Software
|
||||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
# include <config.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_WINDOWS_H
|
||||||
|
#include <windows.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "FGGLApplication.hxx"
|
||||||
#include "FGPanelApplication.hxx"
|
#include "FGPanelApplication.hxx"
|
||||||
#include <GL/gl.h>
|
#include <GL/gl.h>
|
||||||
#include <GL/glut.h>
|
#include <GL/glut.h>
|
||||||
|
@ -172,8 +182,7 @@ void FGPanelApplication::Key( unsigned char key, int x, int y )
|
||||||
{
|
{
|
||||||
switch( key ) {
|
switch( key ) {
|
||||||
case 0x1b:
|
case 0x1b:
|
||||||
if( gameMode ) glutLeaveGameMode();
|
exit(0);
|
||||||
else glutDestroyWindow( windowId );
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -226,7 +235,11 @@ double FGPanelApplication::Sleep()
|
||||||
double elapsed_us = (current_time_stamp - last_time_stamp).toUSecs();
|
double elapsed_us = (current_time_stamp - last_time_stamp).toUSecs();
|
||||||
if ( elapsed_us < frame_us ) {
|
if ( elapsed_us < frame_us ) {
|
||||||
double requested_us = frame_us - elapsed_us;
|
double requested_us = frame_us - elapsed_us;
|
||||||
|
#ifdef _WIN32
|
||||||
|
::Sleep ((int)(requested_us / 1000.0)) ;
|
||||||
|
#else
|
||||||
usleep ( (useconds_t)(requested_us ) ) ;
|
usleep ( (useconds_t)(requested_us ) ) ;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
// busy wait timing loop.
|
// busy wait timing loop.
|
||||||
//
|
//
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
#include "FGGLApplication.hxx"
|
#include "FGGLApplication.hxx"
|
||||||
#include "FGPanelProtocol.hxx"
|
#include "FGPanelProtocol.hxx"
|
||||||
|
|
||||||
|
#include <simgear/math/SGMath.hxx>
|
||||||
#include <simgear/structure/subsystem_mgr.hxx>
|
#include <simgear/structure/subsystem_mgr.hxx>
|
||||||
#include <simgear/props/props.hxx>
|
#include <simgear/props/props.hxx>
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,18 @@
|
||||||
// along with this program; if not, write to the Free Software
|
// along with this program; if not, write to the Free Software
|
||||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
//
|
//
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
# include <config.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_WINDOWS_H
|
||||||
|
#include <windows.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
#define strtof strtod
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "FGPanelProtocol.hxx"
|
#include "FGPanelProtocol.hxx"
|
||||||
#include "ApplicationProperties.hxx"
|
#include "ApplicationProperties.hxx"
|
||||||
#include <simgear/io/sg_socket.hxx>
|
#include <simgear/io/sg_socket.hxx>
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
//
|
//
|
||||||
#ifndef __FGPANELPROTOCOL_HXX
|
#ifndef __FGPANELPROTOCOL_HXX
|
||||||
#define __FGPANELPROTOCOL_HXX
|
#define __FGPANELPROTOCOL_HXX
|
||||||
|
#include <simgear/math/SGMath.hxx>
|
||||||
#include <simgear/structure/subsystem_mgr.hxx>
|
#include <simgear/structure/subsystem_mgr.hxx>
|
||||||
#include <simgear/props/props.hxx>
|
#include <simgear/props/props.hxx>
|
||||||
#include <simgear/io/iochannel.hxx>
|
#include <simgear/io/iochannel.hxx>
|
||||||
|
|
|
@ -17,6 +17,14 @@
|
||||||
// Reader for sgi's .rgb format.
|
// Reader for sgi's .rgb format.
|
||||||
// specification can be found at http://local.wasp.uwa.edu.au/~pbourke/dataformats/sgirgb/sgiversion.html
|
// specification can be found at http://local.wasp.uwa.edu.au/~pbourke/dataformats/sgirgb/sgiversion.html
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
# include <config.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_WINDOWS_H
|
||||||
|
#include <windows.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "FGRGBTextureLoader.hxx"
|
#include "FGRGBTextureLoader.hxx"
|
||||||
#include <GL/gl.h>
|
#include <GL/gl.h>
|
||||||
#include <GL/glu.h>
|
#include <GL/glu.h>
|
||||||
|
|
|
@ -36,6 +36,7 @@
|
||||||
#include <plib/fnt.h>
|
#include <plib/fnt.h>
|
||||||
|
|
||||||
#include <simgear/debug/logstream.hxx>
|
#include <simgear/debug/logstream.hxx>
|
||||||
|
#include <simgear/math/SGMath.hxx>
|
||||||
#include <simgear/misc/sg_path.hxx>
|
#include <simgear/misc/sg_path.hxx>
|
||||||
|
|
||||||
#include "panel.hxx"
|
#include "panel.hxx"
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
#include <string.h> // for strcmp()
|
#include <string.h> // for strcmp()
|
||||||
|
|
||||||
#include <simgear/compiler.h>
|
#include <simgear/compiler.h>
|
||||||
|
#include <simgear/math/SGMath.hxx>
|
||||||
#include <simgear/structure/exception.hxx>
|
#include <simgear/structure/exception.hxx>
|
||||||
#include <simgear/debug/logstream.hxx>
|
#include <simgear/debug/logstream.hxx>
|
||||||
#include <simgear/misc/sg_path.hxx>
|
#include <simgear/misc/sg_path.hxx>
|
||||||
|
|
2
version
2
version
|
@ -1 +1 @@
|
||||||
2.2.0
|
2.3.0
|
||||||
|
|
Loading…
Reference in a new issue