axisarrow.cpp
上传用户:center1979
上传日期:2022-07-26
资源大小:50633k
文件大小:14k
源码类别:

OpenGL

开发平台:

Visual C++

  1. // axisarrow.cpp
  2. //
  3. // Copyright (C) 2007, Celestia Development Team
  4. //
  5. // This program is free software; you can redistribute it and/or
  6. // modify it under the terms of the GNU General Public License
  7. // as published by the Free Software Foundation; either version 2
  8. // of the License, or (at your option) any later version.
  9. #include <algorithm>
  10. #include <celmath/mathlib.h>
  11. #include "gl.h"
  12. #include "vecgl.h"
  13. #include "axisarrow.h"
  14. #include "selection.h"
  15. #include "frame.h"
  16. #include "body.h"
  17. #include "timelinephase.h"
  18. using namespace std;
  19. static const unsigned int MaxArrowSections = 100;
  20. static void RenderArrow(float shaftLength,
  21.                         float headLength,
  22.                         float shaftRadius,
  23.                         float headRadius,
  24.                         unsigned int nSections)
  25. {
  26.     float sintab[MaxArrowSections];
  27.     float costab[MaxArrowSections];
  28.     unsigned int i;
  29.     nSections = min(MaxArrowSections, nSections);
  30.     // Initialize the trig tables
  31.     for (i = 0; i < nSections; i++)
  32.     {
  33.         double theta = (i * 2.0 * PI) / nSections;
  34.         sintab[i] = (float) sin(theta);
  35.         costab[i] = (float) cos(theta);
  36.     }
  37.     // Render the circle at the botton of the arrow shaft
  38.     glBegin(GL_TRIANGLE_FAN);
  39.     glVertex3f(0.0f, 0.0f, 0.0f);
  40.     for (i = 0; i <= nSections; i++)
  41.     {
  42.         unsigned int n = (nSections - i) % nSections;
  43.         glVertex3f(shaftRadius * costab[n], shaftRadius * sintab[n], 0.0f);
  44.     }
  45.     glEnd();
  46.     // Render the arrow shaft
  47.     glBegin(GL_QUAD_STRIP);
  48.     for (i = 0; i <= nSections; i++)
  49.     {
  50.         unsigned int n = i % nSections;
  51.         glVertex3f(shaftRadius * costab[n], shaftRadius * sintab[n], shaftLength);
  52.         glVertex3f(shaftRadius * costab[n], shaftRadius * sintab[n], 0.0f);
  53.     }
  54.     glEnd();
  55.     // Render the annulus
  56.     glBegin(GL_QUAD_STRIP);
  57.     for (i = 0; i <= nSections; i++)
  58.     {
  59.         unsigned int n = i % nSections;
  60.         glVertex3f(headRadius * costab[n],  headRadius * sintab[n], shaftLength);
  61.         glVertex3f(shaftRadius * costab[n], shaftRadius * sintab[n], shaftLength);
  62.     }
  63.     glEnd();
  64.     // Render the head of the arrow
  65.     glBegin(GL_TRIANGLE_FAN);
  66.     glVertex3f(0.0f, 0.0f, shaftLength + headLength);
  67.     for (i = 0; i <= nSections; i++)
  68.     {
  69.         unsigned int n = i % nSections;
  70.         glVertex3f(headRadius * costab[n], headRadius * sintab[n], shaftLength);
  71.     }
  72.     glEnd();
  73. }
  74. // Draw letter x in xz plane
  75. static void RenderX()
  76. {
  77.     glBegin(GL_LINES);
  78.     glVertex3f(0, 0, 0);
  79.     glVertex3f(1, 0, 1);
  80.     glVertex3f(1, 0, 0);
  81.     glVertex3f(0, 0, 1);
  82.     glEnd();
  83. }
  84. // Draw letter y in xz plane
  85. static void RenderY()
  86. {
  87.     glBegin(GL_LINES);
  88.     glVertex3f(0, 0, 1);
  89.     glVertex3f(0.5f, 0, 0.5f);
  90.     glVertex3f(1, 0, 1);
  91.     glVertex3f(0.5f, 0, 0.5f);
  92.     glVertex3f(0.5f, 0, 0);
  93.     glVertex3f(0.5f, 0, 0.5f);
  94.     glEnd();
  95. }
  96. // Draw letter z in xz plane
  97. static void RenderZ()
  98. {
  99.     glBegin(GL_LINE_STRIP);
  100.     glVertex3f(0, 0, 1);
  101.     glVertex3f(1, 0, 1);
  102.     glVertex3f(0, 0, 0);
  103.     glVertex3f(1, 0, 0);
  104.     glEnd();
  105. }
  106. #if 0
  107. void RenderAxisArrows(const Quatf& orientation, float scale, float opacity)
  108. {
  109.     glPushMatrix();
  110.     glRotate(orientation);
  111.     glScalef(scale, scale, scale);
  112.     glDisable(GL_LIGHTING);
  113. #if 0
  114.     // Simple line axes
  115.     glBegin(GL_LINES);
  116.     glColor4f(1.0f, 0.0f, 0.0f, 1.0f);
  117.     glVertex3f(0.0f, 0.0f, 0.0f);
  118.     glVertex3f(-1.0f, 0.0f, 0.0f);
  119.     glColor4f(0.0f, 1.0f, 0.0f, 1.0f);
  120.     glVertex3f(0.0f, 0.0f, 0.0f);
  121.     glVertex3f(0.0f, 0.0f, 1.0f);
  122.     glColor4f(0.0f, 0.0f, 1.0f, 1.0f);
  123.     glVertex3f(0.0f, 0.0f, 0.0f);
  124.     glVertex3f(0.0f, 1.0f, 0.0f);
  125.     glEnd();
  126. #endif
  127.     float shaftLength = 0.85f;
  128.     float headLength = 0.10f;
  129.     float shaftRadius = 0.010f;
  130.     float headRadius = 0.025f;
  131.     unsigned int nSections = 30;
  132.     float labelScale = 0.1f;
  133.     // x-axis
  134.     glPushMatrix();
  135.     glRotatef(90.0f, 0.0f, 1.0f, 0.0f);
  136.     glColor4f(1.0f, 0.0f, 0.0f, opacity);
  137.     RenderArrow(shaftLength, headLength, shaftRadius, headRadius, nSections);
  138.     glTranslatef(0.1f, 0.0f, 0.75f);
  139.     glScalef(labelScale, labelScale, labelScale);
  140.     RenderX();
  141.     glPopMatrix();
  142.     // y-axis
  143.     glPushMatrix();
  144.     glRotatef(180.0f, 0.0f, 1.0f, 0.0f);
  145.     glColor4f(0.0f, 1.0f, 0.0f, opacity);
  146.     RenderArrow(shaftLength, headLength, shaftRadius, headRadius, nSections);
  147.     glTranslatef(0.1f, 0.0f, 0.75f);
  148.     glScalef(labelScale, labelScale, labelScale);
  149.     RenderY();
  150.     glPopMatrix();
  151.     // z-axis
  152.     glPushMatrix();
  153.     glRotatef(-90.0f, 1.0f, 0.0f, 0.0f);
  154.     glColor4f(0.0f, 0.0f, 1.0f, opacity);
  155.     RenderArrow(shaftLength, headLength, shaftRadius, headRadius, nSections);
  156.     glTranslatef(0.1f, 0.0f, 0.75f);
  157.     glScalef(labelScale, labelScale, labelScale);
  158.     RenderZ();
  159.     glPopMatrix();
  160.     glPopMatrix();
  161. }
  162. #endif
  163. void RenderSunDirectionArrow(const Vec3f& direction, float scale, float opacity)
  164. {
  165.     glPushMatrix();
  166.     glRotate(Quatf::vecToVecRotation(Vec3f(0.0f, 0.0f, 1.0f), direction));
  167.     glScalef(scale, scale, scale);
  168.     glDisable(GL_LIGHTING);
  169.     float shaftLength = 0.85f;
  170.     float headLength = 0.10f;
  171.     float shaftRadius = 0.010f;
  172.     float headRadius = 0.025f;
  173.     unsigned int nSections = 30;
  174.     glColor4f(1.0f, 1.0f, 0.0f, opacity);
  175.     RenderArrow(shaftLength, headLength, shaftRadius, headRadius, nSections);
  176.     glPopMatrix();
  177. }
  178. void RenderVelocityArrow(const Vec3f& direction, float scale, float opacity)
  179. {
  180.     glPushMatrix();
  181.     glRotate(Quatf::vecToVecRotation(Vec3f(0.0f, 0.0f, 1.0f), direction));
  182.     glScalef(scale, scale, scale);
  183.     glDisable(GL_LIGHTING);
  184.     float shaftLength = 0.85f;
  185.     float headLength = 0.10f;
  186.     float shaftRadius = 0.010f;
  187.     float headRadius = 0.025f;
  188.     unsigned int nSections = 30;
  189.     glColor4f(0.6f, 0.6f, 0.9f, opacity);
  190.     RenderArrow(shaftLength, headLength, shaftRadius, headRadius, nSections);
  191.     glPopMatrix();
  192. }
  193. /****** ArrowReferenceMark base class ******/
  194. ArrowReferenceMark::ArrowReferenceMark(const Body& _body) :
  195.     body(_body),
  196.     size(1.0),
  197.     color(1.0f, 1.0f, 1.0f),
  198. #ifdef USE_HDR
  199.     opacity(0.0f)
  200. #else
  201.     opacity(1.0f)
  202. #endif
  203. {
  204. }
  205. void
  206. ArrowReferenceMark::setSize(float _size)
  207. {
  208.     size = _size;
  209. }
  210. void
  211. ArrowReferenceMark::setColor(Color _color)
  212. {
  213.     color = _color;
  214. }
  215. void
  216. ArrowReferenceMark::render(Renderer* /* renderer */,
  217.                            const Point3f& /* position */,
  218.                            float /* discSize */,
  219.                            double tdb) const
  220. {
  221.     Vec3d v = getDirection(tdb);
  222.     if (v.length() < 1.0e-12)
  223.     {
  224.         // Skip rendering of zero-length vectors
  225.         return;
  226.     }
  227.     v.normalize();
  228.     Quatd q = Quatd::vecToVecRotation(Vec3d(0.0, 0.0, 1.0), v);
  229.     if (opacity == 1.0f)
  230.     {
  231.         // Enable depth buffering
  232.         glEnable(GL_DEPTH_TEST);
  233.         glDepthMask(GL_TRUE);
  234.         glDisable(GL_BLEND);
  235.     }
  236.     else
  237.     {
  238.         glEnable(GL_DEPTH_TEST);
  239.         glDepthMask(GL_FALSE);
  240.         glEnable(GL_BLEND);
  241. #ifdef USE_HDR
  242.         glBlendFunc(GL_ONE_MINUS_SRC_ALPHA, GL_SRC_ALPHA);
  243. #else
  244.         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  245. #endif
  246.     }
  247.     glPushMatrix();
  248.     glRotate(Quatf((float) q.w, (float) q.x, (float) q.y, (float) q.z));
  249.     glScalef(size, size, size);
  250.     glDisable(GL_LIGHTING);
  251.     glDisable(GL_TEXTURE_2D);
  252.     float shaftLength = 0.85f;
  253.     float headLength = 0.10f;
  254.     float shaftRadius = 0.010f;
  255.     float headRadius = 0.025f;
  256.     unsigned int nSections = 30;
  257.     glColor4f(color.red(), color.green(), color.blue(), opacity);
  258.     RenderArrow(shaftLength, headLength, shaftRadius, headRadius, nSections);
  259.     glPopMatrix();
  260.     glDisable(GL_DEPTH_TEST);
  261.     glDepthMask(GL_FALSE);
  262.     glEnable(GL_TEXTURE_2D);
  263.     glEnable(GL_BLEND);
  264.     glBlendFunc(GL_SRC_ALPHA, GL_ONE);
  265. }
  266. /****** AxesReferenceMark base class ******/
  267. AxesReferenceMark::AxesReferenceMark(const Body& _body) :
  268.     body(_body),
  269.     size(),
  270. #ifdef USE_HDR
  271.     opacity(0.0f)
  272. #else
  273.     opacity(1.0f)
  274. #endif
  275. {
  276. }
  277. void
  278. AxesReferenceMark::setSize(float _size)
  279. {
  280.     size = _size;
  281. }
  282. void
  283. AxesReferenceMark::setOpacity(float _opacity)
  284. {
  285.     opacity = _opacity;
  286. #ifdef USE_HDR
  287.     opacity = 1.0f - opacity;
  288. #endif
  289. }
  290. void
  291. AxesReferenceMark::render(Renderer* /* renderer */,
  292.                           const Point3f& /* position */,
  293.                           float /* discSize */,
  294.                           double tdb) const
  295. {
  296.     Quatd q = getOrientation(tdb);
  297.     if (opacity == 1.0f)
  298.     {
  299.         // Enable depth buffering
  300.         glEnable(GL_DEPTH_TEST);
  301.         glDepthMask(GL_TRUE);
  302.         glDisable(GL_BLEND);
  303.     }
  304.     else
  305.     {
  306.         glEnable(GL_DEPTH_TEST);
  307.         glDepthMask(GL_FALSE);
  308.         glEnable(GL_BLEND);
  309. #ifdef USE_HDR
  310.         glBlendFunc(GL_ONE_MINUS_SRC_ALPHA, GL_SRC_ALPHA);
  311. #else
  312.         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  313. #endif
  314.     }
  315.     glDisable(GL_TEXTURE_2D);
  316.     glPushMatrix();
  317.     glRotate(Quatf((float) q.w, (float) q.x, (float) q.y, (float) q.z));
  318.     glScalef(size, size, size);
  319.     glDisable(GL_LIGHTING);
  320. #if 0
  321.     // Simple line axes
  322.     glBegin(GL_LINES);
  323.     glColor4f(1.0f, 0.0f, 0.0f, 1.0f);
  324.     glVertex3f(0.0f, 0.0f, 0.0f);
  325.     glVertex3f(-1.0f, 0.0f, 0.0f);
  326.     glColor4f(0.0f, 1.0f, 0.0f, 1.0f);
  327.     glVertex3f(0.0f, 0.0f, 0.0f);
  328.     glVertex3f(0.0f, 0.0f, 1.0f);
  329.     glColor4f(0.0f, 0.0f, 1.0f, 1.0f);
  330.     glVertex3f(0.0f, 0.0f, 0.0f);
  331.     glVertex3f(0.0f, 1.0f, 0.0f);
  332.     glEnd();
  333. #endif
  334.     float shaftLength = 0.85f;
  335.     float headLength = 0.10f;
  336.     float shaftRadius = 0.010f;
  337.     float headRadius = 0.025f;
  338.     unsigned int nSections = 30;
  339.     float labelScale = 0.1f;
  340.     // x-axis
  341.     glPushMatrix();
  342.     glRotatef(90.0f, 0.0f, 1.0f, 0.0f);
  343.     glColor4f(1.0f, 0.0f, 0.0f, opacity);
  344.     RenderArrow(shaftLength, headLength, shaftRadius, headRadius, nSections);
  345.     glTranslatef(0.1f, 0.0f, 0.75f);
  346.     glScalef(labelScale, labelScale, labelScale);
  347.     RenderX();
  348.     glPopMatrix();
  349.     // y-axis
  350.     glPushMatrix();
  351.     glRotatef(180.0f, 0.0f, 1.0f, 0.0f);
  352.     glColor4f(0.0f, 1.0f, 0.0f, opacity);
  353.     RenderArrow(shaftLength, headLength, shaftRadius, headRadius, nSections);
  354.     glTranslatef(0.1f, 0.0f, 0.75f);
  355.     glScalef(labelScale, labelScale, labelScale);
  356.     RenderY();
  357.     glPopMatrix();
  358.     // z-axis
  359.     glPushMatrix();
  360.     glRotatef(-90.0f, 1.0f, 0.0f, 0.0f);
  361.     glColor4f(0.0f, 0.0f, 1.0f, opacity);
  362.     RenderArrow(shaftLength, headLength, shaftRadius, headRadius, nSections);
  363.     glTranslatef(0.1f, 0.0f, 0.75f);
  364.     glScalef(labelScale, labelScale, labelScale);
  365.     RenderZ();
  366.     glPopMatrix();
  367.     glPopMatrix();
  368.     glDisable(GL_DEPTH_TEST);
  369.     glDepthMask(GL_FALSE);
  370.     glEnable(GL_TEXTURE_2D);
  371.     glEnable(GL_BLEND);
  372.     glBlendFunc(GL_SRC_ALPHA, GL_ONE);
  373. }
  374. /****** VelocityVectorArrow implementation ******/
  375. VelocityVectorArrow::VelocityVectorArrow(const Body& _body) :
  376.     ArrowReferenceMark(_body)
  377. {
  378.     setTag("velocity vector");
  379.     setColor(Color(0.6f, 0.6f, 0.9f));
  380.     setSize(body.getRadius() * 2.0f);
  381. }
  382. Vec3d
  383. VelocityVectorArrow::getDirection(double tdb) const
  384. {
  385.     const TimelinePhase* phase = body.getTimeline()->findPhase(tdb);
  386.     return phase->orbit()->velocityAtTime(tdb) *
  387.         phase->orbitFrame()->getOrientation(tdb).toMatrix3();
  388. }
  389. /****** SunDirectionArrow implementation ******/
  390. SunDirectionArrow::SunDirectionArrow(const Body& _body) :
  391.     ArrowReferenceMark(_body)
  392. {
  393.     setTag("sun direction");
  394.     setColor(Color(1.0f, 1.0f, 0.4f));
  395.     setSize(body.getRadius() * 2.0f);
  396. }
  397. Vec3d
  398. SunDirectionArrow::getDirection(double tdb) const
  399. {
  400.     const Body* b = &body;
  401.     Star* sun = NULL;
  402.     while (b != NULL)
  403.     {
  404.         Selection center = b->getOrbitFrame(tdb)->getCenter();
  405.         if (center.star() != NULL)
  406.             sun = center.star();
  407.         b = center.body();
  408.     }
  409.     if (sun != NULL)
  410.     {
  411.         return Selection(sun).getPosition(tdb) - body.getPosition(tdb);
  412.     }
  413.     else
  414.     {
  415.         return Vec3d(0.0, 0.0, 0.0);
  416.     }
  417. }
  418. /****** SpinVectorArrow implementation ******/
  419. SpinVectorArrow::SpinVectorArrow(const Body& _body) :
  420.     ArrowReferenceMark(_body)
  421. {
  422.     setTag("spin vector");
  423.     setColor(Color(0.6f, 0.6f, 0.6f));
  424.     setSize(body.getRadius() * 2.0f);
  425. }
  426. Vec3d
  427. SpinVectorArrow::getDirection(double tdb) const
  428. {
  429.     const TimelinePhase* phase = body.getTimeline()->findPhase(tdb);
  430.     return phase->rotationModel()->angularVelocityAtTime(tdb) *
  431.         phase->bodyFrame()->getOrientation(tdb).toMatrix3();
  432. #if 0
  433.     return body.getRotationModel(tdb)->angularVelocityAtTime(tdb) *
  434.         body.getEclipticToFrame(tdb).toMatrix3();
  435. #endif
  436. }
  437. /****** BodyToBodyDirectionArrow implementation ******/
  438. /*! Create a new body-to-body direction arrow pointing from the origin body toward
  439.  *  the specified target object.
  440.  */
  441. BodyToBodyDirectionArrow::BodyToBodyDirectionArrow(const Body& _body, const Selection& _target) :
  442.     ArrowReferenceMark(_body),
  443.     target(_target)
  444. {
  445.     setTag("body to body");
  446.     setColor(Color(0.0f, 0.5f, 0.0f));
  447.     setSize(body.getRadius() * 2.0f);
  448. }
  449. Vec3d
  450. BodyToBodyDirectionArrow::getDirection(double tdb) const
  451. {
  452.     return target.getPosition(tdb) - body.getPosition(tdb);
  453. }
  454. /****** BodyAxisArrows implementation ******/
  455. BodyAxisArrows::BodyAxisArrows(const Body& _body) :
  456.     AxesReferenceMark(_body)
  457. {
  458.     setTag("body axes");
  459.     setOpacity(1.0);
  460.     setSize(body.getRadius() * 2.0f);
  461. }
  462. Quatd
  463. BodyAxisArrows::getOrientation(double tdb) const
  464. {
  465.     return ~(Quatd::yrotation(PI) * body.getEclipticToBodyFixed(tdb));
  466. }
  467. /****** FrameAxisArrows implementation ******/
  468. FrameAxisArrows::FrameAxisArrows(const Body& _body) :
  469.     AxesReferenceMark(_body)
  470. {
  471.     setTag("frame axes");
  472.     setOpacity(0.5);
  473.     setSize(body.getRadius() * 2.0f);
  474. }
  475. Quatd
  476. FrameAxisArrows::getOrientation(double tdb) const
  477. {
  478.     return ~body.getEclipticToFrame(tdb);
  479. }