OpenMoHAA 0.82.1
Loading...
Searching...
No Matches
bspline.h
1/*
2===========================================================================
3Copyright (C) 2024 the OpenMoHAA team
4
5This file is part of OpenMoHAA source code.
6
7OpenMoHAA source code is free software; you can redistribute it
8and/or modify it under the terms of the GNU General Public License as
9published by the Free Software Foundation; either version 2 of the License,
10or (at your option) any later version.
11
12OpenMoHAA source code is distributed in the hope that it will be
13useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with OpenMoHAA source code; if not, write to the Free Software
19Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20===========================================================================
21*/
22
23// bspline.h: Uniform non-rational bspline class.
24//
25
26#pragma once
27
28#include "g_local.h"
29#include "entity.h"
30#include "vector.h"
31
32typedef enum {
33 SPLINE_NORMAL,
34 SPLINE_LOOP,
35 SPLINE_CLAMP
36} splinetype_t;
37
38class BSplineControlPoint : public Class
39{
40private:
41 float roll;
42 Vector position;
43 Vector orientation;
44 float speed;
45
46public:
47 BSplineControlPoint();
48 BSplineControlPoint(Vector pos, Vector orient, float speed);
49 BSplineControlPoint(Vector pos);
50 void Clear(void);
51 void Set(Vector pos);
52 void Set(Vector pos, float speed);
53 void Set(Vector pos, Vector orient, float speed);
54 void Get(Vector& pos, Vector& orient, float& speed);
55 void Get(Vector& pos);
56 Vector *GetPosition(void);
57 Vector *GetOrientation(void);
58 float *GetRoll(void);
59 float *GetSpeed(void);
60 void operator=(BSplineControlPoint& point);
61 void Archive(Archiver& arc) override;
62};
63
64inline void BSplineControlPoint::Archive(Archiver& arc)
65{
66 arc.ArchiveVector(&position);
67 arc.ArchiveVector(&orientation);
68 arc.ArchiveFloat(&speed);
69 arc.ArchiveFloat(&roll);
70}
71
72inline void BSplineControlPoint::operator=(BSplineControlPoint& point)
73{
74 position = point.position;
75 orientation = point.orientation;
76 speed = point.speed;
77 roll = point.roll;
78}
79
80inline BSplineControlPoint::BSplineControlPoint()
81{
82 roll = 0;
83 speed = 1;
84}
85
86inline BSplineControlPoint::BSplineControlPoint(Vector pos)
87{
88 speed = 1;
89 position = pos;
90}
91
92inline BSplineControlPoint::BSplineControlPoint(Vector pos, Vector orient, float speed)
93{
94 position = pos;
95 orient.AngleVectors(&orientation, NULL, NULL);
96 roll = orient[ROLL];
97 if (roll > 180) {
98 roll -= 360;
99 }
100 if (roll < -180) {
101 roll += 360;
102 }
103 this->speed = speed;
104}
105
106inline void BSplineControlPoint::Clear(void)
107{
108 roll = 0;
109 position = "0 0 0";
110 vec_zero.AngleVectors(&orientation, NULL, NULL);
111 speed = 1.0f;
112}
113
114inline void BSplineControlPoint::Set(Vector pos)
115{
116 speed = 1;
117 position = pos;
118}
119
120inline void BSplineControlPoint::Set(Vector pos, float pointspeed)
121{
122 speed = pointspeed;
123 position = pos;
124}
125
126inline void BSplineControlPoint::Set(Vector pos, Vector orient, float speed)
127{
128 position = pos;
129 orient.AngleVectors(&orientation, NULL, NULL);
130 roll = orient[ROLL];
131 if (roll > 180) {
132 roll -= 360;
133 }
134 if (roll < -180) {
135 roll += 360;
136 }
137 this->speed = speed;
138}
139
140inline void BSplineControlPoint::Get(Vector& pos)
141{
142 pos = position;
143}
144
145inline Vector *BSplineControlPoint::GetPosition(void)
146{
147 return &position;
148}
149
150inline void BSplineControlPoint::Get(Vector& pos, Vector& orient, float& speed)
151{
152 pos = position;
153 orient = orientation;
154 speed = this->speed;
155}
156
157inline Vector *BSplineControlPoint::GetOrientation(void)
158{
159 return &orientation;
160}
161
162inline float *BSplineControlPoint::GetRoll(void)
163{
164 return &roll;
165}
166
167inline float *BSplineControlPoint::GetSpeed(void)
168{
169 return &speed;
170}
171
172class BSpline : public Class
173{
174private:
175 BSplineControlPoint *control_points;
176 int num_control_points;
177 int loop_control_point;
178 splinetype_t curvetype;
179 qboolean has_orientation;
180
181 float EvalNormal(float u, Vector& pos, Vector& orient);
182 float EvalLoop(float u, Vector& pos, Vector& orient);
183 float EvalClamp(float u, Vector& pos, Vector& orient);
184
185public:
186 BSpline();
187 ~BSpline();
188 BSpline(Vector *control_points_, int num_control_points_, splinetype_t type);
189 BSpline(
190 Vector *control_points_,
191 Vector *control_orients_,
192 float *control_speeds_,
193 int num_control_points_,
194 splinetype_t type
195 );
196 void operator=(BSpline& spline);
197 void SetType(splinetype_t type);
198 int GetType(void);
199 void Clear(void);
200 void Set(Vector *control_points_, int num_control_points_, splinetype_t type);
201 void
202 Set(Vector *control_points_,
203 Vector *control_orients_,
204 float *control_speeds_,
205 int num_control_points_,
206 splinetype_t type);
207 void AppendControlPoint(const Vector& new_control_point);
208 void AppendControlPoint(const Vector& new_control_point, const float& speed);
209 void AppendControlPoint(const Vector& new_control_point, const Vector& new_control_orient, const float& speed);
210 Vector Eval(float u);
211 float Eval(float u, Vector& pos, Vector& orient);
212
213 void DrawControlSegments(void);
214 void DrawCurve(int num_subdivisions);
215 void DrawCurve(Vector offset, int num_subdivisions);
216
217 void SetLoopPoint(const Vector& pos);
218
219 float EndPoint(void);
220
221 // return the index of the control point picked or -1 if none.
222 int PickControlPoint(const Vector& window_point, float pick_size);
223
224 Vector *GetControlPoint(int id);
225 void GetControlPoint(int id, Vector& pos, Vector& orient, float& speed);
226 void SetControlPoint(int id, const Vector& new_control_point);
227 void SetControlPoint(int id, const Vector& new_control_point, const Vector& new_control_orient, const float& speed);
228 void Archive(Archiver& arc) override;
229};
230
231inline BSpline::BSpline()
232{
233 has_orientation = qfalse;
234 control_points = NULL;
235 num_control_points = 0;
236 loop_control_point = 0;
237 curvetype = SPLINE_NORMAL;
238}
239
240inline BSpline::~BSpline()
241{
242 if (control_points) {
243 delete[] control_points;
244 control_points = NULL;
245 }
246}
247
248inline BSpline::BSpline(Vector *control_points_, int num_control_points_, splinetype_t type)
249{
250 has_orientation = false;
251 control_points = NULL;
252 num_control_points = 0;
253 loop_control_point = 0;
254 curvetype = SPLINE_NORMAL;
255
256 Set(control_points_, num_control_points_, type);
257}
258
259inline BSpline::BSpline(
260 Vector *control_points_,
261 Vector *control_orients_,
262 float *control_speeds_,
263 int num_control_points_,
264 splinetype_t type
265)
266{
267 has_orientation = false;
268 control_points = NULL;
269 num_control_points = 0;
270 loop_control_point = 0;
271 curvetype = SPLINE_NORMAL;
272
273 Set(control_points_, control_orients_, control_speeds_, num_control_points_, type);
274}
275
276inline void BSpline::operator=(BSpline& spline)
277{
278 int i;
279
280 Clear();
281 num_control_points = spline.num_control_points;
282 loop_control_point = spline.loop_control_point;
283 curvetype = spline.curvetype;
284 has_orientation = spline.has_orientation;
285
286 if (num_control_points) {
287 control_points = new BSplineControlPoint[num_control_points];
288 assert(control_points);
289 for (i = 0; i < num_control_points; i++) {
290 control_points[i] = spline.control_points[i];
291 }
292 } else {
293 control_points = NULL;
294 }
295}
296
297inline void BSpline::SetType(splinetype_t type)
298{
299 curvetype = type;
300}
301
302inline int BSpline::GetType(void)
303{
304 return curvetype;
305}
306
307inline float BSpline::EndPoint(void)
308{
309 return num_control_points;
310}
311
312inline Vector *BSpline::GetControlPoint(int id)
313{
314 assert(id >= 0);
315 assert(id < num_control_points);
316 if ((id < 0) && (id >= num_control_points)) {
317 // probably wrong, but if we're in release mode we have no recourse
318 id = 0;
319 }
320
321 return control_points[id].GetPosition();
322}
323
324inline void BSpline::GetControlPoint(int id, Vector& pos, Vector& orient, float& speed)
325{
326 assert(id >= 0);
327 assert(id < num_control_points);
328 if ((id >= 0) && (id < num_control_points)) {
329 control_points[id].Get(pos, orient, speed);
330 }
331}
332
333inline void BSpline::SetControlPoint(int id, const Vector& new_control_point)
334{
335 assert(id >= 0);
336 assert(id < num_control_points);
337 if ((id >= 0) && (id < num_control_points)) {
338 control_points[id].Set(new_control_point);
339 }
340}
341
342inline void
343BSpline::SetControlPoint(int id, const Vector& new_control_point, const Vector& new_control_orient, const float& speed)
344{
345 assert(id >= 0);
346 assert(id < num_control_points);
347 if ((id >= 0) && (id < num_control_points)) {
348 control_points[id].Set(new_control_point, new_control_orient, speed);
349 }
350}
351
352inline void BSpline::Archive(Archiver& arc)
353{
354 int i;
355
356 arc.ArchiveInteger(&num_control_points);
357 if (arc.Loading()) {
358 if (num_control_points) {
359 control_points = new BSplineControlPoint[num_control_points];
360 } else {
361 control_points = NULL;
362 }
363 }
364
365 arc.ArchiveInteger(&loop_control_point);
366
367 i = curvetype;
368 arc.ArchiveInteger(&i);
369 curvetype = (splinetype_t)i;
370
371 arc.ArchiveBoolean(&has_orientation);
372 for (i = 0; i < num_control_points; i++) {
373 control_points[i].Archive(arc);
374 }
375}
376
377extern Event EV_SplinePath_Create;
378extern Event EV_SplinePath_Loop;
379extern Event EV_SplinePath_Speed;
380
381class SplinePath : public Entity
382{
383protected:
384 SplinePath *owner;
385 SplinePath *next;
386 SplinePath *loop;
387 str loop_name;
388
389 void CreatePath(Event *ev);
390 void SetLoop(Event *ev);
391 void SetSpeed(Event *ev);
392 void SetTriggerTarget(Event *ev);
393 void SetThread(Event *ev);
394 void SetFov(Event *ev);
395 void SetWatch(Event *ev);
396 void SetFadeTime(Event *ev);
397
398public:
399 float speed;
400 float fov;
401 float fadeTime;
402 qboolean doWatch;
403 str watchEnt;
404 str triggertarget;
405 str thread;
406
407 CLASS_PROTOTYPE(SplinePath);
408
409 SplinePath();
410 ~SplinePath();
411 SplinePath *GetNext(void);
412 SplinePath *GetPrev(void);
413 SplinePath *GetLoop(void);
414 void SetFadeTime(float newFadeTime);
415 void SetFov(float theFov);
416 void SetWatch(const char *name);
417 void SetThread(const char *name);
418 void SetTriggerTarget(const char *name);
419 void NoWatch(void);
420 str GetWatch(void);
421 float GetFadeTime(void);
422 float GetFov(void);
423 void SetNext(SplinePath *node);
424 void SetPrev(SplinePath *node);
425 void Archive(Archiver& arc) override;
426};
427
428typedef SafePtr<SplinePath> SplinePathPtr;
429
430inline void SplinePath::Archive(Archiver& arc)
431{
432 Entity::Archive(arc);
433
434 arc.ArchiveObjectPointer((Class **)&owner);
435 arc.ArchiveObjectPointer((Class **)&next);
436 arc.ArchiveObjectPointer((Class **)&loop);
437 arc.ArchiveString(&loop_name);
438 arc.ArchiveFloat(&speed);
439 arc.ArchiveFloat(&fov);
440 arc.ArchiveFloat(&fadeTime);
441 arc.ArchiveBoolean(&doWatch);
442 arc.ArchiveString(&watchEnt);
443 arc.ArchiveString(&thread);
444 arc.ArchiveString(&triggertarget);
445 if (arc.Loading()) {
446 CancelEventsOfType(EV_SplinePath_Create);
447 }
448}
449
450inline void SplinePath::SetThread(const char *name)
451{
452 thread = name;
453}
454
455inline void SplinePath::SetTriggerTarget(const char *name)
456{
457 triggertarget = name;
458}
Definition archive.h:86
Definition bspline.h:39
Definition bspline.h:173
Definition class.h:276
Definition listener.h:246
Definition safeptr.h:160
Definition vector.h:61
Definition str.h:77