/* -*- C++ -*- * Copyright ©2004 Hugo Mills * * This software is distributed under the terms of the GNU GPL v3 * For more information on the GPL, see the file COPYING or * visit http://www.gnu.org/ * * This software is distributed without warranty */ #include "xforbit_circular.h" #include "magellan/xfsphere.h" extern "C" PluginInfo* getmodules(int i) { if(i==0) { PluginInfo_Orbit* pi = new PluginInfo_Orbit(); pi->name = "Circular Orbit"; pi->author = "Hugo Mills"; pi->copyright = "©2005, 2008 Hugo Mills"; pi->version = 0x00700; pi->parser = XfOrbit_Circular::parser; return pi; } else return NULL; } XfOrbit* XfOrbit_Circular::parser( ConfigLexer* lex, const std::string& type, const std::string& subtype ) { if(type != "circular") return NULL; double nodes = 0.0; double angle = 0.0; long period = 3600; long timeorigin = time(NULL); double precession = 0.0; bool upright = false; while(!lex->eos()) { if(readkeyedvalue(lex, "nodes", &nodes) || readkeyedvalue(lex, "angle", &angle) || readkeyedvalue(lex, "period", &period) || readkeyedvalue(lex, "precession", &precession) || readbooleanvalue(lex, "upright", &upright) ) ; else { if(lex->type() == TOKEN && lex->value() == "time-origin") { lex->next(); if(lex->type() == TOKEN && lex->value() == "now") { timeorigin = time(NULL); lex->next(); if(lex->type() != CHAR || lex->value() != ";") // Syntax error -- missing semicolon? throw(MissingSemicolon(lex)); } /* else if(lex->type() == STRING) { // Parse date and set timeorigin lex->next(); } */ else if(lex->type() == INTEGER) { // Parse date and set timeorigin timeorigin = time(NULL); int offset = atoi(lex->value().c_str()); timeorigin += offset; lex->next(); if(lex->type() != CHAR || lex->value() != ";") // Syntax error -- missing semicolon? throw(MissingSemicolon(lex)); } else throw(UnknownConfigToken(lex)); } else throw(UnknownConfigToken(lex)); lex->next(); } } return new XfOrbit_Circular(degrad(nodes), degrad(angle), period, timeorigin, degrad(precession), upright); } XfOrbit_Circular::XfOrbit_Circular( double n, double a, long p, long t, double pr, bool up ) : XfOrbit(), nodes(n), angle(a), period(p), timeorigin(t), precession(pr), upright(up) // , cameraangle(ca) { reset(); } void XfOrbit_Circular::reset(void) { long tm = time(NULL) - timeorigin; double nnodes = nodes + precession * (double(tm)/double(period)); double orbitpos = double(tm)/double(period)*2*M_PI; if(upright) { dmat3 round; dmat3 ecliptic; dmat3 noderot; dmat3 tmp; rot_mat(round, RA_Y, -orbitpos); rot_mat(ecliptic, RA_Z, angle); rot_mat(noderot, RA_Y, -nnodes); dvec3 pre; dvec3 post; // Point on the sphere below the camera (before movement) pre[0] = 0; pre[1] = 0; pre[2] = 1; vmul3(post, round, pre); vmul3(pre, ecliptic, post); vmul3(post, noderot, pre); // Convert to lat/long XfSphere sph; dvec2 ll; sph.g(ll, post); setmatrices(ll[0], ll[1]); } else { dmat3 round; dmat3 ecliptic; dmat3 noderot; dmat3 tmp; rot_mat(round, RA_Y, orbitpos); rot_mat(ecliptic, RA_Z, -angle); rot_mat(noderot, RA_Y, nnodes); mmul3(tmp, round, ecliptic); mmul3(matrix, tmp, noderot); rot_mat(round, RA_Y, -orbitpos); rot_mat(ecliptic, RA_Z, angle); rot_mat(noderot, RA_Y, -nnodes); mmul3(tmp, ecliptic, round); mmul3(imatrix, noderot, tmp); } }