PageRenderTime 56ms CodeModel.GetById 14ms RepoModel.GetById 1ms app.codeStats 0ms

/contrib/bobtoolz/DTrainDrawer.cpp

https://gitlab.com/illwieckz/netradiant
C++ | 331 lines | 239 code | 73 blank | 19 comment | 41 complexity | 55a4b740e9e4b35316441230b33a8c26 MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.1, LGPL-2.0
  1. /*
  2. BobToolz plugin for GtkRadiant
  3. Copyright (C) 2001 Gordon Biggans
  4. This library is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU Lesser General Public
  6. License as published by the Free Software Foundation; either
  7. version 2.1 of the License, or (at your option) any later version.
  8. This library is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. Lesser General Public License for more details.
  12. You should have received a copy of the GNU Lesser General Public
  13. License along with this library; if not, write to the Free Software
  14. Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  15. */
  16. #include "DTrainDrawer.h"
  17. #include <list>
  18. #include "str.h"
  19. #include "DPoint.h"
  20. #include "DPlane.h"
  21. #include "DBrush.h"
  22. #include "DEPair.h"
  23. #include "DPatch.h"
  24. #include "DEntity.h"
  25. #include "misc.h"
  26. #include "funchandlers.h"
  27. #include "iglrender.h"
  28. #include "ientity.h"
  29. #include "math/matrix.h"
  30. #include "dialogs/dialogs-gtk.h"
  31. DTrainDrawer::DTrainDrawer() {
  32. m_bDisplay = false;
  33. BuildPaths();
  34. constructShaders();
  35. GlobalShaderCache().attachRenderable( *this );
  36. }
  37. DTrainDrawer::~DTrainDrawer( void ) {
  38. GlobalShaderCache().detachRenderable( *this );
  39. destroyShaders();
  40. ClearPoints();
  41. ClearSplines();
  42. }
  43. void DTrainDrawer::ClearSplines() {
  44. for ( std::list<splinePoint_t *>::const_iterator deadSpline = m_splineList.begin(); deadSpline != m_splineList.end(); deadSpline++ ) {
  45. ( *deadSpline )->m_pointList.clear();
  46. ( *deadSpline )->m_vertexList.clear();
  47. delete ( *deadSpline );
  48. }
  49. m_splineList.clear();
  50. }
  51. void DTrainDrawer::ClearPoints() {
  52. for ( std::list<controlPoint_t *>::const_iterator deadPoint = m_pointList.begin(); deadPoint != m_pointList.end(); deadPoint++ ) {
  53. delete *deadPoint;
  54. }
  55. m_pointList.clear();
  56. }
  57. void CalculateSpline_r( vec3_t* v, int count, vec3_t out, float tension ) {
  58. vec3_t dist;
  59. if ( count < 2 ) {
  60. return;
  61. }
  62. if ( count == 2 ) {
  63. VectorSubtract( v[1], v[0], dist );
  64. VectorMA( v[0], tension, dist, out );
  65. return;
  66. }
  67. vec3_t* v2 = new vec3_t[count - 1];
  68. for ( int i = 0; i < count - 1; i++ ) {
  69. VectorSubtract( v[i + 1], v[i], dist );
  70. VectorMA( v[i], tension, dist, v2[i] );
  71. }
  72. CalculateSpline_r( v2, count - 1, out, tension );
  73. delete[] v2;
  74. }
  75. void DTrainDrawer::render( RenderStateFlags state ) const {
  76. for ( std::list<splinePoint_t* >::const_iterator sp = m_splineList.begin(); sp != m_splineList.end(); sp++ ) {
  77. splinePoint_t* pSP = ( *sp );
  78. glBegin( GL_LINE_STRIP );
  79. for ( std::list<DPoint >::const_iterator v = pSP->m_vertexList.begin(); v != pSP->m_vertexList.end(); v++ ) {
  80. glVertex3fv( ( *v )._pnt );
  81. }
  82. glEnd();
  83. }
  84. }
  85. const char* DTrainDrawer_state_wireframe = "$bobtoolz/traindrawer/wireframe";
  86. const char* DTrainDrawer_state_solid = "$bobtoolz/traindrawer/solid";
  87. void DTrainDrawer::constructShaders(){
  88. OpenGLState state;
  89. GlobalOpenGLStateLibrary().getDefaultState( state );
  90. state.m_state = RENDER_COLOURWRITE | RENDER_DEPTHWRITE | RENDER_BLEND;
  91. state.m_sort = OpenGLState::eSortOverlayFirst;
  92. state.m_linewidth = 1;
  93. state.m_colour[0] = 1;
  94. state.m_colour[1] = 0;
  95. state.m_colour[2] = 0;
  96. state.m_colour[3] = 1;
  97. state.m_linewidth = 1;
  98. GlobalOpenGLStateLibrary().insert( DTrainDrawer_state_wireframe, state );
  99. state.m_colour[0] = 1;
  100. state.m_colour[1] = 1;
  101. state.m_colour[2] = 1;
  102. state.m_colour[3] = 1;
  103. state.m_linewidth = 2;
  104. GlobalOpenGLStateLibrary().insert( DTrainDrawer_state_solid, state );
  105. m_shader_wireframe = GlobalShaderCache().capture( DTrainDrawer_state_wireframe );
  106. m_shader_solid = GlobalShaderCache().capture( DTrainDrawer_state_solid );
  107. }
  108. void DTrainDrawer::destroyShaders(){
  109. GlobalOpenGLStateLibrary().erase( DTrainDrawer_state_wireframe );
  110. GlobalOpenGLStateLibrary().erase( DTrainDrawer_state_solid );
  111. GlobalShaderCache().release( DTrainDrawer_state_wireframe );
  112. GlobalShaderCache().release( DTrainDrawer_state_solid );
  113. }
  114. void DTrainDrawer::renderSolid( Renderer& renderer, const VolumeTest& volume ) const {
  115. if ( !m_bDisplay ) {
  116. return;
  117. }
  118. renderer.SetState( m_shader_wireframe, Renderer::eWireframeOnly );
  119. renderer.SetState( m_shader_solid, Renderer::eFullMaterials );
  120. renderer.addRenderable( *this, g_matrix4_identity );
  121. }
  122. void DTrainDrawer::renderWireframe( Renderer& renderer, const VolumeTest& volume ) const {
  123. renderSolid( renderer, volume );
  124. }
  125. void AddSplineControl( const char* control, splinePoint_t* pSP ) {
  126. controlPoint_t cp;
  127. strncpy( cp.strName, control, 64 );
  128. pSP->m_pointList.push_front( cp );
  129. }
  130. class EntityBuildPaths
  131. {
  132. mutable DEntity e;
  133. DTrainDrawer& drawer;
  134. public:
  135. EntityBuildPaths( DTrainDrawer& drawer ) : drawer( drawer ){
  136. }
  137. void operator()( scene::Instance& instance ) const {
  138. e.ClearEPairs();
  139. e.LoadEPairList( Node_getEntity( instance.path().top() ) );
  140. const char* classname = e.m_Classname.GetBuffer();
  141. const char* target;
  142. const char* control;
  143. const char* targetname;
  144. vec3_t vOrigin;
  145. e.SpawnString( "targetname", NULL, &targetname );
  146. e.SpawnVector( "origin", "0 0 0", vOrigin );
  147. if ( !strcmp( classname, "info_train_spline_main" ) ) {
  148. if ( !targetname ) {
  149. globalOutputStream() << "info_train_spline_main with no targetname";
  150. return;
  151. }
  152. e.SpawnString( "target", NULL, &target );
  153. if ( !target ) {
  154. drawer.AddControlPoint( targetname, vOrigin );
  155. }
  156. else {
  157. splinePoint_t* pSP = drawer.AddSplinePoint( targetname, target, vOrigin );
  158. e.SpawnString( "control", NULL, &control );
  159. if ( control ) {
  160. AddSplineControl( control, pSP );
  161. for ( int j = 2;; j++ ) {
  162. char buffer[16];
  163. sprintf( buffer, "control%i", j );
  164. e.SpawnString( buffer, NULL, &control );
  165. if ( !control ) {
  166. break;
  167. }
  168. AddSplineControl( control, pSP );
  169. }
  170. }
  171. }
  172. }
  173. else if ( !strcmp( classname, "info_train_spline_control" ) ) {
  174. if ( !targetname ) {
  175. globalOutputStream() << "info_train_spline_control with no targetname";
  176. return;
  177. }
  178. drawer.AddControlPoint( targetname, vOrigin );
  179. }
  180. }
  181. };
  182. void DTrainDrawer::BuildPaths() {
  183. Scene_forEachEntity( EntityBuildPaths( *this ) );
  184. std::list<splinePoint_t* >::const_iterator sp;
  185. for ( sp = m_splineList.begin(); sp != m_splineList.end(); sp++ ) {
  186. splinePoint_t* pSP = ( *sp );
  187. controlPoint_t* pTarget = FindControlPoint( pSP->strTarget );
  188. if ( !pTarget ) {
  189. globalOutputStream() << "couldn't find target " << pSP->strTarget;
  190. return;
  191. // continue;
  192. }
  193. pSP->pTarget = pTarget;
  194. for ( std::list<controlPoint_t >::iterator cp = pSP->m_pointList.begin(); cp != pSP->m_pointList.end(); cp++ ) {
  195. controlPoint_t* pControl = FindControlPoint( ( *cp ).strName );
  196. if ( !pControl ) {
  197. globalOutputStream() << "couldn't find control " << ( *cp ).strName;
  198. return;
  199. }
  200. VectorCopy( pControl->vOrigin, ( *cp ).vOrigin );
  201. }
  202. }
  203. m_bDisplay = true;
  204. for ( sp = m_splineList.begin(); sp != m_splineList.end(); sp++ ) {
  205. splinePoint_t* pSP = ( *sp );
  206. DPoint out;
  207. if ( !pSP->pTarget ) {
  208. continue;
  209. }
  210. std::size_t count = pSP->m_pointList.size() + 2;
  211. vec3_t* v = new vec3_t[count];
  212. VectorCopy( pSP->point.vOrigin, v[0] );
  213. int i = 1;
  214. for ( std::list<controlPoint_t>::reverse_iterator cp = pSP->m_pointList.rbegin(); cp != pSP->m_pointList.rend(); cp++ ) {
  215. VectorCopy( ( *cp ).vOrigin, v[i] );
  216. i++;
  217. }
  218. VectorCopy( pSP->pTarget->vOrigin, v[i] );
  219. for ( float tension = 0.0f; tension <= 1.f; tension += 0.01f ) {
  220. CalculateSpline_r( v, static_cast<int>( count ), out._pnt, tension );
  221. pSP->m_vertexList.push_front( out );
  222. }
  223. delete[] v;
  224. VectorCopy( pSP->pTarget->vOrigin, out._pnt );
  225. pSP->m_vertexList.push_front( out );
  226. }
  227. SceneChangeNotify();
  228. }
  229. void DTrainDrawer::AddControlPoint( const char* name, vec_t* origin ){
  230. controlPoint_t* pCP = new controlPoint_t;
  231. strncpy( pCP->strName, name, 64 );
  232. VectorCopy( origin, pCP->vOrigin );
  233. m_pointList.push_back( pCP );
  234. }
  235. splinePoint_t* DTrainDrawer::AddSplinePoint( const char* name, const char* target, vec_t* origin ){
  236. splinePoint_t* pSP = new splinePoint_t;
  237. strncpy( pSP->point.strName, name, 64 );
  238. strncpy( pSP->strTarget, target, 64 );
  239. VectorCopy( origin, pSP->point.vOrigin );
  240. m_splineList.push_back( pSP );
  241. return pSP;
  242. }
  243. controlPoint_t* DTrainDrawer::FindControlPoint( const char* name ){
  244. for ( std::list<controlPoint_t*>::const_iterator cp = m_pointList.begin(); cp != m_pointList.end(); cp++ ) {
  245. if ( !strcmp( name, ( *cp )->strName ) ) {
  246. return ( *cp );
  247. }
  248. }
  249. for ( std::list<splinePoint_t*>::const_iterator sp = m_splineList.begin(); sp != m_splineList.end(); sp++ ) {
  250. if ( !strcmp( name, ( *sp )->point.strName ) ) {
  251. return &( ( *sp )->point );
  252. }
  253. }
  254. return NULL;
  255. }