]> de.git.xonotic.org Git - xonotic/netradiant.git/blob - contrib/bobtoolz/DTrainDrawer.cpp
transfer from internal tree r5311 branches/1.4-gpl
[xonotic/netradiant.git] / contrib / bobtoolz / DTrainDrawer.cpp
1 /*\r
2 BobToolz plugin for GtkRadiant\r
3 Copyright (C) 2001 Gordon Biggans\r
4 \r
5 This library is free software; you can redistribute it and/or\r
6 modify it under the terms of the GNU Lesser General Public\r
7 License as published by the Free Software Foundation; either\r
8 version 2.1 of the License, or (at your option) any later version.\r
9 \r
10 This library is distributed in the hope that it will be useful,\r
11 but WITHOUT ANY WARRANTY; without even the implied warranty of\r
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
13 Lesser General Public License for more details.\r
14 \r
15 You should have received a copy of the GNU Lesser General Public\r
16 License along with this library; if not, write to the Free Software\r
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
18 */\r
19 \r
20 #include "StdAfx.h"\r
21 #include "DPoint.h"\r
22 \r
23 #include "DTrainDrawer.h"\r
24 #include "DEPair.h"\r
25 \r
26 #include "misc.h"\r
27 #include "funchandlers.h"\r
28 \r
29 #include "dialogs/dialogs-gtk.h"\r
30 \r
31 DTrainDrawer::DTrainDrawer() {\r
32         refCount = 1;\r
33         m_bHooked = FALSE;\r
34         m_bDisplay = FALSE;\r
35 \r
36         BuildPaths();\r
37 }\r
38 \r
39 DTrainDrawer::~DTrainDrawer(void) {\r
40         if(m_bHooked)\r
41                 UnRegister();\r
42 \r
43         ClearPoints();\r
44         ClearSplines();\r
45 }\r
46 \r
47 void DTrainDrawer::ClearSplines() {\r
48         for(list<splinePoint_t *>::const_iterator deadSpline = m_splineList.begin(); deadSpline != m_splineList.end(); deadSpline++) {\r
49                 (*deadSpline)->m_pointList.clear();\r
50                 (*deadSpline)->m_vertexList.clear();\r
51                 delete (*deadSpline);\r
52         }\r
53 \r
54         m_splineList.clear();\r
55 }\r
56 \r
57 void DTrainDrawer::ClearPoints() {\r
58         for(list<controlPoint_t *>::const_iterator deadPoint = m_pointList.begin(); deadPoint != m_pointList.end(); deadPoint++) {\r
59                 delete *deadPoint;\r
60         }\r
61 \r
62         m_pointList.clear();\r
63 }\r
64 \r
65 void DTrainDrawer::Register() {\r
66         g_QglTable.m_pfnHookGL2DWindow( this );\r
67         g_QglTable.m_pfnHookGL3DWindow( this );\r
68         m_bHooked = TRUE;\r
69 }\r
70 \r
71 void DTrainDrawer::UnRegister() {\r
72         g_QglTable.m_pfnUnHookGL2DWindow( this );\r
73         g_QglTable.m_pfnUnHookGL3DWindow( this );\r
74         m_bHooked = FALSE;\r
75 }\r
76 \r
77 void CalculateSpline_r(vec3_t* v, int count, vec3_t out, float tension) {\r
78         vec3_t dist;\r
79 \r
80         if(count < 2) {\r
81                 return;\r
82         }\r
83 \r
84         if(count == 2) {\r
85                 VectorSubtract( v[1], v[0], dist );\r
86                 VectorMA(v[0], tension, dist, out);\r
87                 return;\r
88         }\r
89 \r
90         vec3_t* v2 = new vec3_t[count-1];\r
91 \r
92         for( int i = 0; i < count-1; i++ ) {\r
93                 VectorSubtract( v[i+1], v[i], dist );\r
94                 VectorMA(v[i], tension, dist, v2[i]);\r
95         }\r
96 \r
97         CalculateSpline_r( v2, count-1, out, tension);\r
98 \r
99         delete[] v2;\r
100 }\r
101 \r
102 void DTrainDrawer::Draw3D() {\r
103 \r
104         if(!m_bDisplay) {\r
105                 return;\r
106         }\r
107 \r
108         g_QglTable.m_pfn_qglPushAttrib(GL_ALL_ATTRIB_BITS);\r
109 \r
110         g_QglTable.m_pfn_qglDisable(GL_BLEND);\r
111         g_QglTable.m_pfn_qglDisable(GL_LINE_SMOOTH);\r
112 \r
113         g_QglTable.m_pfn_qglPushMatrix();\r
114         \r
115         g_QglTable.m_pfn_qglLineWidth(2.0f);\r
116         g_QglTable.m_pfn_qglColor4f(1.0f, 1.0f, 1.0f, 1.0f);\r
117 \r
118         g_QglTable.m_pfn_qglEnable(GL_BLEND);\r
119         g_QglTable.m_pfn_qglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);\r
120         g_QglTable.m_pfn_qglDisable(GL_POLYGON_SMOOTH);\r
121 \r
122         g_QglTable.m_pfn_qglDepthFunc(GL_ALWAYS);\r
123 \r
124         for(list<splinePoint_t* >::const_iterator sp = m_splineList.begin(); sp != m_splineList.end(); sp++) {\r
125                 splinePoint_t* pSP = (*sp);\r
126 \r
127                 g_QglTable.m_pfn_qglBegin(GL_LINE_STRIP);\r
128                         for(list<DPoint >::const_iterator v = pSP->m_vertexList.begin(); v != pSP->m_vertexList.end(); v++) {\r
129                                 g_QglTable.m_pfn_qglVertex3fv((*v)._pnt);\r
130                         }\r
131                 g_QglTable.m_pfn_qglEnd();\r
132 \r
133         }\r
134 \r
135         g_QglTable.m_pfn_qglPopMatrix();\r
136         g_QglTable.m_pfn_qglPopAttrib();\r
137 }\r
138 \r
139 void DTrainDrawer::Draw2D(VIEWTYPE vt) {\r
140 \r
141         if(!m_bDisplay) {\r
142                 return;\r
143         }\r
144 \r
145         g_QglTable.m_pfn_qglPushAttrib(GL_ALL_ATTRIB_BITS);\r
146 \r
147         g_QglTable.m_pfn_qglDisable(GL_BLEND);\r
148         g_QglTable.m_pfn_qglDisable(GL_LINE_SMOOTH);\r
149 \r
150         g_QglTable.m_pfn_qglPushMatrix();\r
151         \r
152         switch(vt)\r
153         {\r
154         case XY:\r
155                 break;\r
156         case XZ:\r
157                 g_QglTable.m_pfn_qglRotatef(270.0f, 1.0f, 0.0f, 0.0f);\r
158                 break;\r
159         case YZ:\r
160                 g_QglTable.m_pfn_qglRotatef(270.0f, 1.0f, 0.0f, 0.0f);\r
161                 g_QglTable.m_pfn_qglRotatef(270.0f, 0.0f, 0.0f, 1.0f);\r
162                 break;\r
163         }\r
164 \r
165         g_QglTable.m_pfn_qglLineWidth(1.0f);\r
166         g_QglTable.m_pfn_qglColor4f(1.0f, 0.0f, 0.0f, 0.5f);\r
167 \r
168         g_QglTable.m_pfn_qglEnable(GL_BLEND);\r
169         g_QglTable.m_pfn_qglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);\r
170         g_QglTable.m_pfn_qglDisable(GL_POLYGON_SMOOTH);\r
171 \r
172         g_QglTable.m_pfn_qglDepthFunc(GL_ALWAYS);\r
173 \r
174         g_QglTable.m_pfn_qglColor4f(1.f, 0.f, 0.f, 1.f);\r
175 \r
176         for(list<splinePoint_t* >::const_iterator sp = m_splineList.begin(); sp != m_splineList.end(); sp++) {\r
177                 splinePoint_t* pSP = (*sp);\r
178 \r
179                 g_QglTable.m_pfn_qglBegin(GL_LINE_STRIP);\r
180                         for(list<DPoint >::const_iterator v = pSP->m_vertexList.begin(); v != pSP->m_vertexList.end(); v++) {\r
181                                 g_QglTable.m_pfn_qglVertex3fv((*v)._pnt);\r
182                         }\r
183                 g_QglTable.m_pfn_qglEnd();\r
184 \r
185         }\r
186 \r
187         g_QglTable.m_pfn_qglPopMatrix();\r
188         g_QglTable.m_pfn_qglPopAttrib();\r
189 }\r
190 \r
191 void AddSplineControl(const char* control, splinePoint_t* pSP) {\r
192         controlPoint_t cp;\r
193         strncpy(cp.strName,     control, 64);\r
194 \r
195         pSP->m_pointList.push_front(cp);\r
196 }\r
197 \r
198 void DTrainDrawer::BuildPaths() {\r
199         int count = g_FuncTable.m_pfnGetEntityCount();\r
200 \r
201         DEntity e;\r
202 \r
203         for(int i = 0; i < count; i++) {\r
204                 entity_s* ent = (entity_s*)g_FuncTable.m_pfnGetEntityHandle(i);\r
205                 e.ClearEPairs();\r
206                 e.LoadEPairList(*g_EntityTable.m_pfnGetEntityKeyValList(ent));\r
207 \r
208                 const char* classname = e.m_Classname.GetBuffer();\r
209                 const char* target;\r
210                 const char* control;\r
211                 const char* targetname;\r
212                 vec3_t          vOrigin;\r
213 \r
214                 e.SpawnString("targetname", NULL, &targetname);\r
215                 e.SpawnVector("origin", "0 0 0", vOrigin);\r
216 \r
217                 if(!strcmp(classname, "info_train_spline_main")) {\r
218                         if(!targetname) {\r
219                                 Sys_Printf( "info_train_spline_main with no targetname" );\r
220                                 return;\r
221                         }\r
222 \r
223                         e.SpawnString("target", NULL, &target);\r
224 \r
225                         if(!target) {\r
226                                 AddControlPoint( targetname, vOrigin );\r
227                         } else {\r
228                                 splinePoint_t* pSP = AddSplinePoint( targetname, target, vOrigin );\r
229 \r
230                                 e.SpawnString("control", NULL, &control);\r
231 \r
232                                 if(control) {\r
233                                         AddSplineControl( control, pSP );\r
234 \r
235                                         for(int j = 2;; j++) {\r
236                                                 char buffer[16];\r
237                                                 sprintf(buffer, "control%i", j);\r
238 \r
239                                                 e.SpawnString(buffer, NULL, &control);\r
240                                                 if(!control) {\r
241                                                         break;\r
242                                                 }\r
243                                         \r
244                                                 AddSplineControl( control, pSP );\r
245                                         }\r
246                                 }\r
247                         }\r
248                 } else if(!strcmp(classname, "info_train_spline_control")) {\r
249                         if(!targetname) {\r
250                                 Sys_Printf( "info_train_spline_control with no targetname" );\r
251                                 return;\r
252                         }\r
253 \r
254                         AddControlPoint( targetname, vOrigin );\r
255                 }\r
256         }\r
257 \r
258   list<splinePoint_t* >::const_iterator sp;\r
259         for(sp = m_splineList.begin(); sp != m_splineList.end(); sp++) {\r
260                 splinePoint_t* pSP = (*sp);\r
261 \r
262                 controlPoint_t* pTarget = FindControlPoint( pSP->strTarget );\r
263 \r
264                 if(!pTarget) {\r
265                         Sys_Printf( "couldn't find target %s", pSP->strTarget );\r
266                         return;\r
267 //                      continue;\r
268                 }\r
269 \r
270                 pSP->pTarget = pTarget;\r
271 \r
272 \r
273                 for(list<controlPoint_t >::iterator cp = pSP->m_pointList.begin(); cp != pSP->m_pointList.end(); cp++) {                        \r
274                         controlPoint_t* pControl = FindControlPoint( (*cp).strName );\r
275                         if(!pControl) {\r
276                                 Sys_Printf( "couldn't find control %s", (*cp).strName );\r
277                                 return;\r
278                         }\r
279 \r
280                         VectorCopy(pControl->vOrigin, (*cp).vOrigin);\r
281                 }\r
282         }\r
283 \r
284         m_bDisplay = TRUE;\r
285         Register();\r
286 \r
287         for(sp = m_splineList.begin(); sp != m_splineList.end(); sp++) {\r
288                 splinePoint_t* pSP = (*sp);\r
289                 DPoint out;\r
290 \r
291                 if(!pSP->pTarget) {\r
292                         continue;\r
293                 }\r
294 \r
295                 int count = pSP->m_pointList.size() + 2;\r
296                 vec3_t* v = new vec3_t[count];\r
297 \r
298                 VectorCopy(pSP->point.vOrigin, v[0]);\r
299 \r
300                 int i = 1;\r
301                 for(list<controlPoint_t>::reverse_iterator cp = pSP->m_pointList.rbegin(); cp != pSP->m_pointList.rend(); cp++) {\r
302                         VectorCopy((*cp).vOrigin, v[i]);\r
303                         i++;\r
304                 }\r
305                 VectorCopy(pSP->pTarget->vOrigin, v[i]);\r
306 \r
307                 for (float tension = 0.0f; tension <= 1.f; tension += 0.01f) {\r
308                         CalculateSpline_r(v, count, out._pnt, tension);\r
309                         pSP->m_vertexList.push_front(out);\r
310                 }\r
311 \r
312                 delete[] v;\r
313 \r
314                 VectorCopy(pSP->pTarget->vOrigin, out._pnt);\r
315                 pSP->m_vertexList.push_front(out);\r
316         }\r
317 \r
318 \r
319 }\r
320 \r
321 void DTrainDrawer::AddControlPoint(const char* name, vec_t* origin)\r
322 {\r
323         controlPoint_t* pCP = new controlPoint_t;\r
324 \r
325         strncpy(pCP->strName, name, 64);\r
326         VectorCopy( origin, pCP->vOrigin );\r
327 \r
328         m_pointList.push_back( pCP );\r
329 }\r
330 \r
331 splinePoint_t* DTrainDrawer::AddSplinePoint(const char* name, const char* target, vec_t* origin)\r
332 {\r
333         splinePoint_t* pSP = new splinePoint_t;\r
334 \r
335         strncpy(pSP->point.strName, name,               64);\r
336         strncpy(pSP->strTarget,         target,         64);\r
337         VectorCopy( origin, pSP->point.vOrigin );\r
338         m_splineList.push_back( pSP );\r
339 \r
340         return pSP;\r
341 }\r
342 \r
343 controlPoint_t* DTrainDrawer::FindControlPoint(const char* name)\r
344 {\r
345         for(list<controlPoint_t*>::const_iterator cp = m_pointList.begin(); cp != m_pointList.end(); cp++) {\r
346                 if(!strcmp(name, (*cp)->strName)) {\r
347                         return (*cp);\r
348                 }\r
349         }\r
350 \r
351         for(list<splinePoint_t*>::const_iterator sp = m_splineList.begin(); sp != m_splineList.end(); sp++) {\r
352                 if(!strcmp(name, (*sp)->point.strName)) {\r
353                         return &((*sp)->point);\r
354                 }\r
355         }\r
356 \r
357         return NULL;\r
358 }\r