]> icculus.org git repositories - divverent/netradiant.git/blob - contrib/bobtoolz/DBobView.cpp
option -randomsamples: makes -samples use adaptive random subsampling (only subsample...
[divverent/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 {
46         nPathCount = 0;
47         
48         path = NULL;
49
50         boundingShow = BOUNDS_APEX;
51
52   constructShaders();
53   GlobalShaderCache().attachRenderable(*this);
54 }
55
56 DBobView::~DBobView()
57 {
58   GlobalShaderCache().detachRenderable(*this);
59   destroyShaders();
60
61   if(path)
62                 delete[] path;
63
64         g_PathView = NULL;
65 }
66
67 //////////////////////////////////////////////////////////////////////
68 // Implementation
69 //////////////////////////////////////////////////////////////////////
70
71 void DBobView::render(RenderStateFlags state) const
72 {
73         glBegin(GL_LINE_STRIP);
74
75         for(int i = 0; i < nPathCount; i++)
76                 glVertex3fv(path[i]);
77
78         glEnd();
79 }
80
81 const char* DBobView_state_line = "$bobtoolz/bobview/line";
82 const char* DBobView_state_box = "$bobtoolz/bobview/box";
83
84 void DBobView::constructShaders()
85 {
86   OpenGLState state;
87   GlobalOpenGLStateLibrary().getDefaultState(state);
88   state.m_state = RENDER_COLOURWRITE|RENDER_DEPTHWRITE|RENDER_BLEND|RENDER_LINESMOOTH;
89   state.m_sort = OpenGLState::eSortOpaque;
90   state.m_linewidth = 1;
91   state.m_colour[0] = 1;
92   state.m_colour[1] = 0;
93   state.m_colour[2] = 0;
94   state.m_colour[3] = 1;
95   GlobalOpenGLStateLibrary().insert(DBobView_state_line, state);
96
97   state.m_colour[0] = 0.25f;
98   state.m_colour[1] = 0.75f;
99   state.m_colour[2] = 0.75f;
100   state.m_colour[3] = 1;
101   GlobalOpenGLStateLibrary().insert(DBobView_state_box, state);
102
103   m_shader_line = GlobalShaderCache().capture(DBobView_state_line);
104   m_shader_box = GlobalShaderCache().capture(DBobView_state_box);
105 }
106
107 void DBobView::destroyShaders()
108 {
109   GlobalOpenGLStateLibrary().erase(DBobView_state_line);
110   GlobalOpenGLStateLibrary().erase(DBobView_state_box);
111   GlobalShaderCache().release(DBobView_state_line);
112   GlobalShaderCache().release(DBobView_state_box);
113 }
114
115 Matrix4 g_transform_box1 = matrix4_translation_for_vec3(Vector3(16.0f, 16.0f, 28.0f));
116 Matrix4 g_transform_box2 = matrix4_translation_for_vec3(Vector3(-16.0f, 16.0f, 28.0f));
117 Matrix4 g_transform_box3 = matrix4_translation_for_vec3(Vector3(16.0f, -16.0f, -28.0f));
118 Matrix4 g_transform_box4 = matrix4_translation_for_vec3(Vector3(-16.0f, -16.0f, -28.0f));
119
120 void DBobView::renderSolid(Renderer& renderer, const VolumeTest& volume) const
121 {
122         if(!path)
123                 return;
124
125   renderer.SetState(m_shader_line, Renderer::eWireframeOnly);
126   renderer.SetState(m_shader_line, Renderer::eFullMaterials);
127   renderer.addRenderable(*this, g_matrix4_identity);
128
129         if(m_bShowExtra)
130         {
131     renderer.SetState(m_shader_box, Renderer::eWireframeOnly);
132     renderer.SetState(m_shader_box, Renderer::eFullMaterials);
133     renderer.addRenderable(*this, g_transform_box1);
134     renderer.addRenderable(*this, g_transform_box2);
135     renderer.addRenderable(*this, g_transform_box3);
136     renderer.addRenderable(*this, g_transform_box4);
137   }
138 }
139 void DBobView::renderWireframe(Renderer& renderer, const VolumeTest& volume) const
140 {
141   renderSolid(renderer, volume);
142 }
143
144 void DBobView::SetPath(vec3_t *pPath)
145 {
146         if(path)
147                 delete[] path;
148
149         path = pPath;
150 }
151
152 #define LOCAL_GRAVITY -800.0f
153
154 bool DBobView::CalculateTrajectory(vec3_t start, vec3_t apex, float multiplier, int points, float varGravity)
155 {
156         if(apex[2] <= start[2])
157         {
158                 SetPath(NULL);
159                 return false;
160         }
161         // ----think q3a actually would allow these
162         //scrub that, coz the plugin wont :]
163
164         vec3_t dist, speed;
165         VectorSubtract(apex, start, dist);
166
167         vec_t speed_z = (float)sqrt(-2*LOCAL_GRAVITY*dist[2]);
168         float flight_time = -speed_z/LOCAL_GRAVITY;
169
170
171         VectorScale(dist, 1/flight_time, speed);
172         speed[2] = speed_z;
173
174 //      Sys_Printf("Speed: (%.4f %.4f %.4f)\n", speed[0], speed[1], speed[2]);
175
176         vec3_t* pPath = new vec3_t[points];
177
178         float interval = multiplier*flight_time/points;
179         for(int i = 0; i < points; i++)
180         {
181                 float ltime = interval*i;
182
183                 VectorScale(speed, ltime, pPath[i]);
184                 VectorAdd(pPath[i], start, pPath[i]);
185
186                 // could do this all with vectors
187                 // vGrav = {0, 0, -800.0f}
188                 // VectorScale(vGrav, 0.5f*ltime*ltime, vAdd);
189                 // VectorScale(speed, ltime, pPath[i]);
190                 // _VectorAdd(pPath[i], start, pPath[i])
191                 // _VectorAdd(pPath[i], vAdd, pPath[i])
192
193                 pPath[i][2] = start[2] + (speed_z*ltime) + (varGravity*0.5f*ltime*ltime);
194         }
195
196         SetPath(pPath);
197         return true;
198 }
199
200 void DBobView::Begin(const char* trigger, const char *target, float multiplier, int points, float varGravity, bool bNoUpdate, bool bShowExtra)
201 {
202         strcpy(entTrigger, trigger);
203         strcpy(entTarget, target);
204
205         fMultiplier = multiplier;
206         fVarGravity = varGravity;
207         nPathCount = points;
208         m_bShowExtra = bShowExtra;
209
210         if(!UpdatePath())
211         {
212                 globalErrorStream() << "Initialization Failure in DBobView::Begin";
213                 delete this;
214         }
215         globalOutputStream() << "Initialization of Path Plotter succeeded.";
216 }
217
218 bool DBobView::UpdatePath()
219 {
220         vec3_t start, apex;
221
222         if(GetEntityCentre(entTrigger, start))
223         {
224                 if(GetEntityCentre(entTarget, apex))
225                 {
226                         CalculateTrajectory(start, apex, fMultiplier, nPathCount, fVarGravity);
227                         return true;
228                 }
229         }
230         return false;
231 }
232
233 void DBobView_setEntity(Entity& entity, float multiplier, int points, float varGravity, bool bNoUpdate, bool bShowExtra)
234 {
235         DEntity trigger;
236         trigger.LoadEPairList(&entity);
237
238         DEPair* trigger_ep = trigger.FindEPairByKey("targetname");
239
240         if(trigger_ep)
241         {
242                 if(!strcmp(trigger.m_Classname, "trigger_push"))
243                 {
244                         DEPair* target_ep = trigger.FindEPairByKey("target");
245                         if(target_ep)
246                         {
247                                 const scene::Path* entTarget = FindEntityFromTargetname(target_ep->value);
248                                 if(entTarget)
249                                 {
250                                         if(g_PathView)
251                                                 delete g_PathView;
252                                         g_PathView = new DBobView;
253
254                                         Entity* target = Node_getEntity(entTarget->top());
255                                         if(target != 0)
256                                         {
257                                                 if(!bNoUpdate)
258                                                 {
259                                                         g_PathView->trigger = &entity;
260                                                         entity.attach(*g_PathView);
261                                                         g_PathView->target = target;
262                                                         target->attach(*g_PathView);
263                                                 }
264                                           g_PathView->Begin(trigger_ep->value, target_ep->value, multiplier, points, varGravity, bNoUpdate, bShowExtra);
265                                         }
266                                         else
267                                                 globalErrorStream() << "bobToolz PathPlotter: trigger_push ARGH\n";
268                                 }
269                                 else
270                                         globalErrorStream() << "bobToolz PathPlotter: trigger_push target could not be found..\n";
271                         }
272                         else
273                                 globalErrorStream() << "bobToolz PathPlotter: trigger_push has no target..\n";
274                 }
275                 else
276                         globalErrorStream() << "bobToolz PathPlotter: You must select a 'trigger_push' entity..\n";
277         }       
278         else
279                 globalErrorStream() << "bobToolz PathPlotter: Entity must have a targetname.\n";
280         return;
281 }