]> de.git.xonotic.org Git - xonotic/netradiant.git/blob - contrib/bobtoolz/DBobView.cpp
Merge remote-tracking branch 'ttimo/master'
[xonotic/netradiant.git] / contrib / bobtoolz / DBobView.cpp
1 /*
2    BobToolz plugin for GtkRadiant
3    Copyright (C) 2001 Gordon Biggans
4
5    This library is free software; you can redistribute it and/or
6    modify it under the terms of the GNU Lesser General Public
7    License as published by the Free Software Foundation; either
8    version 2.1 of the License, or (at your option) any later version.
9
10    This library is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13    Lesser General Public License for more details.
14
15    You should have received a copy of the GNU Lesser General Public
16    License along with this library; if not, write to the Free Software
17    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18  */
19
20 // BobView.cpp: implementation of the DBobView class.
21 //
22 //////////////////////////////////////////////////////////////////////
23
24 #include "DBobView.h"
25 //#include "misc.h"
26 #include "funchandlers.h"
27
28 #include <list>
29
30 #include "iglrender.h"
31 #include "qerplugin.h"
32 #include "str.h"
33 #include "math/matrix.h"
34
35 #include "DEntity.h"
36 #include "DEPair.h"
37 #include "misc.h"
38 #include "dialogs/dialogs-gtk.h"
39
40 //////////////////////////////////////////////////////////////////////
41 // Construction/Destruction
42 //////////////////////////////////////////////////////////////////////
43
44 DBobView::DBobView(){
45         nPathCount = 0;
46
47         path = NULL;
48
49         boundingShow = BOUNDS_APEX;
50
51         constructShaders();
52         GlobalShaderCache().attachRenderable( *this );
53 }
54
55 DBobView::~DBobView(){
56         GlobalShaderCache().detachRenderable( *this );
57         destroyShaders();
58
59         if ( path ) {
60                 delete[] path;
61         }
62
63         g_PathView = NULL;
64 }
65
66 //////////////////////////////////////////////////////////////////////
67 // Implementation
68 //////////////////////////////////////////////////////////////////////
69
70 void DBobView::render( RenderStateFlags state ) const {
71         glBegin( GL_LINE_STRIP );
72
73         for ( int i = 0; i < nPathCount; i++ )
74                 glVertex3fv( path[i] );
75
76         glEnd();
77 }
78
79 const char* DBobView_state_line = "$bobtoolz/bobview/line";
80 const char* DBobView_state_box = "$bobtoolz/bobview/box";
81
82 void DBobView::constructShaders(){
83         OpenGLState state;
84         GlobalOpenGLStateLibrary().getDefaultState( state );
85         state.m_state = RENDER_COLOURWRITE | RENDER_DEPTHWRITE | RENDER_BLEND | RENDER_LINESMOOTH;
86         state.m_sort = OpenGLState::eSortOpaque;
87         state.m_linewidth = 1;
88         state.m_colour[0] = 1;
89         state.m_colour[1] = 0;
90         state.m_colour[2] = 0;
91         state.m_colour[3] = 1;
92         GlobalOpenGLStateLibrary().insert( DBobView_state_line, state );
93
94         state.m_colour[0] = 0.25f;
95         state.m_colour[1] = 0.75f;
96         state.m_colour[2] = 0.75f;
97         state.m_colour[3] = 1;
98         GlobalOpenGLStateLibrary().insert( DBobView_state_box, state );
99
100         m_shader_line = GlobalShaderCache().capture( DBobView_state_line );
101         m_shader_box = GlobalShaderCache().capture( DBobView_state_box );
102 }
103
104 void DBobView::destroyShaders(){
105         GlobalOpenGLStateLibrary().erase( DBobView_state_line );
106         GlobalOpenGLStateLibrary().erase( DBobView_state_box );
107         GlobalShaderCache().release( DBobView_state_line );
108         GlobalShaderCache().release( DBobView_state_box );
109 }
110
111 Matrix4 g_transform_box1 = matrix4_translation_for_vec3( Vector3( 16.0f, 16.0f, 28.0f ) );
112 Matrix4 g_transform_box2 = matrix4_translation_for_vec3( Vector3( -16.0f, 16.0f, 28.0f ) );
113 Matrix4 g_transform_box3 = matrix4_translation_for_vec3( Vector3( 16.0f, -16.0f, -28.0f ) );
114 Matrix4 g_transform_box4 = matrix4_translation_for_vec3( Vector3( -16.0f, -16.0f, -28.0f ) );
115
116 void DBobView::renderSolid( Renderer& renderer, const VolumeTest& volume ) const {
117         if ( !path ) {
118                 return;
119         }
120
121         renderer.SetState( m_shader_line, Renderer::eWireframeOnly );
122         renderer.SetState( m_shader_line, Renderer::eFullMaterials );
123         renderer.addRenderable( *this, g_matrix4_identity );
124
125         if ( m_bShowExtra ) {
126                 renderer.SetState( m_shader_box, Renderer::eWireframeOnly );
127                 renderer.SetState( m_shader_box, Renderer::eFullMaterials );
128                 renderer.addRenderable( *this, g_transform_box1 );
129                 renderer.addRenderable( *this, g_transform_box2 );
130                 renderer.addRenderable( *this, g_transform_box3 );
131                 renderer.addRenderable( *this, g_transform_box4 );
132         }
133 }
134 void DBobView::renderWireframe( Renderer& renderer, const VolumeTest& volume ) const {
135         renderSolid( renderer, volume );
136 }
137
138 void DBobView::SetPath( vec3_t *pPath ){
139         if ( path ) {
140                 delete[] path;
141         }
142
143         path = pPath;
144 }
145
146 #define LOCAL_GRAVITY -800.0f
147
148 bool DBobView::CalculateTrajectory( vec3_t start, vec3_t apex, float multiplier, int points, float varGravity ){
149         if ( apex[2] <= start[2] ) {
150                 SetPath( NULL );
151                 return false;
152         }
153         // ----think q3a actually would allow these
154         //scrub that, coz the plugin wont :]
155
156         vec3_t dist, speed;
157         VectorSubtract( apex, start, dist );
158
159         vec_t speed_z = (float)sqrt( -2 * LOCAL_GRAVITY * dist[2] );
160         float flight_time = -speed_z / LOCAL_GRAVITY;
161
162
163         VectorScale( dist, 1 / flight_time, speed );
164         speed[2] = speed_z;
165
166 //      Sys_Printf("Speed: (%.4f %.4f %.4f)\n", speed[0], speed[1], speed[2]);
167
168         vec3_t* pPath = new vec3_t[points];
169
170         float interval = multiplier * flight_time / points;
171         for ( int i = 0; i < points; i++ )
172         {
173                 float ltime = interval * i;
174
175                 VectorScale( speed, ltime, pPath[i] );
176                 VectorAdd( pPath[i], start, pPath[i] );
177
178                 // could do this all with vectors
179                 // vGrav = {0, 0, -800.0f}
180                 // VectorScale(vGrav, 0.5f*ltime*ltime, vAdd);
181                 // VectorScale(speed, ltime, pPath[i]);
182                 // _VectorAdd(pPath[i], start, pPath[i])
183                 // _VectorAdd(pPath[i], vAdd, pPath[i])
184
185                 pPath[i][2] = start[2] + ( speed_z * ltime ) + ( varGravity * 0.5f * ltime * ltime );
186         }
187
188         SetPath( pPath );
189         return true;
190 }
191
192 void DBobView::Begin( const char* trigger, const char *target, float multiplier, int points, float varGravity, bool bNoUpdate, bool bShowExtra ){
193         strcpy( entTrigger, trigger );
194         strcpy( entTarget, target );
195
196         fMultiplier = multiplier;
197         fVarGravity = varGravity;
198         nPathCount = points;
199         m_bShowExtra = bShowExtra;
200
201         if ( !UpdatePath() ) {
202                 globalErrorStream() << "Initialization Failure in DBobView::Begin";
203                 delete this;
204         }
205         globalOutputStream() << "Initialization of Path Plotter succeeded.";
206 }
207
208 bool DBobView::UpdatePath(){
209         vec3_t start, apex;
210
211         if ( GetEntityCentre( entTrigger, start ) ) {
212                 if ( GetEntityCentre( entTarget, apex ) ) {
213                         CalculateTrajectory( start, apex, fMultiplier, nPathCount, fVarGravity );
214                         return true;
215                 }
216         }
217         return false;
218 }
219
220 void DBobView_setEntity( Entity& entity, float multiplier, int points, float varGravity, bool bNoUpdate, bool bShowExtra ){
221         DEntity trigger;
222         trigger.LoadEPairList( &entity );
223
224         DEPair* trigger_ep = trigger.FindEPairByKey( "targetname" );
225
226         if ( trigger_ep ) {
227                 if ( !strcmp( trigger.m_Classname, "trigger_push" ) ) {
228                         DEPair* target_ep = trigger.FindEPairByKey( "target" );
229                         if ( target_ep ) {
230                                 const scene::Path* entTarget = FindEntityFromTargetname( target_ep->value );
231                                 if ( entTarget ) {
232                                         if ( g_PathView ) {
233                                                 delete g_PathView;
234                                         }
235                                         g_PathView = new DBobView;
236
237                                         Entity* target = Node_getEntity( entTarget->top() );
238                                         if ( target != 0 ) {
239                                                 if ( !bNoUpdate ) {
240                                                         g_PathView->trigger = &entity;
241                                                         entity.attach( *g_PathView );
242                                                         g_PathView->target = target;
243                                                         target->attach( *g_PathView );
244                                                 }
245                                                 g_PathView->Begin( trigger_ep->value, target_ep->value, multiplier, points, varGravity, bNoUpdate, bShowExtra );
246                                         }
247                                         else{
248                                                 globalErrorStream() << "bobToolz PathPlotter: trigger_push ARGH\n";
249                                         }
250                                 }
251                                 else{
252                                         globalErrorStream() << "bobToolz PathPlotter: trigger_push target could not be found..\n";
253                                 }
254                         }
255                         else{
256                                 globalErrorStream() << "bobToolz PathPlotter: trigger_push has no target..\n";
257                         }
258                 }
259                 else{
260                         globalErrorStream() << "bobToolz PathPlotter: You must select a 'trigger_push' entity..\n";
261                 }
262         }
263         else{
264                 globalErrorStream() << "bobToolz PathPlotter: Entity must have a targetname.\n";
265         }
266         return;
267 }