OpenMoHAA 0.82.0
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 {
34 SPLINE_NORMAL,
35 SPLINE_LOOP,
36 SPLINE_CLAMP
37 } splinetype_t;
38
39class BSplineControlPoint : public Class
40 {
41 private:
42 float roll;
43 Vector position;
44 Vector orientation;
45 float speed;
46
47 public:
48 BSplineControlPoint();
49 BSplineControlPoint( Vector pos, Vector orient, float speed );
50 BSplineControlPoint( Vector pos );
51 void Clear( void );
52 void Set( Vector pos );
53 void Set( Vector pos, float speed );
54 void Set( Vector pos, Vector orient, float speed );
55 void Get( Vector& pos, Vector& orient, float& speed );
56 void Get( Vector& pos );
57 Vector *GetPosition( void );
58 Vector *GetOrientation( void );
59 float *GetRoll( void );
60 float *GetSpeed( void );
61 void operator=( BSplineControlPoint &point );
62 void Archive( Archiver &arc ) override;
63 };
64
65inline void BSplineControlPoint::Archive
66 (
67 Archiver &arc
68 )
69
70 {
71 arc.ArchiveVector( &position );
72 arc.ArchiveVector( &orientation );
73 arc.ArchiveFloat( &speed );
74 arc.ArchiveFloat( &roll );
75 }
76
77inline void BSplineControlPoint::operator=
78 (
80 )
81
82 {
83 position = point.position;
84 orientation = point.orientation;
85 speed = point.speed;
86 roll = point.roll;
87 }
88
89inline BSplineControlPoint::BSplineControlPoint()
90 {
91 roll = 0;
92 speed = 1;
93 }
94
95inline BSplineControlPoint::BSplineControlPoint
96 (
97 Vector pos
98 )
99
100 {
101 speed = 1;
102 position = pos;
103 }
104
105inline BSplineControlPoint::BSplineControlPoint
106 (
107 Vector pos,
108 Vector orient,
109 float speed
110 )
111
112 {
113 position = pos;
114 orient.AngleVectors( &orientation, NULL, NULL );
115 roll = orient[ ROLL ];
116 if ( roll > 180 )
117 {
118 roll -= 360;
119 }
120 if ( roll < -180 )
121 {
122 roll += 360;
123 }
124 this->speed = speed;
125 }
126
127inline void BSplineControlPoint::Clear
128 (
129 void
130 )
131
132 {
133 roll = 0;
134 position = "0 0 0";
135 vec_zero.AngleVectors( &orientation, NULL, NULL );
136 speed = 1.0f;
137 }
138
139inline void BSplineControlPoint::Set
140 (
141 Vector pos
142 )
143
144 {
145 speed = 1;
146 position = pos;
147 }
148
149inline void BSplineControlPoint::Set
150 (
151 Vector pos,
152 float pointspeed
153 )
154
155 {
156 speed = pointspeed;
157 position = pos;
158 }
159
160inline void BSplineControlPoint::Set
161 (
162 Vector pos,
163 Vector orient,
164 float speed
165 )
166
167 {
168 position = pos;
169 orient.AngleVectors( &orientation, NULL, NULL );
170 roll = orient[ ROLL ];
171 if ( roll > 180 )
172 {
173 roll -= 360;
174 }
175 if ( roll < -180 )
176 {
177 roll += 360;
178 }
179 this->speed = speed;
180 }
181
182inline void BSplineControlPoint::Get
183 (
184 Vector& pos
185 )
186 {
187 pos = position;
188 }
189
190inline Vector *BSplineControlPoint::GetPosition
191 (
192 void
193 )
194
195 {
196 return &position;
197 }
198
199inline void BSplineControlPoint::Get
200 (
201 Vector& pos,
202 Vector& orient,
203 float& speed
204 )
205
206 {
207 pos = position;
208 orient = orientation;
209 speed = this->speed;
210 }
211
212inline Vector *BSplineControlPoint::GetOrientation
213 (
214 void
215 )
216 {
217 return &orientation;
218 }
219
220inline float *BSplineControlPoint::GetRoll
221 (
222 void
223 )
224 {
225 return &roll;
226 }
227
228inline float *BSplineControlPoint::GetSpeed
229 (
230 void
231 )
232 {
233 return &speed;
234 }
235
236class BSpline : public Class
237 {
238 private:
239 BSplineControlPoint *control_points;
240 int num_control_points;
241 int loop_control_point;
242 splinetype_t curvetype;
243 qboolean has_orientation;
244
245 float EvalNormal( float u, Vector &pos, Vector& orient );
246 float EvalLoop( float u, Vector &pos, Vector& orient );
247 float EvalClamp( float u, Vector &pos, Vector& orient );
248
249 public:
250 BSpline();
251 ~BSpline();
252 BSpline( Vector *control_points_, int num_control_points_, splinetype_t type );
253 BSpline( Vector *control_points_, Vector *control_orients_, float *control_speeds_, int num_control_points_, splinetype_t type );
254 void operator=( BSpline &spline );
255 void SetType( splinetype_t type );
256 int GetType( void );
257 void Clear( void );
258 void Set( Vector *control_points_, int num_control_points_, splinetype_t type );
259 void Set( Vector *control_points_, Vector *control_orients_, float *control_speeds_, int num_control_points_, splinetype_t type );
260 void AppendControlPoint( const Vector& new_control_point );
261 void AppendControlPoint( const Vector& new_control_point, const float& speed );
262 void AppendControlPoint( const Vector& new_control_point, const Vector& new_control_orient, const float& speed );
263 Vector Eval( float u );
264 float Eval( float u, Vector& pos, Vector& orient );
265
266 void DrawControlSegments( void );
267 void DrawCurve( int num_subdivisions );
268 void DrawCurve( Vector offset, int num_subdivisions );
269
270 void SetLoopPoint( const Vector& pos );
271
272 float EndPoint( void );
273
274 // return the index of the control point picked or -1 if none.
275 int PickControlPoint( const Vector& window_point, float pick_size );
276
277 Vector *GetControlPoint( int id );
278 void GetControlPoint( int id, Vector& pos, Vector& orient, float& speed );
279 void SetControlPoint( int id, const Vector& new_control_point );
280 void SetControlPoint( int id, const Vector& new_control_point, const Vector& new_control_orient, const float& speed );
281 void Archive( Archiver &arc ) override;
282 };
283
284inline BSpline::BSpline()
285 {
286 has_orientation = qfalse;
287 control_points = NULL;
288 num_control_points = 0;
289 loop_control_point = 0;
290 curvetype = SPLINE_NORMAL;
291 }
292
293inline BSpline::~BSpline()
294 {
295 if ( control_points )
296 {
297 delete [] control_points;
298 control_points = NULL;
299 }
300 }
301
302inline BSpline::BSpline
303 (
304 Vector *control_points_,
305 int num_control_points_,
306 splinetype_t type
307 )
308
309 {
310 has_orientation = false;
311 control_points = NULL;
312 num_control_points = 0;
313 loop_control_point = 0;
314 curvetype = SPLINE_NORMAL;
315
316 Set( control_points_, num_control_points_, type );
317 }
318
319inline BSpline::BSpline
320 (
321 Vector *control_points_,
322 Vector *control_orients_,
323 float *control_speeds_,
324 int num_control_points_,
325 splinetype_t type
326 )
327
328 {
329 has_orientation = false;
330 control_points = NULL;
331 num_control_points = 0;
332 loop_control_point = 0;
333 curvetype = SPLINE_NORMAL;
334
335 Set( control_points_, control_orients_, control_speeds_, num_control_points_, type );
336 }
337
338inline void BSpline::operator=
339 (
340 BSpline &spline
341 )
342
343 {
344 int i;
345
346 Clear();
347 num_control_points = spline.num_control_points;
348 loop_control_point = spline.loop_control_point;
349 curvetype = spline.curvetype;
350 has_orientation = spline.has_orientation;
351
352 if ( num_control_points )
353 {
354 control_points = new BSplineControlPoint[num_control_points];
355 assert( control_points );
356 for ( i = 0; i < num_control_points ; i++ )
357 control_points[ i ] = spline.control_points[ i ];
358 }
359 else
360 {
361 control_points = NULL;
362 }
363 }
364
365inline void BSpline::SetType
366 (
367 splinetype_t type
368 )
369
370 {
371 curvetype = type;
372 }
373
374inline int BSpline::GetType
375 (
376 void
377 )
378
379 {
380 return curvetype;
381 }
382
383inline float BSpline::EndPoint
384 (
385 void
386 )
387
388 {
389 return num_control_points;
390 }
391
392inline Vector *BSpline::GetControlPoint
393 (
394 int id
395 )
396
397 {
398 assert( id >= 0 );
399 assert( id < num_control_points );
400 if ( ( id < 0 ) && ( id >= num_control_points ) )
401 {
402 // probably wrong, but if we're in release mode we have no recourse
403 id = 0;
404 }
405
406 return control_points[ id ].GetPosition();
407 }
408
409inline void BSpline::GetControlPoint
410 (
411 int id,
412 Vector& pos,
413 Vector& orient,
414 float& speed
415 )
416
417 {
418 assert( id >= 0 );
419 assert( id < num_control_points );
420 if ( ( id >= 0 ) && ( id < num_control_points ) )
421 {
422 control_points[ id ].Get( pos, orient, speed );
423 }
424 }
425
426inline void BSpline::SetControlPoint
427 (
428 int id,
429 const Vector& new_control_point
430 )
431
432 {
433 assert( id >= 0 );
434 assert( id < num_control_points );
435 if ( ( id >= 0 ) && ( id < num_control_points ) )
436 {
437 control_points[ id ].Set( new_control_point );
438 }
439 }
440
441inline void BSpline::SetControlPoint
442 (
443 int id,
444 const Vector& new_control_point,
445 const Vector& new_control_orient,
446 const float& speed
447 )
448
449 {
450 assert( id >= 0 );
451 assert( id < num_control_points );
452 if ( ( id >= 0 ) && ( id < num_control_points ) )
453 {
454 control_points[ id ].Set( new_control_point, new_control_orient, speed );
455 }
456 }
457
458inline void BSpline::Archive
459 (
460 Archiver &arc
461 )
462 {
463 int i;
464
465 arc.ArchiveInteger( &num_control_points );
466 if ( arc.Loading() )
467 {
468 if ( num_control_points )
469 control_points = new BSplineControlPoint[ num_control_points ];
470 else
471 control_points = NULL;
472 }
473
474 arc.ArchiveInteger( &loop_control_point );
475
476 i = curvetype;
477 arc.ArchiveInteger( &i );
478 curvetype = ( splinetype_t )i;
479
480 arc.ArchiveBoolean( &has_orientation );
481 for( i = 0; i < num_control_points; i++ )
482 {
483 control_points[ i ].Archive( arc );
484 }
485 }
486
487extern Event EV_SplinePath_Create;
488extern Event EV_SplinePath_Loop;
489extern Event EV_SplinePath_Speed;
490
491class SplinePath : public Entity
492 {
493 protected:
494 SplinePath *owner;
495 SplinePath *next;
496 SplinePath *loop;
497 str loop_name;
498
499 void CreatePath( Event *ev );
500 void SetLoop( Event *ev );
501 void SetSpeed( Event *ev );
502 void SetTriggerTarget( Event *ev );
503 void SetThread( Event *ev );
504 void SetFov( Event *ev );
505 void SetWatch( Event *ev );
506 void SetFadeTime( Event *ev );
507
508 public:
509 float speed;
510 float fov;
511 float fadeTime;
512 qboolean doWatch;
513 str watchEnt;
514 str triggertarget;
515 str thread;
516
517 CLASS_PROTOTYPE( SplinePath );
518
519 SplinePath();
520 ~SplinePath();
521 SplinePath *GetNext( void );
522 SplinePath *GetPrev( void );
523 SplinePath *GetLoop( void );
524 void SetFadeTime( float newFadeTime );
525 void SetFov( float theFov );
526 void SetWatch( const char *name );
527 void SetThread( const char *name );
528 void SetTriggerTarget( const char *name );
529 void NoWatch( void );
530 str GetWatch( void );
531 float GetFadeTime( void );
532 float GetFov( void );
533 void SetNext( SplinePath *node );
534 void SetPrev( SplinePath *node );
535 void Archive( Archiver &arc ) override;
536 };
537
538typedef SafePtr<SplinePath> SplinePathPtr;
539
540inline void SplinePath::Archive
541 (
542 Archiver &arc
543 )
544
545 {
546 Entity::Archive( arc );
547
548 arc.ArchiveObjectPointer( ( Class ** )&owner );
549 arc.ArchiveObjectPointer( ( Class ** )&next );
550 arc.ArchiveObjectPointer( ( Class ** )&loop );
551 arc.ArchiveString( &loop_name );
552 arc.ArchiveFloat( &speed );
553 arc.ArchiveFloat( &fov );
554 arc.ArchiveFloat( &fadeTime );
555 arc.ArchiveBoolean( &doWatch );
556 arc.ArchiveString( &watchEnt );
557 arc.ArchiveString( &thread );
558 arc.ArchiveString( &triggertarget );
559 if ( arc.Loading() )
560 {
561 CancelEventsOfType( EV_SplinePath_Create );
562 }
563 }
564
565inline void SplinePath::SetThread
566 (
567 const char *name
568 )
569
570 {
571 thread = name;
572 }
573
574inline void SplinePath::SetTriggerTarget
575 (
576 const char *name
577 )
578
579 {
580 triggertarget = name;
581 }
Definition archive.h:86
Definition bspline.h:40
Definition bspline.h:237
Definition class.h:276
Definition listener.h:246
Definition safeptr.h:160
Definition vector.h:61
Definition str.h:77