]> de.git.xonotic.org Git - xonotic/netradiant.git/blob - contrib/bobtoolz/DTreePlanter.cpp
reformat code! now the code is only ugly on the *inside*
[xonotic/netradiant.git] / contrib / bobtoolz / DTreePlanter.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 #include "DTreePlanter.h"
21
22 #include <list>
23 #include "str.h"
24
25 #include "DPoint.h"
26 #include "DPlane.h"
27 #include "DBrush.h"
28 #include "DEPair.h"
29 #include "DPatch.h"
30 #include "DEntity.h"
31
32 #include "ScriptParser.h"
33 #include "misc.h"
34 #include "scenelib.h"
35
36
37 #include "funchandlers.h"
38
39 SignalHandlerResult
40 DTreePlanter::mouseDown(const WindowVector &position, ButtonIdentifier button, ModifierFlags modifiers)
41 {
42     if (button != c_buttonLeft) {
43         return SIGNAL_CONTINUE_EMISSION;
44     }
45     VIEWTYPE vt = GlobalRadiant().XYWindow_getViewType();
46
47     switch (vt) {
48         case XY:
49             break;
50         case YZ:
51         case XZ:
52         default:
53             return SIGNAL_CONTINUE_EMISSION;
54     }
55
56     Vector3 pt, vhit;
57
58     pt = vector3_snapped(GlobalRadiant().XYWindow_windowToWorld(position), GlobalRadiant().getGridSize());
59
60     if (FindDropPoint(vector3_to_array(pt), vector3_to_array(vhit))) {
61         vhit[2] += m_offset;
62
63         char buffer[128];
64         DEntity e(m_entType);
65
66         sprintf(buffer, "%i %i %i", (int) vhit[0], (int) vhit[1], (int) vhit[2]);
67         e.AddEPair("origin", buffer);
68
69         if (m_autoLink) {
70
71             const scene::Path *pLastEntity = NULL;
72             const scene::Path *pThisEntity = NULL;
73
74             int entpos;
75             for (int i = 0; i < 256; i++) {
76                 sprintf(buffer, m_linkName, i);
77                 pThisEntity = FindEntityFromTargetname(buffer);
78
79                 if (pThisEntity) {
80                     entpos = i;
81                     pLastEntity = pThisEntity;
82                 }
83             }
84
85             if (!pLastEntity) {
86                 sprintf(buffer, m_linkName, 0);
87             } else {
88                 sprintf(buffer, m_linkName, entpos + 1);
89             }
90
91             e.AddEPair("targetname", buffer);
92
93             if (pLastEntity) {
94                 DEntity e2;
95                 e2.LoadFromEntity(pLastEntity->top(), true);
96                 e2.AddEPair("target", buffer);
97                 e2.RemoveFromRadiant();
98                 e2.BuildInRadiant(false);
99             }
100
101         }
102
103         if (m_setAngles) {
104             int angleYaw = (rand() % (m_maxYaw - m_minYaw + 1)) + m_minYaw;
105             int anglePitch = (rand() % (m_maxPitch - m_minPitch + 1)) + m_minPitch;
106
107             sprintf(buffer, "%i %i 0", anglePitch, angleYaw);
108             e.AddEPair("angles", buffer);
109         }
110
111         if (m_numModels) {
112             int treetype = rand() % m_numModels;
113             e.AddEPair("model", m_trees[treetype].name);
114         }
115
116         if (m_useScale) {
117             float scale = (((rand() % 1000) * 0.001f) * (m_maxScale - m_minScale)) + m_minScale;
118
119             sprintf(buffer, "%f", scale);
120             e.AddEPair("modelscale", buffer);
121         }
122
123         e.BuildInRadiant(false);
124     }
125
126     if (m_autoLink) {
127         DoTrainPathPlot();
128     }
129
130     return SIGNAL_STOP_EMISSION;
131 }
132
133 bool DTreePlanter::FindDropPoint(vec3_t in, vec3_t out)
134 {
135     DPlane p1;
136     DPlane p2;
137
138     vec3_t vUp = {0, 0, 1};
139     vec3_t vForward = {0, 1, 0};
140     vec3_t vLeft = {1, 0, 0};
141
142     in[2] = 65535;
143
144     VectorCopy(in, p1.points[0]);
145     VectorCopy(in, p1.points[1]);
146     VectorCopy(in, p1.points[2]);
147     VectorMA(p1.points[1], 20, vUp, p1.points[1]);
148     VectorMA(p1.points[1], 20, vLeft, p1.points[2]);
149
150     VectorCopy(in, p2.points[0]);
151     VectorCopy(in, p2.points[1]);
152     VectorCopy(in, p2.points[2]);
153     VectorMA(p1.points[1], 20, vUp, p2.points[1]);
154     VectorMA(p1.points[1], 20, vForward, p2.points[2]);
155
156     p1.Rebuild();
157     p2.Rebuild();
158
159     bool found = false;
160     vec3_t temp;
161     vec_t dist;
162     int cnt = m_world.GetIDMax();
163     for (int i = 0; i < cnt; i++) {
164         DBrush *pBrush = m_world.GetBrushForID(i);
165
166         if (pBrush->IntersectsWith(&p1, &p2, temp)) {
167             vec3_t diff;
168             vec_t tempdist;
169             VectorSubtract(in, temp, diff);
170             tempdist = VectorLength(diff);
171             if (!found || (tempdist < dist)) {
172                 dist = tempdist;
173                 VectorCopy(temp, out);
174                 found = true;
175             }
176         }
177     }
178
179     return found;
180 }
181
182 class TreePlanterDropEntityIfSelected {
183     mutable DEntity ent;
184     DTreePlanter &planter;
185 public:
186     TreePlanterDropEntityIfSelected(DTreePlanter &planter) : planter(planter)
187     {
188     }
189
190     void operator()(scene::Instance &instance) const
191     {
192         if (!instance.isSelected()) {
193             return;
194         }
195         ent.LoadFromEntity(instance.path().top());
196
197         DEPair *pEpair = ent.FindEPairByKey("origin");
198         if (!pEpair) {
199             return;
200         }
201
202         vec3_t vec, out;
203         sscanf(pEpair->value.GetBuffer(), "%f %f %f", &vec[0], &vec[1], &vec[2]);
204
205         planter.FindDropPoint(vec, out);
206
207         char buffer[256];
208         sprintf(buffer, "%f %f %f", out[0], out[1], out[2]);
209         ent.AddEPair("origin", buffer);
210         ent.RemoveFromRadiant();
211         ent.BuildInRadiant(false);
212     }
213 };
214
215 void DTreePlanter::DropEntsToGround(void)
216 {
217     Scene_forEachEntity(TreePlanterDropEntityIfSelected(*this));
218 }
219
220 void DTreePlanter::MakeChain(int linkNum, const char *linkName)
221 {
222     char buffer[256];
223     int i;
224     for (i = 0; i < linkNum; i++) {
225         DEntity e("info_train_spline_main");
226
227         sprintf(buffer, "%s_pt%i", linkName, i);
228         e.AddEPair("targetname", buffer);
229
230         sprintf(buffer, "0 %i 0", i * 64);
231         e.AddEPair("origin", buffer);
232
233         if (i != m_linkNum - 1) {
234             sprintf(buffer, "%s_pt%i", linkName, i + 1);
235             e.AddEPair("target", buffer);
236
237             sprintf(buffer, "%s_ctl%i", linkName, i);
238             e.AddEPair("control", buffer);
239         }
240         e.BuildInRadiant(false);
241     }
242
243     for (i = 0; i < linkNum - 1; i++) {
244         DEntity e("info_train_spline_control");
245
246         sprintf(buffer, "%s_ctl%i", linkName, i);
247         e.AddEPair("targetname", buffer);
248
249         sprintf(buffer, "0 %i 0", (i * 64) + 32);
250         e.AddEPair("origin", buffer);
251
252         e.BuildInRadiant(false);
253     }
254 }
255
256 void DTreePlanter::SelectChain(void)
257 {
258 /*      char buffer[256];
259
260     for(int i = 0; i < m_linkNum; i++) {
261         DEntity e("info_train_spline_main");
262
263         sprintf( buffer, "%s_pt%i", m_linkName, i );
264         e.AddEPair( "targetname", buffer );
265
266         sprintf( buffer, "0 %i 0", i * 64 );
267         e.AddEPair( "origin", buffer );
268
269         if(i != m_linkNum-1) {
270             sprintf( buffer, "%s_pt%i", m_linkName, i+1 );
271             e.AddEPair( "target", buffer );
272
273             sprintf( buffer, "%s_ctl%i", m_linkName, i );
274             e.AddEPair( "control", buffer );
275         }
276
277         e.BuildInRadiant( false );
278     }
279
280     for(int i = 0; i < m_linkNum-1; i++) {
281         DEntity e("info_train_spline_control");
282
283         sprintf( buffer, "%s_ctl%i", m_linkName, i );
284         e.AddEPair( "targetname", buffer );
285
286         sprintf( buffer, "0 %i 0", (i * 64) + 32);
287         e.AddEPair( "origin", buffer );
288
289         e.BuildInRadiant( false );
290     }*/
291 }