This file is indexed.

/usr/include/crystalspace-2.0/ivaria/ode.h is in libcrystalspace-dev 2.0+dfsg-1build1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
/*
    Copyright (C) 2003 by Jorrit Tyberghein, Daniel Duhprey,
    Leandro Motta Barros

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License as published by the Free Software Foundation; either
    version 2 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Library General Public License for more details.

    You should have received a copy of the GNU Library General Public
    License along with this library; if not, write to the Free
    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

#ifndef __CS_IVARIA_ODE_H__
#define __CS_IVARIA_ODE_H__

/**\file
 * ODE-specific interfaces
 */

#include "csutil/scf_interface.h"

/**
 * This class can be passed in as a callback during the physics update
 * it is only called if FrameRate is enabled.
 */
struct iODEFrameUpdateCallback : public virtual iBase
{
  SCF_INTERFACE(iODEFrameUpdateCallback, 2, 0, 0);

  /// Executes the per update callback
  virtual void Execute (float stepsize) = 0;
};

/**
 * This class exposes parameters specific to odedynam as an implementation
 * of iDynamics.
 * \sa iDynamics
 */
struct iODEDynamicState : public virtual iBase
{
  SCF_INTERFACE(iODEDynamicState, 2, 0, 0);


  /// Sets ODE's Error Resolution Parameter (see ode docs for details)
  virtual void SetGlobalERP (float erp) = 0;
  virtual float GlobalERP () = 0;

  /// Sets ODE's Constraint Force Mixing (see ode docs for details)
  virtual void SetGlobalCFM (float cfm) = 0;
  virtual float GlobalCFM () = 0;

  /// Enables the experimental StepFast code in ode
  virtual void EnableStepFast (bool enable) = 0;
  virtual bool StepFastEnabled () = 0;
  virtual void SetStepFastIterations (int iter) = 0;
  virtual int StepFastIterations () = 0;

  virtual void EnableQuickStep (bool enable) = 0;
  virtual bool QuickStepEnabled () = 0;
  virtual void SetQuickStepIterations (int iter) = 0;
  virtual int QuickStepIterations () = 0;

  /**
   * The following code enables a constant framerate on processing
   * this means if you set the frame rate to (default) 50  The stepsize
   * passed into Step is treated as the elapsed time in seconds received
   * from the virtual clock GetElapsedTicks.
   * The physics will iterate a number of steps at 1/50th
   * of a second until enough time has passed to account for the time
   * Beware the default setting for frame limit is 10, which means
   * if the stepsize passed to Step is longer than 1/10 a second
   * the physics will stop iterating and slow down.  Never set this
   * parameter to 0 or else you could incur cycle of death where
   * the number of physics steps increases the amount of elapsed
   * time between frames which increases the number of physics steps
   * toward infinity
   */
  virtual void EnableFrameRate (bool enable) = 0;
  virtual bool FrameRateEnabled () = 0;

  virtual void SetFrameRate (float hz) = 0;
  virtual float FrameRate () = 0;

  virtual void SetFrameLimit (float hz) = 0;
  virtual float FrameLimit () = 0;

  virtual void AddFrameUpdateCallback (iODEFrameUpdateCallback *cb) = 0;
  virtual void RemoveFrameUpdateCallback (iODEFrameUpdateCallback *cb) = 0;

  /** 
   * This makes updates happen during the logic phase 
   * and invalidates calls to Step()
   * This should be used in conjuction with the FrameRate calls
   */
  virtual void EnableEventProcessing (bool enable) = 0;
  virtual bool EventProcessingEnabled () = 0;

  /**
   * The following enables special robustness checks for fast
   * moving objects to determine if they will tunneling and
   * adjusts the physics frame resolution (rate) to a double
   * for that step (possible doing this recursively down to
   * a potentially infinite resolution for a given step, depending
   * on the speed of the objects being tested)  Only enable
   * this if you are experiencing tunneling problems and can't
   * afford to increase the standard FrameRate in the settings
   * above
   */
  virtual void EnableFastObjects (bool enable) = 0;
  virtual bool FastObjectsEnabled () = 0;

};

struct iODEBallJoint;
struct iODEHingeJoint;
struct iODEHinge2Joint;
struct iODEAMotorJoint;
struct iODEUniversalJoint;
struct iODESliderJoint;

/**
 * This class exposes parameters specific to odedynam as an implementation
 * of iDynamicsSystem. In most cases SystemState should not be modified directly
 * unless you want the behavior of a specific system different from others.
 * \sa iDynamicSystem CS::Physics::Bullet::iDynamicSystem
 */
struct iODEDynamicSystemState : public virtual iBase
{
  SCF_INTERFACE(iODEDynamicSystemState, 2, 1, 0);

  /**
   * Sets ODE's Error Resolution Parameter (see ode docs for details)
   * Setting this in iODEDynamicState will set it for each System
   * Use this only if you want a specific system to behave differently
   */
  virtual void SetERP (float erp) = 0;
  virtual float ERP () = 0;

  /**
   * Sets ODE's Constraint Force Mixing (see ode docs for details)
   * Setting this in iODEDynamicState will set it for each System
   * Use this only if you want a specific system to behave differently
   */
  virtual void SetCFM (float cfm) = 0;
  virtual float CFM () = 0;

  /**
   * Enables the experimental StepFast code in ode
   * Setting this in ODEDynamicState sets it here
   * Only modify it if you want a specific system to behave differently
   */
  virtual void EnableStepFast (bool enable) = 0;
  virtual bool StepFastEnabled () = 0;
  virtual void SetStepFastIterations (int iter) = 0;
  virtual int StepFastIterations () = 0;

  virtual void EnableQuickStep (bool enable) = 0;
  virtual bool QuickStepEnabled () = 0;
  virtual void SetQuickStepIterations (int iter) = 0;
  virtual int QuickStepIterations () = 0;

  /**
   * Turn on/off AutoDisable functionality.
   * AutoDisable will stop moving objects if they are stable in order
   * to save processing time.
   */
  virtual void EnableAutoDisable (bool enable) = 0;
  virtual bool AutoDisableEnabled () =0;
  /**
   * Set the parameters for AutoDisable.
   * \param linear Maximum linear movement to disable a body
   * \param angular Maximum angular movement to disable a body
   * \param steps Minimum number of steps the body meets linear and angular
   *        requirements before it is disabled.
   * \param time Minimum time the body needs to meet linear and angular movement
   *        requirements before it is disabled.
   */
  virtual void SetAutoDisableParams (float linear, float angular, int steps,
    float time)=0;

  /**
   * NOTE: This should not be done here if its been done in iODEDynamicState
   * The following code enables a constant framerate on processing
   * this means if you set the frame rate to (default) 50  The stepsize
   * passed into Step is treated as the elapsed time in seconds received
   * from the virtual clock GetElapsedTicks.
   * The physics will iterate a number of steps at 1/50th
   * of a second until enough time has passed to account for the time
   * Beware the default setting for frame limit is 10, which means
   * if the stepsize passed to Step is longer than 1/10 a second
   * the physics will stop iterating and slow down.  Never set this
   * parameter to 0 or else you could incur cycle of death where
   * the number of physics steps increases the amount of elapsed
   * time between frames which increases the number of physics steps
   * toward infinity
   */
  virtual void EnableFrameRate (bool enable) = 0;
  virtual bool FrameRateEnabled () = 0;

  virtual void SetFrameRate (float hz) = 0;
  virtual float FrameRate () = 0;

  virtual void SetFrameLimit (float hz) = 0;
  virtual float FrameLimit () = 0;

  virtual void AddFrameUpdateCallback (iODEFrameUpdateCallback *cb) = 0;
  virtual void RemoveFrameUpdateCallback (iODEFrameUpdateCallback *cb) = 0;

  /**
   * The following enables special robustness checks for fast
   * moving objects to determine if they will tunneling and
   * adjusts the physics frame resolution (rate) to a double
   * for that step (possible doing this recursively down to
   * a potentially infinite resolution for a given step, depending
   * on the speed of the objects being tested)  Only enable
   * this if you are experiencing tunneling problems and can't
   * afford to increase the standard FrameRate in the settings
   * above
   * Setting this in iODEDynamicState will set it for each System
   * Use this only if you want a specific system to behave differently
   */
  virtual void EnableFastObjects (bool enable) = 0;
  virtual bool FastObjectsEnabled () = 0;

  /// Create a ball joint and add it to he simulation
  virtual csPtr<iODEBallJoint> CreateBallJoint () = 0;

  /// Create a hinge joint and add it to he simulation
  virtual csPtr<iODEHingeJoint> CreateHingeJoint () = 0;

  /// Create a hinge2 joint and add it to he simulation
  virtual csPtr<iODEHinge2Joint> CreateHinge2Joint () = 0;

  /// Create a AMotor joint and add it to he simulation
  virtual csPtr<iODEAMotorJoint> CreateAMotorJoint () = 0;

  /// Create a Universal joint and add it to he simulation
  virtual csPtr<iODEUniversalJoint> CreateUniversalJoint () = 0;

  /// Create a Slider joint and add it to he simulation
  virtual csPtr<iODESliderJoint> CreateSliderJoint () = 0;

  /// Remove a ball joint from the simulation
  virtual void RemoveJoint (iODEBallJoint* joint) = 0;

  /// Remove a hinge joint from the simulation
  virtual void RemoveJoint (iODEHingeJoint* joint) = 0;

  /// Remove a AMotor joint from the simulation
  virtual void RemoveJoint (iODEAMotorJoint* joint) = 0;

  /// Remove a Universal joint from the simulation
  virtual void RemoveJoint (iODEUniversalJoint* joint) = 0;

  /// Remove a Slider joint from the simulation
  virtual void RemoveJoint (iODESliderJoint* joint) = 0;

  /// Remove a Slider joint from the simulation
  virtual void RemoveJoint (iODEHinge2Joint* joint) = 0;

  /**
   * Set the maximum correcting velocity that contacts are
   * allowed to generate. The default value is infinity (i.e. no
   * limit). Reducing this value can help prevent "popping" of deeply
   * embedded objects.
   * \param v velocity
   */
  virtual void SetContactMaxCorrectingVel (float v) = 0;

  /**
   * Get the maximum correcting velocity that contacts are
   * allowed to generate. The default value is infinity (i.e. no
   * limit). Reducing this value can help prevent "popping" of deeply
   * embedded objects.
   */
  virtual float GetContactMaxCorrectingVel () = 0;

  /**
   * Set the depth of the surface layer around all geometry
   * objects. Contacts are allowed to sink into the surface layer up
   * to the given depth before coming to rest. The default value is
   * zero. Increasing this to some small value (e.g. 0.001) can help
   * prevent jittering problems due to contacts being repeatedly made
   * and broken.
   * \param depth the distance two bodies are allowed to interpenetrate
   */
  virtual void SetContactSurfaceLayer (float depth) = 0;

  /**
   * Get the depth of the surface layer around all geometry
   * objects. Contacts are allowed to sink into the surface layer up
   * to the given depth before coming to rest. The default value is
   * zero. Increasing this to some small value (e.g. 0.001) can help
   * prevent jittering problems due to contacts being repeatedly made
   * and broken.
   * \return the distance two bodies are allowed to interpenetrate
   */
  virtual float GetContactSurfaceLayer () = 0;

  /**
   * Set the code to use previous and broken inertia calculation. Use only
   * if you know you need it
   */
  virtual void EnableOldInertia (bool enable) = 0;
  virtual bool IsOldInertiaEnabled () const = 0;
};

/**
 * \todo Document me!
 */
enum ODEJointType
{
  CS_ODE_JOINT_TYPE_UNKNOWN = -1,
  CS_ODE_JOINT_TYPE_BALL,
  CS_ODE_JOINT_TYPE_HINGE,
  CS_ODE_JOINT_TYPE_SLIDER,
  CS_ODE_JOINT_TYPE_CONTACT,
  CS_ODE_JOINT_TYPE_UNIVERSAL,
  CS_ODE_JOINT_TYPE_HINGE2,
  CS_ODE_JOINT_TYPE_FIXED,
  CS_ODE_JOINT_TYPE_AMOTOR
};

/**
* General joint state. Here
*/
struct iODEJointState : public virtual iBase
{
  SCF_INTERFACE(iODEJointState, 2, 0, 0);

  virtual ODEJointType GetType() = 0;

  /**
   * Set low stop angle or position. For rotational joints, this
   * stop must be greater than - pi to be effective.
   */
  virtual void SetLoStop (const csVector3 &value) = 0;

  /**
   * Set high stop angle or position. For rotational joints, this stop must
   * be less than pi to be effective. If the high stop is less than the low
   * stop then both stops will be ineffective.
   */
  virtual void SetHiStop (const csVector3 &value) = 0;

  /// Set desired motor velocity (this will be an angular or linear velocity).
  virtual void SetVel (const csVector3 &value) = 0;

  /**
   * Set the maximum force or torque that the motor will use to achieve the
   * desired velocity. This must always be greater than or equal to zero.
   * Setting this to zero turns off the motor.
   */
  virtual void SetFMax (const csVector3 &value) = 0;

  /**
   * Set the fudge factor. The current joint stop/motor implementation has a
   * small problem: when the joint is at one stop and the motor is set to move
   * it away from the stop, too much force may be applied for one time step,
   * causing a ``jumping'' motion. This fudge factor is used to scale this
   * excess force. It should have a value between zero and one (the default
   * value). If the jumping motion is too visible in a
   * joint, the value can be reduced. Making this value too small can prevent
   * the motor from being able to move the joint away from a stop.
   */
  virtual void SetFudgeFactor (const csVector3 &value) = 0;

  /**
   * Set the bouncyness of the stops. This is a restitution parameter in the
   * range 0..1. 0 means the stops are not bouncy at all, 1 means maximum
   * bouncyness.
   */
  virtual void SetBounce (const csVector3 &value) = 0;

  /**
   * Set the constraint force mixing (CFM) value for joint used when not at a
   * stop.
   */
  virtual void SetCFM (const csVector3 &value) = 0;

  /// Set the error reduction parameter (ERP) used by the stops.
  virtual void SetStopERP (const csVector3 &value) = 0;

  /**
   * Set the constraint force mixing (CFM) value for joint used by the stops.
   * Together with the ERP value this can be used to get spongy or soft stops.
   * Note that this is intended for unpowered joints, it does not really work
   * as expected when a powered joint reaches its limit.
   */
  virtual void SetStopCFM (const csVector3 &value) = 0;

  /// Set suspension error reduction parameter (ERP).
  virtual void SetSuspensionERP (const csVector3 &value) = 0;

  /// Set suspension constraint force mixing (CFM) value.
  virtual void SetSuspensionCFM (const csVector3 &value) = 0;

  /// Get low stop angle or position.
  virtual csVector3 GetLoStop () = 0;

  /// Get high stop angle or position.
  virtual csVector3 GetHiStop () = 0;

  /// Get desired motor velocity (this will be an angular or linear velocity).
  virtual csVector3 GetVel () = 0;

  /**
   * Get the maximum force or torque that the motor will use to achieve the
   * desired velocity.
   */
  virtual csVector3 GetMaxForce () = 0;

  /// Get the fudge factor.
  virtual csVector3 GetFudgeFactor () = 0;

  /// Get the bouncyness of the stops.
  virtual csVector3 GetBounce () = 0;

  /**
   * Get the constraint force mixing (CFM) value for joint used when not
   * at a stop.
   */
  virtual csVector3 GetCFM () = 0;

  /// Get the error reduction parameter (ERP) used by the stops.
  virtual csVector3 GetStopERP () = 0;

  /// Get the constraint force mixing (CFM) value for joint used by the stops.
  virtual csVector3 GetStopCFM () = 0;

  /// Get suspension error reduction parameter (ERP).
  virtual csVector3 GetSuspensionERP () = 0;

  /// Get suspension constraint force mixing (CFM) value.
  virtual csVector3 GetSuspensionCFM () = 0;

};

/**
 * General joint state.
 */
struct iODEGeneralJointState : public virtual iBase
{
  SCF_INTERFACE(iODEGeneralJointState, 2, 0, 0);

  /**
   * Set low stop angle or position. For rotational joints, this
   * stop must be greater than - pi to be effective.
   */
  virtual void SetLoStop (float value, int axis) = 0;

  /**
   * Set high stop angle or position. For rotational joints, this stop must
   * be less than pi to be effective. If the high stop is less than the low
   * stop then both stops will be ineffective.
   */
  virtual void SetHiStop (float value, int axis) = 0;

  /// Set desired motor velocity (this will be an angular or linear velocity).
  virtual void SetVel (float value, int axis) = 0;

  /**
   * Set the maximum force or torque that the motor will use to achieve the
   * desired velocity. This must always be greater than or equal to zero.
   * Setting this to zero turns off the motor.
   */
  virtual void SetFMax (float value, int axis) = 0;

  /**
   * Set the fudge factor. The current joint stop/motor implementation has a
   * small problem: when the joint is at one stop and the motor is set to move
   * it away from the stop, too much force may be applied for one time step,
   * causing a ``jumping'' motion. This fudge factor is used to scale this
   * excess force. It should have a value between zero and one (the default
   * value). If the jumping motion is too visible in a
   * joint, the value can be reduced. Making this value too small can prevent
   * the motor from being able to move the joint away from a stop.
   */
  virtual void SetFudgeFactor (float value, int axis) = 0;

  /**
   * Set the bouncyness of the stops. This is a restitution parameter in the
   * range 0..1. 0 means the stops are not bouncy at all, 1 means maximum
   * bouncyness.
   */
  virtual void SetBounce (float value, int axis) = 0;

  /**
   * Set the constraint force mixing (CFM) value for joint used when not at a
   * stop.
   */
  virtual void SetCFM (float value, int axis) = 0;

  /// Set the error reduction parameter (ERP) used by the stops.
  virtual void SetStopERP (float value, int axis) = 0;

  /**
   * Set the constraint force mixing (CFM) value for joint used by the stops.
   * Together with the ERP value this can be used to get spongy or soft stops.
   * Note that this is intended for unpowered joints, it does not really work
   * as expected when a powered joint reaches its limit.
   */
  virtual void SetStopCFM (float value, int axis) = 0;

  /// Set suspension error reduction parameter (ERP).
  virtual void SetSuspensionERP (float value, int axis) = 0;

  /// Set suspension constraint force mixing (CFM) value.
  virtual void SetSuspensionCFM (float value, int axis) = 0;

  /// Get low stop angle or position.
  virtual float GetLoStop (int axis) = 0;

  /// Get high stop angle or position.
  virtual float GetHiStop (int axis) = 0;

  /// Get desired motor velocity (this will be an angular or linear velocity).
  virtual float GetVel (int axis) = 0;

  /**
   * Get the maximum force or torque that the motor will use to achieve the
   * desired velocity.
   */
  virtual float GetFMax (int axis) = 0;

  /// Get the fudge factor.
  virtual float GetFudgeFactor (int axis) = 0;

  /// Get the bouncyness of the stops.
  virtual float GetBounce (int axis) = 0;

  /**
   * Get the constraint force mixing (CFM) value for joint used when not
   * at a stop.
   */
  virtual float GetCFM (int axis) = 0;

  /// Get the error reduction parameter (ERP) used by the stops.
  virtual float GetStopERP (int axis) = 0;

  /// Get the constraint force mixing (CFM) value for joint used by the stops.
  virtual float GetStopCFM (int axis) = 0;

  /// Get suspension error reduction parameter (ERP).
  virtual float GetSuspensionERP (int axis) = 0;

  /// Get suspension constraint force mixing (CFM) value.
  virtual float GetSuspensionCFM (int axis) = 0;

  /**
   * Attach the joint to some new bodies. If the joint is already attached, it
   * will be detached from the old bodies first. To attach this joint to only
   * one body, set body1 or body2 to zero - a zero body refers to the static
   * environment. Setting both bodies to zero puts the joint into "limbo", i.e.
   * it will have no effect on the simulation.
   */
  virtual void Attach (iRigidBody *body1, iRigidBody *body2) = 0;

  /// Get an attached body (valid values for body are 0 and 1)
  virtual csRef<iRigidBody> GetAttachedBody (int body) = 0;

  /// Get force that joint applies to body 1
  virtual csVector3 GetFeedbackForce1 () = 0;

  /// Get torque that joint applies to body 1
  virtual csVector3 GetFeedbackTorque1 () = 0;

  /// Get force that joint applies to body 2
  virtual csVector3 GetFeedbackForce2 () = 0;

  /// Get torque that joint applies to body 2
  virtual csVector3 GetFeedbackTorque2 () = 0;

};

struct iODESliderJoint : public virtual iODEGeneralJointState
{
  SCF_INTERFACE(iODESliderJoint, 2, 1, 0);

  ///Set the slider axis.
  virtual void SetSliderAxis (float x, float y, float z) = 0;

  ///Get the slider axis.
  virtual csVector3 GetSliderAxis () = 0;

  /**
   * Get the slider linear position (i.e. the slider's "extension").
   * When the axis is set, the current position of the attached bodies
   * is examined and that position will be the zero position.
   */
  virtual float GetSliderPosition () = 0;

  ///Get the time derivative of slider position.
  virtual float GetSliderPositionRate () = 0;
};

/**
 * A universal joint is like a ball and socket joint that constrains
 * an extra degree of rotational freedom. Given axis 1 on body 1, and
 * axis 2 on body 2 that is perpendicular to axis 1, it keeps them
 * perpendicular. In other words, rotation of the two bodies about the
 * direction perpendicular to the two axes will be equal.
 */
struct iODEUniversalJoint : public virtual iODEGeneralJointState
{
  SCF_INTERFACE(iODEUniversalJoint, 2, 1, 0);

  /// Set universal anchor.
  virtual void SetUniversalAnchor (float x, float y, float z) = 0;

  /// Set axis on body 1 (should be perpendicular to axis 2)
  virtual void SetUniversalAxis1 (float x, float y, float z) = 0;

  /// Set axis on body 2 (should be perpendicular to axis 1)
  virtual void SetUniversalAxis2 (float x, float y, float z) = 0;

  /**
   * Get the joint anchor point, in world coordinates. This returns
   * the point on body 1. If the joint is perfectly satisfied, this
   * will be the same as the point on body 2.
   */
  virtual csVector3 GetUniversalAnchor1 () = 0;

  /**
   * Get the joint anchor point, in world coordinates. This returns
   * the point on body 2. If the joint is perfectly satisfied, this
   * will be the same as the point on body 1.
   */
  virtual csVector3 GetUniversalAnchor2 () = 0;

  /// Get universal axis on body 1.
  virtual csVector3 GetUniversalAxis1 () = 0;

  /// Get universal axis on body 2.
  virtual csVector3 GetUniversalAxis2 () = 0;

};

enum ODEAMotorMode
{
  CS_ODE_AMOTOR_MODE_UNKNOWN = -1,

  CS_ODE_AMOTOR_MODE_USER = 0,
  CS_ODE_AMOTOR_MODE_EULER,

  CS_ODE_AMOTOR_MODE_LAST
};

/**
 * ODE AMotor joint. An angular motor (AMotor) allows the relative
 * angular velocities of two bodies to be controlled. The angular
 * velocity can be controlled on up to three axes, allowing torque
 * motors and stops to be set for rotation about those axes. This
 * is mainly useful in conjunction with ball joints (which do not
 * constrain the angular degrees of freedom at all), but it can be
 * used in any situation where angular control is needed. To use an
 * AMotor with a ball joint, simply attach it to the same two bodies
 * that the ball joint is attached to.
 */
struct iODEAMotorJoint : public virtual iODEGeneralJointState
{
  SCF_INTERFACE(iODEAMotorJoint, 2, 1, 0);

  /**
   * Set the angular motor mode. The mode parameter must be one of the
   * following constants: CS_ODE_AMOTOR_MODE_USER (The AMotor axes and
   * joint angle settings are entirely controlled by the user, this is
   * the default mode), CS_ODE_AMOTOR_MODE_EULER ( Euler angles are
   * automatically computed, when this mode is initially set the current
   * relative orientations of the bodies will correspond to all euler
   * angles at zero).
   */
  virtual void SetAMotorMode (ODEAMotorMode mode) = 0;

  /**
   * Get the angular motor mode.
   */
  virtual ODEAMotorMode GetAMotorMode () = 0;

  /**
   * Set the number of angular axes that will be controlled by the
   * AMotor. The argument num can range from 0 (which effectively
   * deactivates the joint) to 3. This is automatically set to 3
   * in CS_ODE_AMOTOR_MODE_EULER mode.
   */
  virtual void SetAMotorNumAxes (int axis_num) = 0;

  /**
   * Get the number of angular axes that will be controlled by the
   * AMotor.
   */
  virtual int GetAMotorNumAxes () = 0;

  /**
   * Set AMotor axis.
   * \param axis_num - axis number
   * \param rel_orient - ``relative orientation'' mode:
   * - 0: The axis is anchored to the global frame.
   * - 1: The axis is anchored to the first body.
   * - 2: The axis is anchored to the second body.
   * \param x, y, z - axis
   */
  virtual void SetAMotorAxis (int axis_num, int rel_orient, float x, float y,
  	float z) = 0;

  /**
   * Set AMotor axis.
   * \param axis_num - axis number
   * \param rel_orient - ``relative orientation'' mode:
   * - 0: The axis is anchored to the global frame.
   * - 1: The axis is anchored to the first body.
   * - 2: The axis is anchored to the second body.
   */
  virtual void SetAMotorAxis (int axis_num, int rel_orient,
  	const csVector3 &axis) = 0;

  /**
   * Get AMotor axis.
   */
  virtual csVector3 GetAMotorAxis (int axis_num) = 0;

  /**
   * Get ``relative orientation'' mode:
   * - 0: The axis is anchored to the global frame.
   * - 1: The axis is anchored to the first body.
   * - 2: The axis is anchored to the second body.
   */
  virtual int GetAMotorAxisRelOrientation (int axis_num) = 0;

  /**
   * Tell the AMotor what the current angle is along axis anum. This
   * function should only be called in CS_ODE_AMOTOR_MODE_USER mode,
   * because in this mode the AMotor has no other way of knowing the
   * joint angles. The angle information is needed if stops have been
   * set along the axis, but it is not needed for axis motors.
   */
  virtual void SetAMotorAngle (int axis_num, float angle) = 0;

  /**
   * Return the current angle for axis anum. In CS_ODE_AMOTOR_MODE_USER
   * mode this is simply the value that was set with SetAMotorAngle. In
   * CS_ODE_AMOTOR_MODE_EULER mode this is the corresponding euler angle.
   */
  virtual float GetAMotorAngle (int axis_num) = 0;

  /**
   * Return the current angle rate for axis anum. In CS_ODE_AMOTOR_MODE_USER
   * mode this is always zero, as not enough information is available. In
   * CS_ODE_AMOTOR_MODE_EULER mode this is the corresponding euler angle rate.
   */
  virtual float GetAMotorAngleRate (int axis_num) = 0;
};

/**
 * ODE hinge 2 joint. The hinge-2 joint is the same as two hinges connected 
 * in series, with different hinge axe.
 */
struct iODEHinge2Joint : public virtual iODEGeneralJointState
{
  SCF_INTERFACE(iODEHinge2Joint, 2, 1, 0);

  /**
   * Set the joint anchor point. The joint will try to keep this point
   * on each body together. Input specified in world coordinates.
   */
  virtual void SetHingeAnchor (const csVector3 &pos) = 0;

  /**
   * Sets free hinge2 axis 1.
   */
  virtual void SetHingeAxis1 (const csVector3 &axis) = 0;

  /**
   * Sets free hinge2 axis 2.
   */
  virtual void SetHingeAxis2 (const csVector3 &axis) = 0;


  /**
   * Get the joint anchor point, in world coordinates. This returns the
   * point on body 1.
   */
  virtual csVector3 GetHingeAnchor1 () = 0;

  /**
   * Get the joint anchor point, in world coordinates. This returns the
   * point on body 2.
   */
  virtual csVector3 GetHingeAnchor2 () = 0;

  /**
   * Get free hinge axis 1.
   */
  virtual csVector3 GetHingeAxis1 () = 0;

  /**
   * Get free hinge axis 2.
   */
  virtual csVector3 GetHingeAxis2 () = 0;

  /**
   * Get the hinge angle. The nagle is measured between the two bodies.
   * The angle will be between -pi..pi. When the hinge anchor or axis
   * is set, the current position of the attached bodies is examined and
   * that position will be the zero angle.
   */
  virtual float GetHingeAngle () = 0;

  /**
   * Get the time derivative of angle value.
   */
  virtual float GetHingeAngleRate1 () = 0;

  /**
   * Get the time derivative of angle value.
   */
  virtual float GetHingeAngleRate2 () = 0;

  /**
   * This value will show you how far the joint has come apart.
   */
  virtual csVector3 GetAnchorError () = 0;

};

/**
 * ODE hinge joint (contrainted translation and 1 free rotation axis).
 */
struct iODEHingeJoint : public virtual iODEGeneralJointState
{
  SCF_INTERFACE(iODEHingeJoint, 2, 1, 0);

  /**
   * Set the joint anchor point. The joint will try to keep this point
   * on each body together. Input specified in world coordinates.
   */
  virtual void SetHingeAnchor (const csVector3 &pos) = 0;

  /**
   * Sets free hinge axis.
   */
  virtual void SetHingeAxis (const csVector3 &axis) = 0;

  /**
   * Get the joint anchor point, in world coordinates. This returns the
   * point on body 1.
   */
  virtual csVector3 GetHingeAnchor1 () = 0;

  /**
   * Get the joint anchor point, in world coordinates. This returns the
   * point on body 2.
   */
  virtual csVector3 GetHingeAnchor2 () = 0;

  /**
   * Get free hinge axis.
   */
  virtual csVector3 GetHingeAxis () = 0;

  /**
   * Get the hinge angle. The nagle is measured between the two bodies.
   * The angle will be between -pi..pi. When the hinge anchor or axis
   * is set, the current position of the attached bodies is examined and
   * that position will be the zero angle.
   */
  virtual float GetHingeAngle () = 0;

  /**
   * Get the time derivative of angle value.
   */
  virtual float GetHingeAngleRate () = 0;

  /**
   * This value will show you how far the joint has come apart.
   */
  virtual csVector3 GetAnchorError () = 0;

};

/**
 * ODE ball and socket joint (contrainted translation and free rotation).
 */
struct iODEBallJoint : public virtual iBase
{
  SCF_INTERFACE(iODEBallJoint, 2, 0, 0);

  /**
   * Set the joint anchor point. The joint will try to keep this point
   * on each body together. Input specified in world coordinates.
   */
  virtual void SetBallAnchor (const csVector3 &pos) = 0;

  /**
   * Get the joint anchor point, in world coordinates. This returns
   * the point on body 1.
   */
  virtual csVector3 GetBallAnchor1 () = 0;

  /**
   * Get the joint anchor point, in world coordinates. This returns the
   * point on body 2.
   */
  virtual csVector3 GetBallAnchor2 () = 0;

  /**
   * This value will show you how far the joint has come apart.
   */
  virtual csVector3 GetAnchorError () = 0;

   /**
   * Attach the joint to some new bodies. If the joint is already attached, it
   * will be detached from the old bodies first. To attach this joint to only
   * one body, set body1 or body2 to zero - a zero body refers to the static
   * environment. Setting both bodies to zero puts the joint into "limbo", i.e.
   * it will have no effect on the simulation.
   */
  virtual void Attach (iRigidBody *body1, iRigidBody *body2) = 0;

  /// Get an attached body (valid values for body are 0 and 1)
  virtual csRef<iRigidBody> GetAttachedBody (int body) = 0;

  /// Get force that joint applies to body 1
  virtual csVector3 GetFeedbackForce1 () = 0;

  /// Get torque that joint applies to body 1
  virtual csVector3 GetFeedbackTorque1 () = 0;

  /// Get force that joint applies to body 2
  virtual csVector3 GetFeedbackForce2 () = 0;

  /// Get torque that joint applies to body 2
  virtual csVector3 GetFeedbackTorque2 () = 0;
};

#endif // __CS_IVARIA_ODE_H__