Christophe Teyssier's cel: URL implementation.

ver1_5_1
Chris Laurel 2002-11-03 20:33:30 +00:00
parent d0ddfc0781
commit 053534ec2d
2 changed files with 426 additions and 0 deletions

View File

@ -0,0 +1,355 @@
/***************************************************************************
url.cpp - description
-------------------
begin : Wed Aug 7 2002
copyright : (C) 2002 by chris
email : chris@tux.teyssier.org
***************************************************************************/
/***************************************************************************
* *
* 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. *
* *
***************************************************************************/
#include <string>
#include <stdio.h>
#include "celestiacore.h"
#include "celengine/astro.h"
#include "url.h"
Url::Url(const std::string& str, CelestiaCore *core) {
urlStr = str;
appCore = core;
std::string::size_type pos, endPrevious;
std::vector<Selection> bodies;
Simulation *sim = appCore->getSimulation();
std::map<std::string, std::string> params = parseUrlParams(urlStr);
if (urlStr.substr(0, 6) != "cel://") {
urlStr = "";
return;
}
pos = urlStr.find("/", 6);
if (pos == std::string::npos) pos = urlStr.find("?", 6);
if (pos == std::string::npos) modeStr = urlStr.substr(6);
else modeStr = decode_string(urlStr.substr(6, pos - 6));
if (modeStr == "Freeflight") {
mode = astro::Universal;
nbBodies = 0;
}
if (modeStr == "Follow") {
mode = astro::Ecliptical;
nbBodies = 1;
}
if (modeStr == "SyncOrbit") {
mode = astro::Geographic;
nbBodies = 1;
}
if (modeStr == "Chase") {
mode = astro::Chase;
nbBodies = 1;
}
if (modeStr == "PhaseLock") {
mode = astro::PhaseLock;
nbBodies = 2;
}
if (nbBodies == -1) {
urlStr = "";
return; // Mode not recognized
}
endPrevious = pos;
int nb = nbBodies, i=1;
while (nb != 0 && endPrevious != std::string::npos) {
std::string bodyName="";
pos = urlStr.find("/", endPrevious + 1);
if (pos == std::string::npos) pos = urlStr.find("?", endPrevious + 1);
if (pos == std::string::npos) bodyName = urlStr.substr(endPrevious + 1);
else bodyName = urlStr.substr(endPrevious + 1, pos - endPrevious - 1);
endPrevious = pos;
bodyName = decode_string(bodyName);
pos = 0;
if (i==1) body1 = bodyName;
if (i==2) body2 = bodyName;
while(pos != std::string::npos) {
pos = bodyName.find(":", pos + 1);
if (pos != std::string::npos) bodyName[pos]='/';
}
bodies.push_back(sim->findObjectFromPath(bodyName));
nb--;
i++;
}
if (nb != 0) {
urlStr = "";
return; // Number of bodies in Url doesn't match Mode
}
if (nbBodies == 0) ref = FrameOfReference();
if (nbBodies == 1) ref = FrameOfReference(mode, bodies[0]);
if (nbBodies == 2) ref = FrameOfReference(mode, bodies[0], bodies[1]);
fromString = true;
std::string time="";
pos = urlStr.find("?", endPrevious + 1);
if (pos == std::string::npos) time = urlStr.substr(endPrevious + 1);
else time = urlStr.substr(endPrevious + 1, pos - endPrevious -1);
time = decode_string(time);
int t;
date = astro::Date(0.0);
sscanf(time.substr(0, 4).c_str(), "%04d", &t);
date.year=t;
sscanf(time.substr(5, 2).c_str(), "%02d", &t);
date.month=t;
sscanf(time.substr(8, 2).c_str(), "%02d", &t);
date.day=t;
sscanf(time.substr(11, 2).c_str(), "%02d", &t);
date.hour=t;
sscanf(time.substr(14, 2).c_str(), "%02d", &t);
date.minute=t;
sscanf(time.substr(17, 2).c_str(), "%02d", &t);
date.seconds=float(t);
BigFix x(params["x"].c_str()), y(params["y"].c_str()), z(params["z"].c_str());
coord = UniversalCoord(x,y,z);
float ow, ox, oy, oz;
sscanf(params["ow"].c_str(), "%f", &ow);
sscanf(params["ox"].c_str(), "%f", &ox);
sscanf(params["oy"].c_str(), "%f", &oy);
sscanf(params["oz"].c_str(), "%f", &oz);
orientation = Quatf(ow, ox, oy, oz);
if (params["fov"] != "") {
sscanf(params["fov"].c_str(), "%f", &fieldOfView);
}
if (params["ts"] != "") {
sscanf(params["ts"].c_str(), "%f", &timeScale);
}
if (params["rf"] != "") {
sscanf(params["rf"].c_str(), "%d", &renderFlags);
}
if (params["lm"] != "") {
sscanf(params["lm"].c_str(), "%d", &labelMode);
}
if (params["select"] != "") {
selectedStr = params["select"];
}
if (params["track"] != "") {
trackedStr = params["track"];
}
name = modeStr;
if (body1 != "") name += " " + getBodyShortName(body1);
if (body2 != "") name += " " + getBodyShortName(body2);
if (trackedStr != "") name += " -> " + getBodyShortName(trackedStr);
if (selectedStr != "") name += " [" + getBodyShortName(selectedStr) + "]";
}
Url::Url(CelestiaCore* core) {
appCore = core;
Simulation *sim = appCore->getSimulation();
Renderer *renderer = appCore->getRenderer();
modeStr = getCoordSysName(sim->getFrame().coordSys);
ref = sim->getFrame();
urlStr += "cel://" + modeStr;
if (sim->getFrame().coordSys != astro::Universal) {
body1 = getSelectionName(sim->getFrame().refObject);
urlStr += "/" + body1;
if (sim->getFrame().coordSys == astro::PhaseLock) {
body2 = getSelectionName(sim->getFrame().targetObject);
urlStr += "/" + body2;
}
}
char date_str[30];
date = astro::Date(sim->getTime());
sprintf(date_str, "%04d-%02d-%02dT%02d:%02d:%02d",
date.year, date.month, date.day, date.hour, date.minute, int(date.seconds));
coord = sim->getObserver().getPosition();
urlStr += std::string("/") + date_str + "?x=" + coord.x.toString();
urlStr += "&y=" + coord.y.toString();
urlStr += "&z=" + coord.z.toString();
orientation = sim->getObserver().getOrientation();
char buff[255];
sprintf(buff, "&ow=%f&ox=%f&oy=%f&oz=%f", orientation.w, orientation.x, orientation.y, orientation.z);
urlStr += buff;
tracked = sim->getTrackedObject();
trackedStr = getSelectionName(tracked);
if (trackedStr != "") urlStr += "&track=" + trackedStr;
selected = sim->getSelection();
selectedStr = getSelectionName(selected);
if (selectedStr != "") urlStr += "&select=" + selectedStr;
fieldOfView = renderer->getFieldOfView();
timeScale = sim->getTimeScale();
renderFlags = renderer->getRenderFlags();
labelMode = renderer->getLabelMode();
sprintf(buff, "&fov=%f&ts=%f&rf=%d&lm=%d", fieldOfView,
timeScale, renderFlags, labelMode);
urlStr += buff;
name = modeStr;
if (body1 != "") name += " " + getBodyShortName(body1);
if (body2 != "") name += " " + getBodyShortName(body2);
if (trackedStr != "") name += " -> " + getBodyShortName(trackedStr);
if (selectedStr != "") name += " [" + getBodyShortName(selectedStr) + "]";
}
std::string Url::getAsString() const {
return urlStr;
}
std::string Url::getName() const {
return name;
}
std::string Url::getBodyShortName(const std::string& body) const {
std::string::size_type pos;
if (body != "") {
pos = body.rfind(":");
if (pos != std::string::npos) return body.substr(pos+1);
else return body;
}
return "";
}
std::map<std::string, std::string> Url::parseUrlParams(const std::string& url) const{
std::string::size_type pos, startName, startValue;
std::map<std::string, std::string> params;
pos = url.find("?");
while (pos != std::string::npos) {
startName = pos + 1;
startValue = url.find("=", startName);
pos = url.find("&", pos + 1);
if (startValue != std::string::npos) {
startValue++;
if (pos != std::string::npos)
params[url.substr(startName, startValue - startName -1)] = decode_string(url.substr(startValue, pos - startValue));
else
params[url.substr(startName, startValue - startName -1)] = decode_string(url.substr(startValue));
}
}
return params;
}
std::string Url::getCoordSysName(astro::CoordinateSystem mode) const {
switch (mode) {
case astro::Universal:
return "Freeflight";
case astro::Ecliptical:
return "Follow";
case astro::Geographic:
return "SyncOrbit";
case astro::Chase:
return "Chase";
case astro::PhaseLock:
return "PhaseLock";
}
return "Unknown";
}
std::string Url::getSelectionName(const Selection& selection) const {
Universe *universe = appCore->getSimulation()->getUniverse();
if (selection.body != 0) {
std::string name=selection.body->getName();
if (selection.body->getSystem() != 0) {
if (selection.body->getSystem()->getPrimaryBody() != 0) {
name=selection.body->getSystem()->getPrimaryBody()->getName() + ":" + name;
}
if (selection.body->getSystem()->getStar() != 0) {
name=universe->getStarCatalog()->getStarName(*(selection.body->getSystem()->getStar()))
+ ":" + name;
}
}
return name;
}
if (selection.star != 0) return universe->getStarCatalog()->getStarName(*selection.star);
if (selection.galaxy != 0) return selection.galaxy->getName();
return "";
}
void Url::goTo() {
if (urlStr == "") return;
Simulation *sim = appCore->getSimulation();
Renderer *renderer = appCore->getRenderer();
std::string::size_type pos;
sim->setTime((double) date);
sim->update(0.0);
sim->setFrame(ref);
sim->setObserverPosition(coord);
sim->setObserverOrientation(orientation);
renderer->setFieldOfView(fieldOfView);
sim->setTimeScale(timeScale);
renderer->setRenderFlags(renderFlags);
renderer->setLabelMode(labelMode);
pos = 0;
while(pos != std::string::npos) {
pos = selectedStr.find(":", pos + 1);
if (pos != std::string::npos) selectedStr[pos]='/';
Selection sel = sim->findObjectFromPath(selectedStr);
sim->setSelection(sel);
}
pos = 0;
while(pos != std::string::npos) {
pos = trackedStr.find(":", pos + 1);
if (pos != std::string::npos) trackedStr[pos]='/';
Selection sel = sim->findObjectFromPath(trackedStr);
sim->setTrackedObject(sel);
}
}
Url::~Url() {
}
std::string Url::decode_string(const std::string& str) {
std::string::size_type a=0, b;
std::string out = "";
b = str.find("%");
while (b != std::string::npos) {
char c;
out += str.substr(a, b-a);
std::string c_code = str.substr(b+1, 2);
sscanf(c_code.c_str(), "%02x", &c);
out += c;
a = b + 3;
b = str.find("%", a);
}
out += str.substr(a);
return out;
}

71
src/celestia/url.h 100644
View File

@ -0,0 +1,71 @@
/***************************************************************************
url.h - description
-------------------
begin : Wed Aug 7 2002
copyright : (C) 2002 by chris
email : chris@tux.teyssier.org
***************************************************************************/
/***************************************************************************
* *
* 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. *
* *
***************************************************************************/
#ifndef _URL_H_
#define _URL_H_
#include <string>
#include "celestiacore.h"
#include "celengine/astro.h"
class CelestiaCore;
class Url
{
public:
// parses str
Url(const std::string& str, CelestiaCore *core);
// current url of appCore
Url(CelestiaCore* appCore);
~Url();
std::string getAsString() const;
std::string getName() const;
void goTo();
private:
std::string urlStr, name;
std::string modeStr;
std::string body1, body2, selectedStr, trackedStr;
CelestiaCore *appCore;
FrameOfReference ref;
Selection selected;
Selection tracked;
astro::CoordinateSystem mode;
int nbBodies;
UniversalCoord coord;
Quatf orientation;
float fieldOfView;
float timeScale;
int renderFlags;
int labelMode;
astro::Date date;
std::map<std::string, std::string> parseUrlParams(const std::string& url) const;
std::string getCoordSysName(astro::CoordinateSystem mode) const;
std::string getSelectionName(const Selection& selection) const;
std::string getBodyShortName(const std::string& body) const;
static std::string decode_string(const std::string& str);
bool fromString;
};
#endif