- added ViewFormat for parsing GE queries for Camera and stuff

- Camera now controlled with adjustable alt, tilt, auto roll based on aircraft banking and auto heading based on aircraft heading


git-svn-id: http://moon:8086/svn/software/trunk/projects/FsTrack@129 b431acfa-c32f-4a4a-93f1-934dc6c82436
This commit is contained in:
2015-01-13 23:12:57 +00:00
parent 5c19b3e189
commit f471a98b52
9 changed files with 363 additions and 40 deletions
+4
View File
@@ -8,6 +8,10 @@
<FILE id="edoJMV" name="IPCuser.c" compile="1" resource="0" file="../../../extLib/FSUIPC/IPCuser.c"/>
<FILE id="H8XnE6" name="IPCuser.h" compile="0" resource="0" file="../../../extLib/FSUIPC/IPCuser.h"/>
<GROUP id="{5356CAE2-AF78-67D9-5B9A-B642C31D86A7}" name="Source">
<FILE id="vFudTr" name="IFsLink.hpp" compile="0" resource="0" file="Source/IFsLink.hpp"/>
<FILE id="PagC6q" name="IHttp.hpp" compile="0" resource="0" file="Source/IHttp.hpp"/>
<FILE id="XsFnKu" name="IKml.hpp" compile="0" resource="0" file="Source/IKml.hpp"/>
<FILE id="wvlNhQ" name="ViewFormat.hpp" compile="0" resource="0" file="Source/ViewFormat.hpp"/>
<FILE id="LzGXK0" name="HttpServer.cpp" compile="1" resource="0" file="Source/HttpServer.cpp"/>
<FILE id="lMXJZr" name="HttpServer.hpp" compile="0" resource="0" file="Source/HttpServer.hpp"/>
<FILE id="qge6g6" name="Kml.cpp" compile="1" resource="0" file="Source/Kml.cpp"/>
+28 -19
View File
@@ -1,6 +1,5 @@
#include "HttpServer.hpp"
HttpServer::HttpServer(int port, const char *pDocDir)
: Thread("Http")
, m_port(port)
@@ -23,36 +22,46 @@ void HttpServer::addListener(IHttpListener *pListener)
const char* HttpServer::getDocName(char *buffer, int buflen)
{
static char docBuffer[1024];
char *pDocname;
char *pDoc = docBuffer;
char *pBuf;
bool hasQuery = false;
strcpy(docBuffer, m_docDir);
pDocname = &docBuffer[strlen(docBuffer)];
*pDocname = '\\';
pDocname++;
int i, off;
pDoc = &docBuffer[strlen(docBuffer)];
*pDoc = '\\';
pDoc++;
if (!stricmp(buffer, "GET"))
{
return nullptr;
}
off = 0;
while(buffer[3+off] == 0x20)
off++;
pBuf = buffer + 3;
while(*pBuf == 0x20)
pBuf++;
while(buffer[3+off] == '/')
off++;
while(*pBuf == '/')
pBuf++;
i = 0;
while(buffer[3+off+i] != 0x20)
int len = 0;
while(*pBuf != 0x20)
{
pDocname[i] = buffer[3+off+i];
i++;
if (*pBuf == '?')
{
hasQuery = true;
break;
}
*pDoc++ = *pBuf++;
len++;
}
pDocname[i] = 0;
*pDoc = 0;
if (i==0)
if (hasQuery)
{
m_viewFormat.parse(pBuf);
}
if (len==0)
return nullptr;
return docBuffer;
@@ -85,7 +94,7 @@ void HttpServer::run()
}
else
{
m_listeners.call(&IHttpListener::onUpdate, pDoc);
m_listeners.call(&IHttpListener::onUpdate, pDoc, m_viewFormat);
}
}
+4 -2
View File
@@ -1,7 +1,8 @@
#ifndef HTTPSERVER
#define HTTPSERVER
#ifndef HTTPSERVER_HPP
#define HTTPSERVER_HPP
#include "../JuceLibraryCode/JuceHeader.h"
#include "ViewFormat.hpp"
#include "IHttp.hpp"
class HttpServer : public juce::Thread
@@ -15,6 +16,7 @@ private:
int m_port;
const char *m_docDir;
ListenerList <IHttpListener> m_listeners;
ViewFormat m_viewFormat;
const char* getDocName(char *buffer, int buflen);
void run();
+3 -1
View File
@@ -8,12 +8,14 @@
#ifndef IHTTP_HPP
#define IHTTP_HPP
#include "ViewFormat.hpp"
struct IHttpListener
{
IHttpListener() {}
virtual ~IHttpListener() {}
virtual void onUpdate(const char *pPath) = 0;
virtual void onUpdate(const char *pPath, ViewFormat const &viewFormat) = 0;
};
#endif /* IHTTP_HPP */
+66 -13
View File
@@ -12,6 +12,10 @@ Kml::Kml(const char *pDocRoot)
, m_docRoot(pDocRoot)
, m_altitudeModeString("absolute")
, m_pathColorString("0xff00ffff")
, m_cameraAlt(1000)
, m_cameraTilt(0)
, m_cameraAutoHeading(false)
, m_cameraAutoRoll(false)
{
memset(m_path, 0, sizeof(m_path));
}
@@ -49,6 +53,7 @@ void Kml::create()
// Create an outer XML element..
kml->setAttribute("xmlns", "http://www.opengis.net/kml/2.2");
kml->setAttribute("xmlns:gx", "http://www.google.com/kml/ext/2.2");
sprintf(m_path, "%s\\flight_%4.4d%2.2d%2.2d_%2.2d%2.2d%2.2d.kml", m_docRoot, 1900+time_now->tm_year, time_now->tm_mon+1, time_now->tm_mday, time_now->tm_hour, time_now->tm_min, time_now->tm_sec);
pFile->addTextElement(m_path);
pSnippet->setAttribute("maxLines", "2");
@@ -57,13 +62,13 @@ void Kml::create()
pSnippet->addTextElement(time_str);
// Camera
pCamera->createNewChildElement("longitude")->addTextElement("");
pCamera->createNewChildElement("latitude")->addTextElement("");
pCamera->createNewChildElement("altitude")->addTextElement("");
pCamera->createNewChildElement("heading")->addTextElement("");
pCamera->createNewChildElement("tilt")->addTextElement("");
pCamera->createNewChildElement("altitudeMode")->addTextElement("");
pCamera->createNewChildElement("longitude")->addTextElement("0");
pCamera->createNewChildElement("latitude")->addTextElement("0");
pCamera->createNewChildElement("altitude")->addTextElement("0");
pCamera->createNewChildElement("heading")->addTextElement("0");
pCamera->createNewChildElement("tilt")->addTextElement("0");
pCamera->createNewChildElement("roll")->addTextElement("0");
pCamera->createNewChildElement("altitudeMode")->addTextElement(m_altitudeModeString);
}
@@ -103,6 +108,16 @@ void Kml::setPathColor(String const &colorString)
}
void Kml::setCameraAltitude(float alt_meters)
{
m_cameraAlt = alt_meters;
}
void Kml::setCameraTilt(float tilt_deg)
{
m_cameraTilt = tilt_deg;
}
void Kml::update(FlightData const &flightData)
{
const ScopedLock sl (m_lock);
@@ -110,6 +125,16 @@ void Kml::update(FlightData const &flightData)
updatePath(flightData);
}
void Kml::setCameraAutoHeading(bool enable)
{
m_cameraAutoHeading = enable;
}
void Kml::setCameraAutoRoll(bool enable)
{
m_cameraAutoRoll = enable;
}
void Kml::updatePlane(FlightData const &flightData)
{
char temp_str[1024];
@@ -133,7 +158,6 @@ void Kml::updatePlane(FlightData const &flightData)
XmlElement *pCoords;
XmlElement *pCamera;
XmlElement *pLookAt;
if(pPlacemark == NULL)
{
@@ -212,13 +236,20 @@ void Kml::updatePlane(FlightData const &flightData)
pCoords = pPlacemark->getChildByName("Point")->getChildByName("coordinates");
pCoords->getFirstChildElement()->setText(temp_str);
// Camera
pCamera = kml->getChildByName("NetworkLinkControl")->getChildByName("Camera");
pCamera->getChildByName("longitude")->getFirstChildElement()->setText(String(flightData.lon));
pCamera->getChildByName("latitude")->getFirstChildElement()->setText(String(flightData.lat));
pCamera->getChildByName("altitude")->getFirstChildElement()->setText(String(flightData.alt_meter));
pCamera->getChildByName("heading")->getFirstChildElement()->setText(String(flightData.hdgTrue_deg));
pCamera->getChildByName("tilt")->getFirstChildElement()->setText("90");
pCamera->getChildByName("altitude")->getFirstChildElement()->setText(String(flightData.alt_meter+m_cameraAlt));
if (m_cameraAutoHeading)
pCamera->getChildByName("heading")->getFirstChildElement()->setText(String(flightData.hdgTrue_deg));
pCamera->getChildByName("tilt")->getFirstChildElement()->setText(String(m_cameraTilt));
if (m_cameraAutoRoll)
pCamera->getChildByName("roll")->getFirstChildElement()->setText(String(flightData.bank_deg));
pCamera->getChildByName("altitudeMode")->getFirstChildElement()->setText(m_altitudeModeString);
}
@@ -323,8 +354,30 @@ void Kml::exportKmz(const char *pPath)
}
}
void Kml::onUpdate(const char *pPath)
void Kml::onUpdate(const char *pPath, ViewFormat const &viewFormat)
{
if (kml == nullptr)
return;
// LookAt
XmlElement *pCamera;
pCamera = kml->getChildByName("NetworkLinkControl")->getChildByName("Camera");
if (viewFormat.has_camera)
{
// pCamera->getChildByName("longitude")->getFirstChildElement()->setText(String(viewFormat.camera.lookatLon));
// pCamera->getChildByName("latitude")->getFirstChildElement()->setText(String(viewFormat.camera.lookatLat));
// pCamera->getChildByName("altitude")->getFirstChildElement()->setText(String(viewFormat.camera.lookatRange));
// pCamera->getChildByName("heading")->getFirstChildElement()->setText(String(viewFormat.camera.lookatHeading));
// pCamera->getChildByName("heading")->getFirstChildElement()->setText(String(0));
// pCamera->getChildByName("tilt")->getFirstChildElement()->setText(String(viewFormat.camera.lookatTilt));
// pCamera->getChildByName("tilt")->getFirstChildElement()->setText(String(0));
// pCamera->getChildByName("range")->getFirstChildElement()->setText(String(viewFormat.camera.lookatRange));
// pCamera->getChildByName("range")->getFirstChildElement()->setText(String("10000"));
// pCamera->getChildByName("altitudeMode")->getFirstChildElement()->setText(m_altitudeModeString);
}
exportKmz(pPath);
}
+9 -2
View File
@@ -13,6 +13,10 @@ public:
void setAltitudeMode(String const &modeString);
void setPathColor(String const &colorString);
void setCameraAltitude(float alt_meters);
void setCameraTilt(float tilt_deg);
void setCameraAutoHeading(bool enable);
void setCameraAutoRoll(bool enable);
private:
CriticalSection m_lock;
@@ -23,7 +27,10 @@ private:
const char *m_docRoot;
String m_altitudeModeString;
String m_pathColorString;
float m_cameraAlt;
float m_cameraTilt;
bool m_cameraAutoHeading;
bool m_cameraAutoRoll;
void create();
void destroy();
const char* getPath();
@@ -32,7 +39,7 @@ private:
void exportKmz(const char *pPath);
void updatePlane(FlightData const &flightData);
void updatePath(FlightData const &flightData);
void onUpdate(const char *pPath);
void onUpdate(const char *pPath, ViewFormat const &viewFormat);
};
#endif // !KML_HPP
+84 -2
View File
@@ -69,6 +69,28 @@ MainComponent::MainComponent (String const &homeDir)
m_altitudeMode->addSeparator();
m_altitudeMode->addListener (this);
addAndMakeVisible (m_cameraAltitude = new Slider ("Camera Altitude"));
m_cameraAltitude->setTooltip (TRANS("Camera Altitude"));
m_cameraAltitude->setRange (0, 100000, 100);
m_cameraAltitude->setSliderStyle (Slider::LinearHorizontal);
m_cameraAltitude->setTextBoxStyle (Slider::TextBoxLeft, false, 80, 20);
m_cameraAltitude->addListener (this);
addAndMakeVisible (m_CameraTilt = new Slider ("Camera Tilt"));
m_CameraTilt->setTooltip (TRANS("Camera Tilt"));
m_CameraTilt->setRange (0, 90, 5);
m_CameraTilt->setSliderStyle (Slider::LinearHorizontal);
m_CameraTilt->setTextBoxStyle (Slider::TextBoxLeft, false, 80, 20);
m_CameraTilt->addListener (this);
addAndMakeVisible (m_cameraAutoHeadingEnable = new ToggleButton ("Camera Auto Heading"));
m_cameraAutoHeadingEnable->setTooltip (TRANS("Camera Auto Heading"));
m_cameraAutoHeadingEnable->addListener (this);
addAndMakeVisible (m_cameraAutoRollEnable = new ToggleButton ("Camera Auto Roll"));
m_cameraAutoRollEnable->setTooltip (TRANS("Camera Auto Roll"));
m_cameraAutoRollEnable->addListener (this);
//[UserPreSize]
//[/UserPreSize]
@@ -99,6 +121,8 @@ MainComponent::MainComponent (String const &homeDir)
m_colorSelector->setCurrentColour(juce::Colours::yellow);
m_altitudeMode->setSelectedId(1, juce::NotificationType::sendNotification);
m_cameraAltitude->setValue(10000, juce::NotificationType::sendNotification);
m_CameraTilt->setValue(0, juce::NotificationType::sendNotification);
//[/Constructor]
}
@@ -116,6 +140,10 @@ MainComponent::~MainComponent()
m_kmlUpdInterval_s = nullptr;
m_colorSelector = nullptr;
m_altitudeMode = nullptr;
m_cameraAltitude = nullptr;
m_CameraTilt = nullptr;
m_cameraAutoHeadingEnable = nullptr;
m_cameraAutoRollEnable = nullptr;
//[Destructor]. You can add your own custom destruction code here..
@@ -138,9 +166,13 @@ void MainComponent::resized()
{
m_fsuipcStatus->setBounds (16, 264, 150, 24);
m_flightStatus->setBounds (216, 264, 150, 24);
m_kmlUpdInterval_s->setBounds (16, 232, 184, 24);
m_kmlUpdInterval_s->setBounds (24, 232, 160, 24);
m_colorSelector->setBounds (24, 24, 168, 192);
m_altitudeMode->setBounds (216, 32, 160, 24);
m_cameraAltitude->setBounds (216, 80, 160, 24);
m_CameraTilt->setBounds (216, 120, 160, 24);
m_cameraAutoHeadingEnable->setBounds (216, 160, 150, 24);
m_cameraAutoRollEnable->setBounds (216, 192, 150, 24);
//[UserResized] Add your own custom resize handling here..
//[/UserResized]
}
@@ -156,6 +188,18 @@ void MainComponent::sliderValueChanged (Slider* sliderThatWasMoved)
m_fsLink->setUpdateInterval(sliderThatWasMoved->getValue());
//[/UserSliderCode_m_kmlUpdInterval_s]
}
else if (sliderThatWasMoved == m_cameraAltitude)
{
//[UserSliderCode_m_cameraAltitude] -- add your slider handling code here..
m_kml->setCameraAltitude(sliderThatWasMoved->getValue());
//[/UserSliderCode_m_cameraAltitude]
}
else if (sliderThatWasMoved == m_CameraTilt)
{
//[UserSliderCode_m_CameraTilt] -- add your slider handling code here..
m_kml->setCameraTilt(sliderThatWasMoved->getValue());
//[/UserSliderCode_m_CameraTilt]
}
//[UsersliderValueChanged_Post]
//[/UsersliderValueChanged_Post]
@@ -177,6 +221,28 @@ void MainComponent::comboBoxChanged (ComboBox* comboBoxThatHasChanged)
//[/UsercomboBoxChanged_Post]
}
void MainComponent::buttonClicked (Button* buttonThatWasClicked)
{
//[UserbuttonClicked_Pre]
//[/UserbuttonClicked_Pre]
if (buttonThatWasClicked == m_cameraAutoHeadingEnable)
{
//[UserButtonCode_m_cameraAutoHeadingEnable] -- add your button handler code here..
m_kml->setCameraAutoHeading(buttonThatWasClicked->getToggleState());
//[/UserButtonCode_m_cameraAutoHeadingEnable]
}
else if (buttonThatWasClicked == m_cameraAutoRollEnable)
{
//[UserButtonCode_m_cameraAutoRollEnable] -- add your button handler code here..
m_kml->setCameraAutoRoll(buttonThatWasClicked->getToggleState());
//[/UserButtonCode_m_cameraAutoRollEnable]
}
//[UserbuttonClicked_Post]
//[/UserbuttonClicked_Post]
}
//[MiscUserCode] You can add your own definitions of your custom methods or any other code here...
@@ -229,7 +295,7 @@ BEGIN_JUCER_METADATA
editableDoubleClick="0" focusDiscardsChanges="0" fontname="Default font"
fontsize="15" bold="0" italic="0" justification="33"/>
<SLIDER name="KML Update Interval" id="c4434642fabdd31c" memberName="m_kmlUpdInterval_s"
virtualName="" explicitFocusOrder="0" pos="16 232 184 24" tooltip="KML Update Interval"
virtualName="" explicitFocusOrder="0" pos="24 232 160 24" tooltip="KML Update Interval"
min="0.10000000000000001" max="10" int="0.10000000000000001"
style="LinearHorizontal" textBoxPos="TextBoxLeft" textBoxEditable="1"
textBoxWidth="80" textBoxHeight="20" skewFactor="1"/>
@@ -240,6 +306,22 @@ BEGIN_JUCER_METADATA
virtualName="" explicitFocusOrder="0" pos="216 32 160 24" tooltip="Altitude Mode"
editable="0" layout="33" items="absolute&#10;relativeToGround&#10;clampToGround&#10;"
textWhenNonSelected="" textWhenNoItems="(no choices)"/>
<SLIDER name="Camera Altitude" id="3352cbc6aebbcc9e" memberName="m_cameraAltitude"
virtualName="" explicitFocusOrder="0" pos="216 80 160 24" tooltip="Camera Altitude"
min="0" max="100000" int="100" style="LinearHorizontal" textBoxPos="TextBoxLeft"
textBoxEditable="1" textBoxWidth="80" textBoxHeight="20" skewFactor="1"/>
<SLIDER name="Camera Tilt" id="4993af2027f11be1" memberName="m_CameraTilt"
virtualName="" explicitFocusOrder="0" pos="216 120 160 24" tooltip="Camera Tilt"
min="0" max="90" int="5" style="LinearHorizontal" textBoxPos="TextBoxLeft"
textBoxEditable="1" textBoxWidth="80" textBoxHeight="20" skewFactor="1"/>
<TOGGLEBUTTON name="Camera Auto Heading" id="97a6fc7c399da63d" memberName="m_cameraAutoHeadingEnable"
virtualName="" explicitFocusOrder="0" pos="216 160 150 24" tooltip="Camera Auto Heading"
buttonText="Camera Auto Heading" connectedEdges="0" needsCallback="1"
radioGroupId="0" state="0"/>
<TOGGLEBUTTON name="Camera Auto Roll" id="cc847f94257e9212" memberName="m_cameraAutoRollEnable"
virtualName="" explicitFocusOrder="0" pos="216 192 150 24" tooltip="Camera Auto Roll"
buttonText="Camera Auto Roll" connectedEdges="0" needsCallback="1"
radioGroupId="0" state="0"/>
</JUCER_COMPONENT>
END_JUCER_METADATA
+7 -1
View File
@@ -41,7 +41,8 @@ class MainComponent : public Component,
public IFsLinkListener,
public ChangeListener,
public SliderListener,
public ComboBoxListener
public ComboBoxListener,
public ButtonListener
{
public:
//==============================================================================
@@ -56,6 +57,7 @@ public:
void resized();
void sliderValueChanged (Slider* sliderThatWasMoved);
void comboBoxChanged (ComboBox* comboBoxThatHasChanged);
void buttonClicked (Button* buttonThatWasClicked);
@@ -77,6 +79,10 @@ private:
ScopedPointer<Slider> m_kmlUpdInterval_s;
ScopedPointer<ColourSelector> m_colorSelector;
ScopedPointer<ComboBox> m_altitudeMode;
ScopedPointer<Slider> m_cameraAltitude;
ScopedPointer<Slider> m_CameraTilt;
ScopedPointer<ToggleButton> m_cameraAutoHeadingEnable;
ScopedPointer<ToggleButton> m_cameraAutoRollEnable;
//==============================================================================
+158
View File
@@ -0,0 +1,158 @@
#ifndef VIEWFORMAT_HPP
#define VIEWFORMAT_HPP
#include "../JuceLibraryCode/JuceHeader.h"
class AParser
{
public:
virtual void parse(char **ppStream)
{
printf("%s\n", extractField(ppStream));
}
protected:
AParser() {}
~AParser() {}
struct Field
{
Field(const char *_name, AParser &_member, bool &hasTag)
: name(_name)
, member(_member)
, m_hasTag(hasTag)
{
m_hasTag = false;
}
const char *name;
AParser &member;
bool &m_hasTag;
};
char *extractField(char **ppStream)
{
static char field[256];
char *pStream = *ppStream;
char *pField = field;
skip(&pStream);
for (size_t i=0; i < sizeof(field); i++)
{
if (*pStream == ',')
break;
if (*pStream == ';')
break;
if (*pStream == '=')
break;
*(pField++) = *(pStream++);
}
*pField = 0;
*ppStream = pStream;
return field;
}
private:
void skip(char **ppStream)
{
while ((**ppStream == '\\') || (**ppStream == '?') || (**ppStream == ',') || (**ppStream == ';') || (**ppStream == '=') || (**ppStream <= 0x20))
{
(*ppStream)++;
};
}
};
// ?BBOX=1.0, 2.0, 3.0, 4.0?CAMERA/Pos=1.0, 2.0, 3.0
class ViewFormat : private AParser
{
private:
struct Bbox : public AParser
{
float n, e, s, w;
void parse(char **ppStream)
{
n = String(extractField(ppStream)).getFloatValue();
e = String(extractField(ppStream)).getFloatValue();
s = String(extractField(ppStream)).getFloatValue();
w = String(extractField(ppStream)).getFloatValue();
}
};
struct Camera : public AParser
{
float lookatLon, lookatLat, lookatRange, lookatTilt, lookatHeading;
void parse(char **ppStream)
{
lookatLon = String(extractField(ppStream)).getFloatValue();
lookatLat = String(extractField(ppStream)).getFloatValue();
lookatRange = String(extractField(ppStream)).getFloatValue();
lookatTilt = String(extractField(ppStream)).getFloatValue();
lookatHeading = String(extractField(ppStream)).getFloatValue();
}
};
struct View : public AParser
{
float horizFov, vertFov, horizPixels, vertPixels, terrainEnabled;
void parse(char **ppStream)
{
horizFov = String(extractField(ppStream)).getFloatValue();
vertFov = String(extractField(ppStream)).getFloatValue();
horizPixels = String(extractField(ppStream)).getFloatValue();
vertPixels = String(extractField(ppStream)).getFloatValue();
terrainEnabled = String(extractField(ppStream)).getFloatValue();
}
};
AParser::Field fieldBbox;
AParser::Field fieldCamera;
AParser::Field fieldView;
AParser::Field *fields[3];
public:
bool has_bbox;
Bbox bbox;
bool has_camera;
Camera camera;
bool has_view;
View view;
ViewFormat()
: fieldBbox(AParser::Field("BBox", bbox, has_bbox))
, fieldCamera(AParser::Field("Camera", camera, has_camera))
, fieldView(AParser::Field("View", view, has_view))
{
fields[0] = &fieldBbox;
fields[1] = &fieldCamera;
fields[2] = &fieldView;
}
~ViewFormat() {}
void parse(const char *pStream)
{
char *pSubStream = (char*)pStream;
for (unsigned i=0; i < sizeof(fields)/sizeof(*fields); i++)
{
char *pField = extractField(&pSubStream);
if (!stricmp(pField, fields[i]->name))
{
fields[i]->member.parse(&pSubStream);
fields[i]->m_hasTag = true;
}
}
}
};
#endif // VIEWFORMAT_HPP