diff options
Merge branch 'master' of ssh://opensimulator.org/var/git/opensim
Diffstat (limited to 'OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs')
-rwxr-xr-x | OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs | 273 |
1 files changed, 169 insertions, 104 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs b/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs index bc6e4c4..e91bfa8 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs | |||
@@ -1,104 +1,169 @@ | |||
1 | using System; | 1 | using System; |
2 | using System.Collections.Generic; | 2 | using System.Collections.Generic; |
3 | using System.Text; | 3 | using System.Text; |
4 | using OpenMetaverse; | 4 | using OpenMetaverse; |
5 | 5 | ||
6 | namespace OpenSim.Region.Physics.BulletSPlugin | 6 | namespace OpenSim.Region.Physics.BulletSPlugin |
7 | { | 7 | { |
8 | public abstract class BSMotor | 8 | public abstract class BSMotor |
9 | { | 9 | { |
10 | public virtual void Reset() { } | 10 | // Timescales and other things can be turned off by setting them to 'infinite'. |
11 | public virtual void Zero() { } | 11 | public const float Infinite = 10000f; |
12 | } | 12 | public readonly static Vector3 InfiniteVector = new Vector3(BSMotor.Infinite, BSMotor.Infinite, BSMotor.Infinite); |
13 | // Can all the incremental stepping be replaced with motor classes? | 13 | |
14 | public class BSVMotor : BSMotor | 14 | public BSMotor(string useName) |
15 | { | 15 | { |
16 | public Vector3 FrameOfReference { get; set; } | 16 | UseName = useName; |
17 | public Vector3 Offset { get; set; } | 17 | PhysicsScene = null; |
18 | 18 | } | |
19 | public float TimeScale { get; set; } | 19 | public virtual void Reset() { } |
20 | public float TargetValueDecayTimeScale { get; set; } | 20 | public virtual void Zero() { } |
21 | public Vector3 CurrentValueReductionTimescale { get; set; } | 21 | |
22 | public float Efficiency { get; set; } | 22 | public string UseName { get; private set; } |
23 | 23 | // Used only for outputting debug information. Might not be set so check for null. | |
24 | public Vector3 TargetValue { get; private set; } | 24 | public BSScene PhysicsScene { get; set; } |
25 | public Vector3 CurrentValue { get; private set; } | 25 | protected void MDetailLog(string msg, params Object[] parms) |
26 | 26 | { | |
27 | 27 | if (PhysicsScene != null) | |
28 | 28 | { | |
29 | BSVMotor(float timeScale, float decayTimeScale, Vector3 frictionTimeScale, float efficiency) | 29 | if (PhysicsScene.VehicleLoggingEnabled) |
30 | { | 30 | { |
31 | TimeScale = timeScale; | 31 | PhysicsScene.DetailLog(msg, parms); |
32 | TargetValueDecayTimeScale = decayTimeScale; | 32 | } |
33 | CurrentValueReductionTimescale = frictionTimeScale; | 33 | } |
34 | Efficiency = efficiency; | 34 | } |
35 | } | 35 | } |
36 | public void SetCurrent(Vector3 current) | 36 | // Can all the incremental stepping be replaced with motor classes? |
37 | { | 37 | public class BSVMotor : BSMotor |
38 | CurrentValue = current; | 38 | { |
39 | } | 39 | public Vector3 FrameOfReference { get; set; } |
40 | public void SetTarget(Vector3 target) | 40 | public Vector3 Offset { get; set; } |
41 | { | 41 | |
42 | TargetValue = target; | 42 | public float TimeScale { get; set; } |
43 | } | 43 | public float TargetValueDecayTimeScale { get; set; } |
44 | public Vector3 Step(float timeStep) | 44 | public Vector3 FrictionTimescale { get; set; } |
45 | { | 45 | public float Efficiency { get; set; } |
46 | if (CurrentValue.LengthSquared() > 0.001f) | 46 | |
47 | { | 47 | public Vector3 TargetValue { get; private set; } |
48 | // Vector3 origDir = Target; // DEBUG | 48 | public Vector3 CurrentValue { get; private set; } |
49 | // Vector3 origVel = CurrentValue; // DEBUG | 49 | |
50 | 50 | public BSVMotor(string useName) | |
51 | // Add (desiredVelocity - currentAppliedVelocity) / howLongItShouldTakeToComplete | 51 | : base(useName) |
52 | Vector3 addAmount = (TargetValue - CurrentValue)/(TargetValue) * timeStep; | 52 | { |
53 | CurrentValue += addAmount; | 53 | TimeScale = TargetValueDecayTimeScale = BSMotor.Infinite; |
54 | 54 | Efficiency = 1f; | |
55 | float decayFactor = (1.0f / TargetValueDecayTimeScale) * timeStep; | 55 | FrictionTimescale = BSMotor.InfiniteVector; |
56 | TargetValue *= (1f - decayFactor); | 56 | CurrentValue = TargetValue = Vector3.Zero; |
57 | 57 | } | |
58 | Vector3 frictionFactor = (Vector3.One / CurrentValueReductionTimescale) * timeStep; | 58 | public BSVMotor(string useName, float timeScale, float decayTimeScale, Vector3 frictionTimeScale, float efficiency) |
59 | CurrentValue *= (Vector3.One - frictionFactor); | 59 | : this(useName) |
60 | } | 60 | { |
61 | else | 61 | TimeScale = timeScale; |
62 | { | 62 | TargetValueDecayTimeScale = decayTimeScale; |
63 | // if what remains of direction is very small, zero it. | 63 | FrictionTimescale = frictionTimeScale; |
64 | TargetValue = Vector3.Zero; | 64 | Efficiency = efficiency; |
65 | CurrentValue = Vector3.Zero; | 65 | CurrentValue = TargetValue = Vector3.Zero; |
66 | 66 | } | |
67 | // VDetailLog("{0},MoveLinear,zeroed", Prim.LocalID); | 67 | public void SetCurrent(Vector3 current) |
68 | } | 68 | { |
69 | return CurrentValue; | 69 | CurrentValue = current; |
70 | } | 70 | } |
71 | } | 71 | public void SetTarget(Vector3 target) |
72 | 72 | { | |
73 | public class BSFMotor : BSMotor | 73 | TargetValue = target; |
74 | { | 74 | } |
75 | public float TimeScale { get; set; } | 75 | public Vector3 Step(float timeStep) |
76 | public float DecayTimeScale { get; set; } | 76 | { |
77 | public float Friction { get; set; } | 77 | Vector3 returnCurrent = Vector3.Zero; |
78 | public float Efficiency { get; set; } | 78 | if (!CurrentValue.ApproxEquals(TargetValue, 0.01f)) |
79 | 79 | { | |
80 | public float Target { get; private set; } | 80 | Vector3 origTarget = TargetValue; // DEBUG |
81 | public float CurrentValue { get; private set; } | 81 | Vector3 origCurrVal = CurrentValue; // DEBUG |
82 | 82 | ||
83 | BSFMotor(float timeScale, float decayTimescale, float friction, float efficiency) | 83 | // Addition = (desiredVector - currentAppliedVector) / secondsItShouldTakeToComplete |
84 | { | 84 | Vector3 addAmount = (TargetValue - CurrentValue)/TimeScale * timeStep; |
85 | } | 85 | CurrentValue += addAmount; |
86 | public void SetCurrent(float target) | 86 | |
87 | { | 87 | returnCurrent = CurrentValue; |
88 | } | 88 | |
89 | public void SetTarget(float target) | 89 | // The desired value reduces to zero which also reduces the difference with current. |
90 | { | 90 | // If the decay time is infinite, don't decay at all. |
91 | } | 91 | float decayFactor = 0f; |
92 | public float Step(float timeStep) | 92 | if (TargetValueDecayTimeScale != BSMotor.Infinite) |
93 | { | 93 | { |
94 | return 0f; | 94 | decayFactor = (1.0f / TargetValueDecayTimeScale) * timeStep; |
95 | } | 95 | TargetValue *= (1f - decayFactor); |
96 | } | 96 | } |
97 | public class BSPIDMotor : BSMotor | 97 | |
98 | { | 98 | Vector3 frictionFactor = Vector3.Zero; |
99 | // TODO: write and use this one | 99 | if (FrictionTimescale != BSMotor.InfiniteVector) |
100 | BSPIDMotor() | 100 | { |
101 | { | 101 | // frictionFactor = (Vector3.One / FrictionTimescale) * timeStep; |
102 | } | 102 | frictionFactor.X = FrictionTimescale.X == BSMotor.Infinite ? 0f : (1f / FrictionTimescale.X) * timeStep; |
103 | } | 103 | frictionFactor.Y = FrictionTimescale.Y == BSMotor.Infinite ? 0f : (1f / FrictionTimescale.Y) * timeStep; |
104 | } | 104 | frictionFactor.Z = FrictionTimescale.Z == BSMotor.Infinite ? 0f : (1f / FrictionTimescale.Z) * timeStep; |
105 | CurrentValue *= (Vector3.One - frictionFactor); | ||
106 | } | ||
107 | |||
108 | MDetailLog("{0},BSVMotor.Step,nonZero,{1},origCurr={2},origTarget={3},timeStep={4},timeScale={5},addAmnt={6},targetDecay={7},decayFact={8},fricTS={9},frictFact={10}", | ||
109 | BSScene.DetailLogZero, UseName, origCurrVal, origTarget, | ||
110 | timeStep, TimeScale, addAmount, | ||
111 | TargetValueDecayTimeScale, decayFactor, | ||
112 | FrictionTimescale, frictionFactor); | ||
113 | MDetailLog("{0},BSVMotor.Step,nonZero,{1},curr={2},target={3},add={4},decay={5},frict={6},ret={7}", | ||
114 | BSScene.DetailLogZero, UseName, CurrentValue, TargetValue, | ||
115 | addAmount, decayFactor, frictionFactor, returnCurrent); | ||
116 | } | ||
117 | else | ||
118 | { | ||
119 | // Difference between what we have and target is small. Motor is done. | ||
120 | CurrentValue = Vector3.Zero; | ||
121 | TargetValue = Vector3.Zero; | ||
122 | |||
123 | MDetailLog("{0},BSVMotor.Step,zero,{1},curr={2},target={3},ret={4}", | ||
124 | BSScene.DetailLogZero, UseName, TargetValue, CurrentValue, returnCurrent); | ||
125 | |||
126 | } | ||
127 | return returnCurrent; | ||
128 | } | ||
129 | public override string ToString() | ||
130 | { | ||
131 | return String.Format("<{0},curr={1},targ={2},decayTS={3},frictTS={4}>", | ||
132 | UseName, CurrentValue, TargetValue, TargetValueDecayTimeScale, FrictionTimescale); | ||
133 | } | ||
134 | } | ||
135 | |||
136 | public class BSFMotor : BSMotor | ||
137 | { | ||
138 | public float TimeScale { get; set; } | ||
139 | public float DecayTimeScale { get; set; } | ||
140 | public float Friction { get; set; } | ||
141 | public float Efficiency { get; set; } | ||
142 | |||
143 | public float Target { get; private set; } | ||
144 | public float CurrentValue { get; private set; } | ||
145 | |||
146 | public BSFMotor(string useName, float timeScale, float decayTimescale, float friction, float efficiency) | ||
147 | : base(useName) | ||
148 | { | ||
149 | } | ||
150 | public void SetCurrent(float target) | ||
151 | { | ||
152 | } | ||
153 | public void SetTarget(float target) | ||
154 | { | ||
155 | } | ||
156 | public float Step(float timeStep) | ||
157 | { | ||
158 | return 0f; | ||
159 | } | ||
160 | } | ||
161 | public class BSPIDMotor : BSMotor | ||
162 | { | ||
163 | // TODO: write and use this one | ||
164 | public BSPIDMotor(string useName) | ||
165 | : base(useName) | ||
166 | { | ||
167 | } | ||
168 | } | ||
169 | } | ||