00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include <celengine/frame.h>
00011
00012
00013 RigidTransform FrameOfReference::toUniversal(const RigidTransform& xform,
00014 double t) const
00015 {
00016
00017 if (coordSys == astro::Universal)
00018 return xform;
00019 UniversalCoord origin = refObject.getPosition(t);
00020
00021 if (coordSys == astro::Geographic)
00022 {
00023 Quatd rotation(1, 0, 0, 0);
00024 switch (refObject.getType())
00025 {
00026 case Selection::Type_Body:
00027 rotation = refObject.body()->getEclipticalToGeographic(t);
00028 break;
00029 case Selection::Type_Star:
00030 rotation = refObject.star()->getRotationElements().eclipticalToPlanetographic(t);
00031 break;
00032 case Selection::Type_Location:
00033 if (refObject.location()->getParentBody() != NULL)
00034 rotation = refObject.location()->getParentBody()->getEclipticalToGeographic(t);
00035 break;
00036 default:
00037 break;
00038 }
00039
00040 Point3d p = (Point3d) xform.translation * rotation.toMatrix4();
00041 return RigidTransform(origin + Vec3d(p.x, p.y, p.z),
00042 xform.rotation * rotation);
00043 }
00044 else if (coordSys == astro::PhaseLock)
00045 {
00046 Mat3d m;
00047 Vec3d lookDir = refObject.getPosition(t) - targetObject.getPosition(t);
00048 lookDir.normalize();
00049
00050 switch (refObject.getType())
00051 {
00052 case Selection::Type_Body:
00053 {
00054 Body* body = refObject.body();
00055 Vec3d axisDir = Vec3d(0, 1, 0) * body->getEclipticalToEquatorial(t).toMatrix3();
00056 Vec3d v = axisDir ^ lookDir;
00057 v.normalize();
00058 Vec3d u = lookDir ^ v;
00059 m = Mat3d(v, u, lookDir);
00060 }
00061 break;
00062 case Selection::Type_Star:
00063 {
00064 Star* star = refObject.star();
00065 Vec3d axisDir = Vec3d(0, 1, 0) * star->getRotationElements().eclipticalToEquatorial(t).toMatrix3();
00066 Vec3d v = axisDir ^ lookDir;
00067 v.normalize();
00068 Vec3d u = lookDir ^ v;
00069 m = Mat3d(v, u, lookDir);
00070 }
00071 default:
00072 return xform;
00073 }
00074
00075 Point3d p = (Point3d) xform.translation * m;
00076
00077 return RigidTransform(origin + Vec3d(p.x, p.y, p.z),
00078 xform.rotation * Quatd(m));
00079 }
00080 else if (coordSys == astro::Chase)
00081 {
00082 Mat3d m;
00083
00084 switch (refObject.getType())
00085 {
00086 case Selection::Type_Body:
00087 {
00088 Body* body = refObject.body();
00089 Vec3d lookDir = body->getOrbit()->positionAtTime(t) -
00090 body->getOrbit()->positionAtTime(t - 1.0 / 1440.0);
00091 Vec3d axisDir = Vec3d(0, 1, 0) * body->getEclipticalToEquatorial(t).toMatrix3();
00092 lookDir.normalize();
00093 Vec3d v = lookDir ^ axisDir;
00094 v.normalize();
00095 Vec3d u = v ^ lookDir;
00096 m = Mat3d(v, u, -lookDir);
00097 }
00098 break;
00099 default:
00100 return xform;
00101 }
00102
00103 Point3d p = (Point3d) xform.translation * m;
00104
00105 return RigidTransform(origin + Vec3d(p.x, p.y, p.z),
00106 xform.rotation * Quatd(m));
00107 }
00108 else
00109 {
00110 return RigidTransform(origin + xform.translation, xform.rotation);
00111 }
00112 }
00113
00114
00115 RigidTransform FrameOfReference::fromUniversal(const RigidTransform& xform,
00116 double t) const
00117 {
00118
00119 if (coordSys == astro::Universal)
00120 return xform;
00121 UniversalCoord origin = refObject.getPosition(t);
00122
00123 if (coordSys == astro::Geographic)
00124 {
00125 Quatd rotation(1, 0, 0, 0);
00126 switch (refObject.getType())
00127 {
00128 case Selection::Type_Body:
00129 rotation = refObject.body()->getEclipticalToGeographic(t);
00130 break;
00131 case Selection::Type_Star:
00132 rotation = refObject.star()->getRotationElements().eclipticalToPlanetographic(t);
00133 break;
00134 case Selection::Type_Location:
00135 if (refObject.location()->getParentBody() != NULL)
00136 rotation = refObject.location()->getParentBody()->getEclipticalToGeographic(t);
00137 break;
00138 default:
00139 break;
00140 }
00141 Vec3d v = (xform.translation - origin) * (~rotation).toMatrix4();
00142
00143 return RigidTransform(UniversalCoord(v.x, v.y, v.z),
00144 xform.rotation * ~rotation);
00145 }
00146 else if (coordSys == astro::PhaseLock)
00147 {
00148 Mat3d m;
00149 Vec3d lookDir = refObject.getPosition(t) - targetObject.getPosition(t);
00150 lookDir.normalize();
00151
00152 switch (refObject.getType())
00153 {
00154 case Selection::Type_Body:
00155 {
00156 Body* body = refObject.body();
00157 Vec3d axisDir = Vec3d(0, 1, 0) * body->getEclipticalToEquatorial(t).toMatrix3();
00158 Vec3d v = axisDir ^ lookDir;
00159 v.normalize();
00160 Vec3d u = lookDir ^ v;
00161 m = Mat3d(v, u, lookDir);
00162 }
00163 break;
00164
00165 case Selection::Type_Star:
00166 {
00167 Star* star = refObject.star();
00168 Vec3d axisDir = Vec3d(0, 1, 0) * star->getRotationElements().eclipticalToEquatorial(t).toMatrix3();
00169 Vec3d v = axisDir ^ lookDir;
00170 v.normalize();
00171 Vec3d u = lookDir ^ v;
00172 m = Mat3d(v, u, lookDir);
00173 }
00174
00175 default:
00176 return xform;
00177 }
00178
00179 Vec3d v = (xform.translation - origin) * m.transpose();
00180
00181 return RigidTransform(UniversalCoord(v.x, v.y, v.z),
00182 xform.rotation * ~Quatd(m));
00183 }
00184 else if (coordSys == astro::Chase)
00185 {
00186 Mat3d m;
00187
00188 switch (refObject.getType())
00189 {
00190 case Selection::Type_Body:
00191 {
00192 Body* body = refObject.body();
00193 Vec3d lookDir = body->getOrbit()->positionAtTime(t) -
00194 body->getOrbit()->positionAtTime(t - 1.0 / 1440.0);
00195 Vec3d axisDir = Vec3d(0, 1, 0) * body->getEclipticalToEquatorial(t).toMatrix3();
00196 lookDir.normalize();
00197 Vec3d v = lookDir ^ axisDir;
00198 v.normalize();
00199 Vec3d u = v ^ lookDir;
00200 m = Mat3d(v, u, -lookDir);
00201 }
00202 break;
00203
00204 default:
00205 return xform;
00206 }
00207
00208 Vec3d v = (xform.translation - origin) * m.transpose();
00209
00210 return RigidTransform(UniversalCoord(v.x, v.y, v.z),
00211 xform.rotation * ~Quatd(m));
00212 }
00213 else
00214 {
00215 return RigidTransform(xform.translation.difference(origin),
00216 xform.rotation);
00217 }
00218 }