debrisgeo.cpp 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. #include "pch.h"
  2. //////////////////////////////////////////////////////////////////////////////
  3. //
  4. // DebrisGeo
  5. //
  6. //////////////////////////////////////////////////////////////////////////////
  7. const float maxDistance = 100;
  8. class DebrisGeo : public Geo {
  9. private:
  10. class DebrisData {
  11. public:
  12. Vector m_position;
  13. Color m_color;
  14. float m_startTime;
  15. };
  16. typedef TList<DebrisData> DebrisDataList;
  17. DebrisDataList m_listData;
  18. TRef<Surface> m_psurface;
  19. float m_time;
  20. Vector m_positionLast;
  21. Number* GetTime() { return Number::Cast(GetChild(0)); }
  22. Viewport* GetViewport() { return Viewport::Cast(GetChild(1)); }
  23. Camera* GetCamera() { return GetViewport()->GetCamera(); }
  24. RectValue* GetViewRect() { return GetViewport()->GetViewRect(); }
  25. public:
  26. DebrisGeo(Modeler* pmodeler, Number* ptime, Viewport* pviewport) :
  27. Geo(ptime, pviewport)
  28. {
  29. m_positionLast = GetCamera()->GetPosition();
  30. m_psurface = pmodeler->LoadSurface("debris1bmp", true);
  31. }
  32. void Evaluate()
  33. {
  34. const Rect& rect = GetViewRect()->GetValue();
  35. Camera* pcamera = GetCamera();
  36. float focus = pcamera->GetFocus();
  37. float rfocus = 1.0f / focus;
  38. const Vector& position = pcamera->GetPosition();
  39. Orientation orient = pcamera->GetOrientation();
  40. Vector forward = orient.GetForward();
  41. Vector up = orient.GetUp();
  42. Vector right = orient.GetRight();
  43. //
  44. // save the current time
  45. //
  46. m_time = GetTime()->GetValue();
  47. //
  48. // how far did we move?
  49. //
  50. float length = (m_positionLast - position).Length();
  51. if (length > 100) {
  52. //
  53. // we jumped clear everything
  54. //
  55. m_listData.SetEmpty();
  56. length = 0;
  57. } else {
  58. //
  59. // remove any debris that are too far away from the ship
  60. //
  61. DebrisDataList::Iterator iter(m_listData);
  62. while (!iter.End()) {
  63. DebrisData& data = iter.Value();
  64. float time = m_time - data.m_startTime;
  65. float bright = 1.0f - 0.25f * time * time;
  66. float distance = (data.m_position - position).LengthSquared();
  67. if (bright <= 0 || distance > 250000) {
  68. iter.Remove();
  69. } else {
  70. iter.Next();
  71. }
  72. }
  73. //
  74. // if we are moving add new debris
  75. //
  76. while (length > 0) {
  77. m_listData.PushFront();
  78. DebrisData& data = m_listData.GetFront();
  79. float angle = random(0, 2 * pi);
  80. float distance = maxDistance * sqrt(random(0, 1));
  81. float radius = rfocus * distance * sqrt(random(0, 1));
  82. float c = radius * cos(angle);
  83. float s = radius * sin(angle);
  84. data.m_position =
  85. position
  86. + distance * forward
  87. + c * right
  88. + s * up;
  89. data.m_color =
  90. Color(
  91. random(0.50f, 0.75f),
  92. random(0.75f, 1.00f),
  93. random(0.75f, 1.00f)
  94. );
  95. data.m_startTime = m_time;
  96. length -= 1.0f;
  97. }
  98. }
  99. m_positionLast = position;
  100. }
  101. void Render(Context* pcontext)
  102. {
  103. const Vector& position = GetCamera()->GetPosition();
  104. float scale = 0.1f / GetCamera()->GetFocus();
  105. DebrisDataList::Iterator iter(m_listData);
  106. while (!iter.End()) {
  107. DebrisData& data = iter.Value();
  108. float time = m_time - data.m_startTime;
  109. float bright = 1.0f - 0.25f * time * time;
  110. float distance = (data.m_position - position).LengthSquared();
  111. if (distance > 400) {
  112. pcontext->DrawDecal(
  113. m_psurface,
  114. bright * data.m_color,
  115. data.m_position,
  116. Vector::GetZero(),
  117. Vector::GetZero(),
  118. scale,
  119. 0
  120. );
  121. }
  122. iter.Next();
  123. }
  124. }
  125. //////////////////////////////////////////////////////////////////////////////
  126. //
  127. // Value members
  128. //
  129. //////////////////////////////////////////////////////////////////////////////
  130. ZString GetFunctionName() { return "DebrisGeo"; }
  131. };
  132. TRef<Geo> CreateDebrisGeo(Modeler* pmodeler, Number* ptime, Viewport* pviewport)
  133. {
  134. return new DebrisGeo(pmodeler, ptime, pviewport);
  135. }