aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorJeff Ames2007-12-04 04:59:27 +0000
committerJeff Ames2007-12-04 04:59:27 +0000
commit21c35d5703814c89e4e8d602df19b77a8174b8e0 (patch)
tree695032f9039ef624cb33f601e3709859533ad5be
parent* Split out the ODEPlugin Nested classes. (diff)
downloadopensim-SC-21c35d5703814c89e4e8d602df19b77a8174b8e0.zip
opensim-SC-21c35d5703814c89e4e8d602df19b77a8174b8e0.tar.gz
opensim-SC-21c35d5703814c89e4e8d602df19b77a8174b8e0.tar.bz2
opensim-SC-21c35d5703814c89e4e8d602df19b77a8174b8e0.tar.xz
set svn:eol-style
-rw-r--r--OpenSim/Region/Physics/OdePlugin/ODECharacter.cs954
-rw-r--r--OpenSim/Region/Physics/OdePlugin/ODEPrim.cs1372
2 files changed, 1163 insertions, 1163 deletions
diff --git a/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs b/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs
index cda6af2..888f555 100644
--- a/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs
+++ b/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs
@@ -1,477 +1,477 @@
1using System; 1using System;
2using System.Collections.Generic; 2using System.Collections.Generic;
3using Axiom.Math; 3using Axiom.Math;
4using Ode.NET; 4using Ode.NET;
5using OpenSim.Framework; 5using OpenSim.Framework;
6using OpenSim.Region.Physics.Manager; 6using OpenSim.Region.Physics.Manager;
7 7
8namespace OpenSim.Region.Physics.OdePlugin 8namespace OpenSim.Region.Physics.OdePlugin
9{ 9{
10 public class OdeCharacter : PhysicsActor 10 public class OdeCharacter : PhysicsActor
11 { 11 {
12 private PhysicsVector _position; 12 private PhysicsVector _position;
13 private d.Vector3 _zeroPosition; 13 private d.Vector3 _zeroPosition;
14 private bool _zeroFlag = false; 14 private bool _zeroFlag = false;
15 private bool m_lastUpdateSent = false; 15 private bool m_lastUpdateSent = false;
16 private PhysicsVector _velocity; 16 private PhysicsVector _velocity;
17 private PhysicsVector _target_velocity; 17 private PhysicsVector _target_velocity;
18 private PhysicsVector _acceleration; 18 private PhysicsVector _acceleration;
19 private PhysicsVector m_rotationalVelocity; 19 private PhysicsVector m_rotationalVelocity;
20 private static float PID_D = 3020.0f; 20 private static float PID_D = 3020.0f;
21 private static float PID_P = 7000.0f; 21 private static float PID_P = 7000.0f;
22 private static float POSTURE_SERVO = 10000.0f; 22 private static float POSTURE_SERVO = 10000.0f;
23 public static float CAPSULE_RADIUS = 0.5f; 23 public static float CAPSULE_RADIUS = 0.5f;
24 public float CAPSULE_LENGTH = 0.79f; 24 public float CAPSULE_LENGTH = 0.79f;
25 private bool flying = false; 25 private bool flying = false;
26 private bool m_iscolliding = false; 26 private bool m_iscolliding = false;
27 private bool m_iscollidingGround = false; 27 private bool m_iscollidingGround = false;
28 private bool m_wascolliding = false; 28 private bool m_wascolliding = false;
29 private bool m_wascollidingGround = false; 29 private bool m_wascollidingGround = false;
30 private bool m_alwaysRun = false; 30 private bool m_alwaysRun = false;
31 private bool m_hackSentFall = false; 31 private bool m_hackSentFall = false;
32 private bool m_hackSentFly = false; 32 private bool m_hackSentFly = false;
33 private string m_name = ""; 33 private string m_name = "";
34 34
35 private bool[] m_colliderarr = new bool[11]; 35 private bool[] m_colliderarr = new bool[11];
36 private bool[] m_colliderGroundarr = new bool[11]; 36 private bool[] m_colliderGroundarr = new bool[11];
37 37
38 38
39 private bool jumping = false; 39 private bool jumping = false;
40 //private float gravityAccel; 40 //private float gravityAccel;
41 public IntPtr Body; 41 public IntPtr Body;
42 private OdeScene _parent_scene; 42 private OdeScene _parent_scene;
43 public IntPtr Shell; 43 public IntPtr Shell;
44 public d.Mass ShellMass; 44 public d.Mass ShellMass;
45 public bool collidelock = false; 45 public bool collidelock = false;
46 46
47 public OdeCharacter(String avName, OdeScene parent_scene, PhysicsVector pos) 47 public OdeCharacter(String avName, OdeScene parent_scene, PhysicsVector pos)
48 { 48 {
49 _velocity = new PhysicsVector(); 49 _velocity = new PhysicsVector();
50 _target_velocity = new PhysicsVector(); 50 _target_velocity = new PhysicsVector();
51 _position = pos; 51 _position = pos;
52 _acceleration = new PhysicsVector(); 52 _acceleration = new PhysicsVector();
53 _parent_scene = parent_scene; 53 _parent_scene = parent_scene;
54 54
55 for (int i = 0; i < 11; i++) 55 for (int i = 0; i < 11; i++)
56 { 56 {
57 m_colliderarr[i] = false; 57 m_colliderarr[i] = false;
58 } 58 }
59 59
60 lock (OdeScene.OdeLock) 60 lock (OdeScene.OdeLock)
61 { 61 {
62 62
63 Shell = d.CreateCapsule(parent_scene.space, CAPSULE_RADIUS, CAPSULE_LENGTH); 63 Shell = d.CreateCapsule(parent_scene.space, CAPSULE_RADIUS, CAPSULE_LENGTH);
64 d.MassSetCapsule(out ShellMass, 50.0f, 3, 0.4f, 1.0f); 64 d.MassSetCapsule(out ShellMass, 50.0f, 3, 0.4f, 1.0f);
65 Body = d.BodyCreate(parent_scene.world); 65 Body = d.BodyCreate(parent_scene.world);
66 d.BodySetMass(Body, ref ShellMass); 66 d.BodySetMass(Body, ref ShellMass);
67 d.BodySetPosition(Body, pos.X, pos.Y, pos.Z); 67 d.BodySetPosition(Body, pos.X, pos.Y, pos.Z);
68 d.GeomSetBody(Shell, Body); 68 d.GeomSetBody(Shell, Body);
69 } 69 }
70 m_name = avName; 70 m_name = avName;
71 parent_scene.geom_name_map[Shell] = avName; 71 parent_scene.geom_name_map[Shell] = avName;
72 parent_scene.actor_name_map[Shell] = (PhysicsActor)this; 72 parent_scene.actor_name_map[Shell] = (PhysicsActor)this;
73 } 73 }
74 public override int PhysicsActorType 74 public override int PhysicsActorType
75 { 75 {
76 get { return (int)ActorTypes.Agent; } 76 get { return (int)ActorTypes.Agent; }
77 set { return; } 77 set { return; }
78 } 78 }
79 public override bool SetAlwaysRun 79 public override bool SetAlwaysRun
80 { 80 {
81 get { return m_alwaysRun; } 81 get { return m_alwaysRun; }
82 set { m_alwaysRun = value; } 82 set { m_alwaysRun = value; }
83 } 83 }
84 public override bool IsPhysical 84 public override bool IsPhysical
85 { 85 {
86 get { return false; } 86 get { return false; }
87 set { return; } 87 set { return; }
88 } 88 }
89 public override bool ThrottleUpdates 89 public override bool ThrottleUpdates
90 { 90 {
91 get { return false; } 91 get { return false; }
92 set { return; } 92 set { return; }
93 } 93 }
94 public override bool Flying 94 public override bool Flying
95 { 95 {
96 get { return flying; } 96 get { return flying; }
97 set { flying = value; } 97 set { flying = value; }
98 } 98 }
99 public override bool IsColliding 99 public override bool IsColliding
100 { 100 {
101 101
102 get { return m_iscolliding; } 102 get { return m_iscolliding; }
103 set 103 set
104 { 104 {
105 int i; 105 int i;
106 int truecount = 0; 106 int truecount = 0;
107 int falsecount = 0; 107 int falsecount = 0;
108 108
109 if (m_colliderarr.Length >= 10) 109 if (m_colliderarr.Length >= 10)
110 { 110 {
111 for (i = 0; i < 10; i++) 111 for (i = 0; i < 10; i++)
112 { 112 {
113 m_colliderarr[i] = m_colliderarr[i + 1]; 113 m_colliderarr[i] = m_colliderarr[i + 1];
114 } 114 }
115 } 115 }
116 m_colliderarr[10] = value; 116 m_colliderarr[10] = value;
117 117
118 for (i = 0; i < 11; i++) 118 for (i = 0; i < 11; i++)
119 { 119 {
120 if (m_colliderarr[i]) 120 if (m_colliderarr[i])
121 { 121 {
122 truecount++; 122 truecount++;
123 } 123 }
124 else 124 else
125 { 125 {
126 falsecount++; 126 falsecount++;
127 } 127 }
128 } 128 }
129 129
130 // Equal truecounts and false counts means we're colliding with something. 130 // Equal truecounts and false counts means we're colliding with something.
131 131
132 if (falsecount > 1.2 * truecount) 132 if (falsecount > 1.2 * truecount)
133 { 133 {
134 m_iscolliding = false; 134 m_iscolliding = false;
135 } 135 }
136 else 136 else
137 { 137 {
138 m_iscolliding = true; 138 m_iscolliding = true;
139 } 139 }
140 if (m_wascolliding != m_iscolliding) 140 if (m_wascolliding != m_iscolliding)
141 { 141 {
142 base.SendCollisionUpdate(new CollisionEventUpdate()); 142 base.SendCollisionUpdate(new CollisionEventUpdate());
143 } 143 }
144 m_wascolliding = m_iscolliding; 144 m_wascolliding = m_iscolliding;
145 } 145 }
146 } 146 }
147 public override bool CollidingGround 147 public override bool CollidingGround
148 { 148 {
149 get { return m_iscollidingGround; } 149 get { return m_iscollidingGround; }
150 set 150 set
151 { 151 {
152 int i; 152 int i;
153 int truecount = 0; 153 int truecount = 0;
154 int falsecount = 0; 154 int falsecount = 0;
155 155
156 if (m_colliderGroundarr.Length >= 10) 156 if (m_colliderGroundarr.Length >= 10)
157 { 157 {
158 for (i = 0; i < 10; i++) 158 for (i = 0; i < 10; i++)
159 { 159 {
160 m_colliderGroundarr[i] = m_colliderGroundarr[i + 1]; 160 m_colliderGroundarr[i] = m_colliderGroundarr[i + 1];
161 } 161 }
162 } 162 }
163 m_colliderGroundarr[10] = value; 163 m_colliderGroundarr[10] = value;
164 164
165 for (i = 0; i < 11; i++) 165 for (i = 0; i < 11; i++)
166 { 166 {
167 if (m_colliderGroundarr[i]) 167 if (m_colliderGroundarr[i])
168 { 168 {
169 truecount++; 169 truecount++;
170 } 170 }
171 else 171 else
172 { 172 {
173 falsecount++; 173 falsecount++;
174 } 174 }
175 } 175 }
176 176
177 // Equal truecounts and false counts means we're colliding with something. 177 // Equal truecounts and false counts means we're colliding with something.
178 178
179 if (falsecount > 1.2 * truecount) 179 if (falsecount > 1.2 * truecount)
180 { 180 {
181 m_iscollidingGround = false; 181 m_iscollidingGround = false;
182 } 182 }
183 else 183 else
184 { 184 {
185 m_iscollidingGround = true; 185 m_iscollidingGround = true;
186 } 186 }
187 if (m_wascollidingGround != m_iscollidingGround) 187 if (m_wascollidingGround != m_iscollidingGround)
188 { 188 {
189 //base.SendCollisionUpdate(new CollisionEventUpdate()); 189 //base.SendCollisionUpdate(new CollisionEventUpdate());
190 } 190 }
191 m_wascollidingGround = m_iscollidingGround; 191 m_wascollidingGround = m_iscollidingGround;
192 } 192 }
193 } 193 }
194 public override bool CollidingObj 194 public override bool CollidingObj
195 { 195 {
196 get { return false; } 196 get { return false; }
197 set { return; } 197 set { return; }
198 } 198 }
199 199
200 public override PhysicsVector Position 200 public override PhysicsVector Position
201 { 201 {
202 get { return _position; } 202 get { return _position; }
203 set 203 set
204 { 204 {
205 lock (OdeScene.OdeLock) 205 lock (OdeScene.OdeLock)
206 { 206 {
207 d.BodySetPosition(Body, value.X, value.Y, value.Z); 207 d.BodySetPosition(Body, value.X, value.Y, value.Z);
208 _position = value; 208 _position = value;
209 } 209 }
210 } 210 }
211 } 211 }
212 public override PhysicsVector RotationalVelocity 212 public override PhysicsVector RotationalVelocity
213 { 213 {
214 get { return m_rotationalVelocity; } 214 get { return m_rotationalVelocity; }
215 set { m_rotationalVelocity = value; } 215 set { m_rotationalVelocity = value; }
216 } 216 }
217 public override PhysicsVector Size 217 public override PhysicsVector Size
218 { 218 {
219 get { return new PhysicsVector(CAPSULE_RADIUS * 2, CAPSULE_RADIUS * 2, CAPSULE_LENGTH); } 219 get { return new PhysicsVector(CAPSULE_RADIUS * 2, CAPSULE_RADIUS * 2, CAPSULE_LENGTH); }
220 set 220 set
221 { 221 {
222 lock (OdeScene.OdeLock) 222 lock (OdeScene.OdeLock)
223 { 223 {
224 PhysicsVector SetSize = value; 224 PhysicsVector SetSize = value;
225 float prevCapsule = CAPSULE_LENGTH; 225 float prevCapsule = CAPSULE_LENGTH;
226 float capsuleradius = CAPSULE_RADIUS; 226 float capsuleradius = CAPSULE_RADIUS;
227 capsuleradius = 0.2f; 227 capsuleradius = 0.2f;
228 228
229 CAPSULE_LENGTH = (SetSize.Z - ((SetSize.Z * 0.43f))); // subtract 43% of the size 229 CAPSULE_LENGTH = (SetSize.Z - ((SetSize.Z * 0.43f))); // subtract 43% of the size
230 d.BodyDestroy(Body); 230 d.BodyDestroy(Body);
231 d.GeomDestroy(Shell); 231 d.GeomDestroy(Shell);
232 //OpenSim.Framework.Console.MainLog.Instance.Verbose("PHYSICS", "Set Avatar Height To: " + (CAPSULE_RADIUS + CAPSULE_LENGTH)); 232 //OpenSim.Framework.Console.MainLog.Instance.Verbose("PHYSICS", "Set Avatar Height To: " + (CAPSULE_RADIUS + CAPSULE_LENGTH));
233 Shell = d.CreateCapsule(_parent_scene.space, capsuleradius, CAPSULE_LENGTH); 233 Shell = d.CreateCapsule(_parent_scene.space, capsuleradius, CAPSULE_LENGTH);
234 d.MassSetCapsule(out ShellMass, 50.0f, 3, CAPSULE_RADIUS, CAPSULE_LENGTH); 234 d.MassSetCapsule(out ShellMass, 50.0f, 3, CAPSULE_RADIUS, CAPSULE_LENGTH);
235 Body = d.BodyCreate(_parent_scene.world); 235 Body = d.BodyCreate(_parent_scene.world);
236 d.BodySetMass(Body, ref ShellMass); 236 d.BodySetMass(Body, ref ShellMass);
237 d.BodySetPosition(Body, _position.X, _position.Y, _position.Z + Math.Abs(CAPSULE_LENGTH - prevCapsule)); 237 d.BodySetPosition(Body, _position.X, _position.Y, _position.Z + Math.Abs(CAPSULE_LENGTH - prevCapsule));
238 d.GeomSetBody(Shell, Body); 238 d.GeomSetBody(Shell, Body);
239 } 239 }
240 _parent_scene.geom_name_map[Shell] = m_name; 240 _parent_scene.geom_name_map[Shell] = m_name;
241 _parent_scene.actor_name_map[Shell] = (PhysicsActor)this; 241 _parent_scene.actor_name_map[Shell] = (PhysicsActor)this;
242 } 242 }
243 } 243 }
244 244
245 public override PrimitiveBaseShape Shape 245 public override PrimitiveBaseShape Shape
246 { 246 {
247 set 247 set
248 { 248 {
249 return; 249 return;
250 } 250 }
251 } 251 }
252 252
253 public override PhysicsVector Velocity 253 public override PhysicsVector Velocity
254 { 254 {
255 get { return _velocity; } 255 get { return _velocity; }
256 set { _target_velocity = value; } 256 set { _target_velocity = value; }
257 } 257 }
258 258
259 public override bool Kinematic 259 public override bool Kinematic
260 { 260 {
261 get { return false; } 261 get { return false; }
262 set { } 262 set { }
263 } 263 }
264 264
265 public override Quaternion Orientation 265 public override Quaternion Orientation
266 { 266 {
267 get { return Quaternion.Identity; } 267 get { return Quaternion.Identity; }
268 set { } 268 set { }
269 } 269 }
270 270
271 public override PhysicsVector Acceleration 271 public override PhysicsVector Acceleration
272 { 272 {
273 get { return _acceleration; } 273 get { return _acceleration; }
274 } 274 }
275 275
276 public void SetAcceleration(PhysicsVector accel) 276 public void SetAcceleration(PhysicsVector accel)
277 { 277 {
278 _acceleration = accel; 278 _acceleration = accel;
279 } 279 }
280 280
281 public override void AddForce(PhysicsVector force) 281 public override void AddForce(PhysicsVector force)
282 { 282 {
283 283
284 _target_velocity.X += force.X; 284 _target_velocity.X += force.X;
285 _target_velocity.Y += force.Y; 285 _target_velocity.Y += force.Y;
286 _target_velocity.Z += force.Z; 286 _target_velocity.Z += force.Z;
287 287
288 //m_lastUpdateSent = false; 288 //m_lastUpdateSent = false;
289 } 289 }
290 public void doForce(PhysicsVector force) 290 public void doForce(PhysicsVector force)
291 { 291 {
292 if (!collidelock) 292 if (!collidelock)
293 { 293 {
294 d.BodyAddForce(Body, force.X, force.Y, force.Z); 294 d.BodyAddForce(Body, force.X, force.Y, force.Z);
295 295
296 // ok -- let's stand up straight! 296 // ok -- let's stand up straight!
297 d.Vector3 feet; 297 d.Vector3 feet;
298 d.Vector3 head; 298 d.Vector3 head;
299 d.BodyGetRelPointPos(Body, 0.0f, 0.0f, -1.0f, out feet); 299 d.BodyGetRelPointPos(Body, 0.0f, 0.0f, -1.0f, out feet);
300 d.BodyGetRelPointPos(Body, 0.0f, 0.0f, 1.0f, out head); 300 d.BodyGetRelPointPos(Body, 0.0f, 0.0f, 1.0f, out head);
301 float posture = head.Z - feet.Z; 301 float posture = head.Z - feet.Z;
302 302
303 // restoring force proportional to lack of posture: 303 // restoring force proportional to lack of posture:
304 float servo = (2.5f - posture) * POSTURE_SERVO; 304 float servo = (2.5f - posture) * POSTURE_SERVO;
305 d.BodyAddForceAtRelPos(Body, 0.0f, 0.0f, servo, 0.0f, 0.0f, 1.0f); 305 d.BodyAddForceAtRelPos(Body, 0.0f, 0.0f, servo, 0.0f, 0.0f, 1.0f);
306 d.BodyAddForceAtRelPos(Body, 0.0f, 0.0f, -servo, 0.0f, 0.0f, -1.0f); 306 d.BodyAddForceAtRelPos(Body, 0.0f, 0.0f, -servo, 0.0f, 0.0f, -1.0f);
307 //m_lastUpdateSent = false; 307 //m_lastUpdateSent = false;
308 308
309 } 309 }
310 310
311 } 311 }
312 public override void SetMomentum(PhysicsVector momentum) 312 public override void SetMomentum(PhysicsVector momentum)
313 { 313 {
314 314
315 } 315 }
316 316
317 public void Move(float timeStep) 317 public void Move(float timeStep)
318 { 318 {
319 // no lock; for now it's only called from within Simulate() 319 // no lock; for now it's only called from within Simulate()
320 PhysicsVector vec = new PhysicsVector(); 320 PhysicsVector vec = new PhysicsVector();
321 d.Vector3 vel = d.BodyGetLinearVel(Body); 321 d.Vector3 vel = d.BodyGetLinearVel(Body);
322 float movementdivisor = 1f; 322 float movementdivisor = 1f;
323 323
324 if (!m_alwaysRun) 324 if (!m_alwaysRun)
325 { 325 {
326 movementdivisor = 1.3f; 326 movementdivisor = 1.3f;
327 } 327 }
328 else 328 else
329 { 329 {
330 movementdivisor = 0.8f; 330 movementdivisor = 0.8f;
331 331
332 } 332 }
333 333
334 // if velocity is zero, use position control; otherwise, velocity control 334 // if velocity is zero, use position control; otherwise, velocity control
335 if (_target_velocity.X == 0.0f && _target_velocity.Y == 0.0f && _target_velocity.Z == 0.0f && m_iscolliding) 335 if (_target_velocity.X == 0.0f && _target_velocity.Y == 0.0f && _target_velocity.Z == 0.0f && m_iscolliding)
336 { 336 {
337 // keep track of where we stopped. No more slippin' & slidin' 337 // keep track of where we stopped. No more slippin' & slidin'
338 if (!_zeroFlag) 338 if (!_zeroFlag)
339 { 339 {
340 _zeroFlag = true; 340 _zeroFlag = true;
341 _zeroPosition = d.BodyGetPosition(Body); 341 _zeroPosition = d.BodyGetPosition(Body);
342 } 342 }
343 d.Vector3 pos = d.BodyGetPosition(Body); 343 d.Vector3 pos = d.BodyGetPosition(Body);
344 vec.X = (_target_velocity.X - vel.X) * PID_D + (_zeroPosition.X - pos.X) * PID_P; 344 vec.X = (_target_velocity.X - vel.X) * PID_D + (_zeroPosition.X - pos.X) * PID_P;
345 vec.Y = (_target_velocity.Y - vel.Y) * PID_D + (_zeroPosition.Y - pos.Y) * PID_P; 345 vec.Y = (_target_velocity.Y - vel.Y) * PID_D + (_zeroPosition.Y - pos.Y) * PID_P;
346 if (flying) 346 if (flying)
347 { 347 {
348 vec.Z = (_target_velocity.Z - vel.Z) * PID_D + (_zeroPosition.Z - pos.Z) * PID_P; 348 vec.Z = (_target_velocity.Z - vel.Z) * PID_D + (_zeroPosition.Z - pos.Z) * PID_P;
349 } 349 }
350 } 350 }
351 else 351 else
352 { 352 {
353 353
354 _zeroFlag = false; 354 _zeroFlag = false;
355 if (m_iscolliding || flying) 355 if (m_iscolliding || flying)
356 { 356 {
357 357
358 vec.X = ((_target_velocity.X / movementdivisor) - vel.X) * PID_D; 358 vec.X = ((_target_velocity.X / movementdivisor) - vel.X) * PID_D;
359 vec.Y = ((_target_velocity.Y / movementdivisor) - vel.Y) * PID_D; 359 vec.Y = ((_target_velocity.Y / movementdivisor) - vel.Y) * PID_D;
360 } 360 }
361 if (m_iscolliding && !flying && _target_velocity.Z > 0.0f) 361 if (m_iscolliding && !flying && _target_velocity.Z > 0.0f)
362 { 362 {
363 d.Vector3 pos = d.BodyGetPosition(Body); 363 d.Vector3 pos = d.BodyGetPosition(Body);
364 vec.Z = (_target_velocity.Z - vel.Z) * PID_D + (_zeroPosition.Z - pos.Z) * PID_P; 364 vec.Z = (_target_velocity.Z - vel.Z) * PID_D + (_zeroPosition.Z - pos.Z) * PID_P;
365 if (_target_velocity.X > 0) 365 if (_target_velocity.X > 0)
366 { 366 {
367 vec.X = ((_target_velocity.X - vel.X) / 1.2f) * PID_D; 367 vec.X = ((_target_velocity.X - vel.X) / 1.2f) * PID_D;
368 } 368 }
369 if (_target_velocity.Y > 0) 369 if (_target_velocity.Y > 0)
370 { 370 {
371 vec.Y = ((_target_velocity.Y - vel.Y) / 1.2f) * PID_D; 371 vec.Y = ((_target_velocity.Y - vel.Y) / 1.2f) * PID_D;
372 } 372 }
373 } 373 }
374 else if (!m_iscolliding && !flying) 374 else if (!m_iscolliding && !flying)
375 { 375 {
376 d.Vector3 pos = d.BodyGetPosition(Body); 376 d.Vector3 pos = d.BodyGetPosition(Body);
377 if (_target_velocity.X > 0) 377 if (_target_velocity.X > 0)
378 { 378 {
379 vec.X = ((_target_velocity.X - vel.X) / 1.2f) * PID_D; 379 vec.X = ((_target_velocity.X - vel.X) / 1.2f) * PID_D;
380 } 380 }
381 if (_target_velocity.Y > 0) 381 if (_target_velocity.Y > 0)
382 { 382 {
383 vec.Y = ((_target_velocity.Y - vel.Y) / 1.2f) * PID_D; 383 vec.Y = ((_target_velocity.Y - vel.Y) / 1.2f) * PID_D;
384 } 384 }
385 385
386 } 386 }
387 387
388 388
389 if (flying) 389 if (flying)
390 { 390 {
391 vec.Z = (_target_velocity.Z - vel.Z) * PID_D; 391 vec.Z = (_target_velocity.Z - vel.Z) * PID_D;
392 } 392 }
393 } 393 }
394 if (flying) 394 if (flying)
395 { 395 {
396 vec.Z += 10.0f; 396 vec.Z += 10.0f;
397 } 397 }
398 398
399 399
400 doForce(vec); 400 doForce(vec);
401 } 401 }
402 402
403 public void UpdatePositionAndVelocity() 403 public void UpdatePositionAndVelocity()
404 { 404 {
405 // no lock; called from Simulate() -- if you call this from elsewhere, gotta lock or do Monitor.Enter/Exit! 405 // no lock; called from Simulate() -- if you call this from elsewhere, gotta lock or do Monitor.Enter/Exit!
406 d.Vector3 vec = d.BodyGetPosition(Body); 406 d.Vector3 vec = d.BodyGetPosition(Body);
407 407
408 // kluge to keep things in bounds. ODE lets dead avatars drift away (they should be removed!) 408 // kluge to keep things in bounds. ODE lets dead avatars drift away (they should be removed!)
409 if (vec.X < 0.0f) vec.X = 0.0f; 409 if (vec.X < 0.0f) vec.X = 0.0f;
410 if (vec.Y < 0.0f) vec.Y = 0.0f; 410 if (vec.Y < 0.0f) vec.Y = 0.0f;
411 if (vec.X > 255.95f) vec.X = 255.95f; 411 if (vec.X > 255.95f) vec.X = 255.95f;
412 if (vec.Y > 255.95f) vec.Y = 255.95f; 412 if (vec.Y > 255.95f) vec.Y = 255.95f;
413 413
414 _position.X = vec.X; 414 _position.X = vec.X;
415 _position.Y = vec.Y; 415 _position.Y = vec.Y;
416 _position.Z = vec.Z; 416 _position.Z = vec.Z;
417 417
418 if (_zeroFlag) 418 if (_zeroFlag)
419 { 419 {
420 _velocity.X = 0.0f; 420 _velocity.X = 0.0f;
421 _velocity.Y = 0.0f; 421 _velocity.Y = 0.0f;
422 _velocity.Z = 0.0f; 422 _velocity.Z = 0.0f;
423 if (!m_lastUpdateSent) 423 if (!m_lastUpdateSent)
424 { 424 {
425 m_lastUpdateSent = true; 425 m_lastUpdateSent = true;
426 base.RequestPhysicsterseUpdate(); 426 base.RequestPhysicsterseUpdate();
427 string primScenAvatarIn = _parent_scene.whichspaceamIin(_position); 427 string primScenAvatarIn = _parent_scene.whichspaceamIin(_position);
428 int[] arrayitem = _parent_scene.calculateSpaceArrayItemFromPos(_position); 428 int[] arrayitem = _parent_scene.calculateSpaceArrayItemFromPos(_position);
429 if (primScenAvatarIn == "0") 429 if (primScenAvatarIn == "0")
430 { 430 {
431 OpenSim.Framework.Console.MainLog.Instance.Verbose("Physics", "Avatar " + m_name + " in space with no prim. Arr:':" + arrayitem[0].ToString() + "," + arrayitem[1].ToString()); 431 OpenSim.Framework.Console.MainLog.Instance.Verbose("Physics", "Avatar " + m_name + " in space with no prim. Arr:':" + arrayitem[0].ToString() + "," + arrayitem[1].ToString());
432 } 432 }
433 else 433 else
434 { 434 {
435 OpenSim.Framework.Console.MainLog.Instance.Verbose("Physics", "Avatar " + m_name + " in Prim space':" + primScenAvatarIn + ". Arr:" + arrayitem[0].ToString() + "," + arrayitem[1].ToString()); 435 OpenSim.Framework.Console.MainLog.Instance.Verbose("Physics", "Avatar " + m_name + " in Prim space':" + primScenAvatarIn + ". Arr:" + arrayitem[0].ToString() + "," + arrayitem[1].ToString());
436 } 436 }
437 437
438 } 438 }
439 } 439 }
440 else 440 else
441 { 441 {
442 m_lastUpdateSent = false; 442 m_lastUpdateSent = false;
443 vec = d.BodyGetLinearVel(Body); 443 vec = d.BodyGetLinearVel(Body);
444 _velocity.X = (vec.X); 444 _velocity.X = (vec.X);
445 _velocity.Y = (vec.Y); 445 _velocity.Y = (vec.Y);
446 446
447 _velocity.Z = (vec.Z); 447 _velocity.Z = (vec.Z);
448 if (_velocity.Z < -6 && !m_hackSentFall) 448 if (_velocity.Z < -6 && !m_hackSentFall)
449 { 449 {
450 m_hackSentFall = true; 450 m_hackSentFall = true;
451 base.SendCollisionUpdate(new CollisionEventUpdate()); 451 base.SendCollisionUpdate(new CollisionEventUpdate());
452 } 452 }
453 else if (flying && !m_hackSentFly) 453 else if (flying && !m_hackSentFly)
454 { 454 {
455 //m_hackSentFly = true; 455 //m_hackSentFly = true;
456 //base.SendCollisionUpdate(new CollisionEventUpdate()); 456 //base.SendCollisionUpdate(new CollisionEventUpdate());
457 } 457 }
458 else 458 else
459 { 459 {
460 m_hackSentFly = false; 460 m_hackSentFly = false;
461 m_hackSentFall = false; 461 m_hackSentFall = false;
462 } 462 }
463 } 463 }
464 } 464 }
465 465
466 public void Destroy() 466 public void Destroy()
467 { 467 {
468 lock (OdeScene.OdeLock) 468 lock (OdeScene.OdeLock)
469 { 469 {
470 d.GeomDestroy(Shell); 470 d.GeomDestroy(Shell);
471 _parent_scene.geom_name_map.Remove(Shell); 471 _parent_scene.geom_name_map.Remove(Shell);
472 d.BodyDestroy(Body); 472 d.BodyDestroy(Body);
473 } 473 }
474 } 474 }
475 } 475 }
476 476
477} 477}
diff --git a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs
index f423e82..19de4ca 100644
--- a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs
+++ b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs
@@ -1,686 +1,686 @@
1using System; 1using System;
2using System.Collections.Generic; 2using System.Collections.Generic;
3using Axiom.Math; 3using Axiom.Math;
4using Ode.NET; 4using Ode.NET;
5using OpenSim.Framework; 5using OpenSim.Framework;
6using OpenSim.Region.Physics.Manager; 6using OpenSim.Region.Physics.Manager;
7 7
8namespace OpenSim.Region.Physics.OdePlugin 8namespace OpenSim.Region.Physics.OdePlugin
9{ 9{
10 10
11 public class OdePrim : PhysicsActor 11 public class OdePrim : PhysicsActor
12 { 12 {
13 public PhysicsVector _position; 13 public PhysicsVector _position;
14 private PhysicsVector _velocity; 14 private PhysicsVector _velocity;
15 private PhysicsVector m_lastVelocity = new PhysicsVector(0.0f, 0.0f, 0.0f); 15 private PhysicsVector m_lastVelocity = new PhysicsVector(0.0f, 0.0f, 0.0f);
16 private PhysicsVector m_lastposition = new PhysicsVector(0.0f, 0.0f, 0.0f); 16 private PhysicsVector m_lastposition = new PhysicsVector(0.0f, 0.0f, 0.0f);
17 private PhysicsVector m_rotationalVelocity; 17 private PhysicsVector m_rotationalVelocity;
18 private PhysicsVector _size; 18 private PhysicsVector _size;
19 private PhysicsVector _acceleration; 19 private PhysicsVector _acceleration;
20 private Quaternion _orientation; 20 private Quaternion _orientation;
21 private PhysicsVector m_taintposition; 21 private PhysicsVector m_taintposition;
22 private PhysicsVector m_taintsize; 22 private PhysicsVector m_taintsize;
23 private Quaternion m_taintrot; 23 private Quaternion m_taintrot;
24 private bool m_taintshape = false; 24 private bool m_taintshape = false;
25 private bool m_taintPhysics = false; 25 private bool m_taintPhysics = false;
26 public bool m_taintremove = false; 26 public bool m_taintremove = false;
27 27
28 private IMesh _mesh; 28 private IMesh _mesh;
29 private PrimitiveBaseShape _pbs; 29 private PrimitiveBaseShape _pbs;
30 private OdeScene _parent_scene; 30 private OdeScene _parent_scene;
31 public IntPtr m_targetSpace = (IntPtr)0; 31 public IntPtr m_targetSpace = (IntPtr)0;
32 public IntPtr prim_geom; 32 public IntPtr prim_geom;
33 public IntPtr _triMeshData; 33 public IntPtr _triMeshData;
34 private bool iscolliding = false; 34 private bool iscolliding = false;
35 private bool m_isphysical = false; 35 private bool m_isphysical = false;
36 private bool m_throttleUpdates = false; 36 private bool m_throttleUpdates = false;
37 private int throttleCounter = 0; 37 private int throttleCounter = 0;
38 public bool outofBounds = false; 38 public bool outofBounds = false;
39 39
40 public bool _zeroFlag = false; 40 public bool _zeroFlag = false;
41 private bool m_lastUpdateSent = false; 41 private bool m_lastUpdateSent = false;
42 42
43 public IntPtr Body = (IntPtr)0; 43 public IntPtr Body = (IntPtr)0;
44 private String m_primName; 44 private String m_primName;
45 private PhysicsVector _target_velocity; 45 private PhysicsVector _target_velocity;
46 public d.Mass pMass; 46 public d.Mass pMass;
47 private const float MassMultiplier = 150f; // Ref: Water: 1000kg.. this iset to 500 47 private const float MassMultiplier = 150f; // Ref: Water: 1000kg.. this iset to 500
48 private int debugcounter = 0; 48 private int debugcounter = 0;
49 49
50 50
51 public OdePrim(String primName, OdeScene parent_scene, IntPtr targetSpace, PhysicsVector pos, PhysicsVector size, 51 public OdePrim(String primName, OdeScene parent_scene, IntPtr targetSpace, PhysicsVector pos, PhysicsVector size,
52 Quaternion rotation, IMesh mesh, PrimitiveBaseShape pbs, bool pisPhysical) 52 Quaternion rotation, IMesh mesh, PrimitiveBaseShape pbs, bool pisPhysical)
53 { 53 {
54 54
55 55
56 _velocity = new PhysicsVector(); 56 _velocity = new PhysicsVector();
57 _position = pos; 57 _position = pos;
58 m_taintposition = pos; 58 m_taintposition = pos;
59 if (_position.X > 257) 59 if (_position.X > 257)
60 { 60 {
61 _position.X = 257; 61 _position.X = 257;
62 } 62 }
63 if (_position.X < 0) 63 if (_position.X < 0)
64 { 64 {
65 _position.X = 0; 65 _position.X = 0;
66 } 66 }
67 if (_position.Y > 257) 67 if (_position.Y > 257)
68 { 68 {
69 _position.Y = 257; 69 _position.Y = 257;
70 } 70 }
71 if (_position.Y < 0) 71 if (_position.Y < 0)
72 { 72 {
73 _position.Y = 0; 73 _position.Y = 0;
74 } 74 }
75 75
76 _size = size; 76 _size = size;
77 m_taintsize = _size; 77 m_taintsize = _size;
78 _acceleration = new PhysicsVector(); 78 _acceleration = new PhysicsVector();
79 m_rotationalVelocity = PhysicsVector.Zero; 79 m_rotationalVelocity = PhysicsVector.Zero;
80 _orientation = rotation; 80 _orientation = rotation;
81 m_taintrot = _orientation; 81 m_taintrot = _orientation;
82 _mesh = mesh; 82 _mesh = mesh;
83 _pbs = pbs; 83 _pbs = pbs;
84 84
85 _parent_scene = parent_scene; 85 _parent_scene = parent_scene;
86 m_targetSpace = targetSpace; 86 m_targetSpace = targetSpace;
87 87
88 if (pos.Z < 0) 88 if (pos.Z < 0)
89 m_isphysical = false; 89 m_isphysical = false;
90 else 90 else
91 { 91 {
92 m_isphysical = pisPhysical; 92 m_isphysical = pisPhysical;
93 // If we're physical, we need to be in the master space for now. 93 // If we're physical, we need to be in the master space for now.
94 // linksets *should* be in a space together.. but are not currently 94 // linksets *should* be in a space together.. but are not currently
95 if (m_isphysical) 95 if (m_isphysical)
96 m_targetSpace = _parent_scene.space; 96 m_targetSpace = _parent_scene.space;
97 97
98 } 98 }
99 m_primName = primName; 99 m_primName = primName;
100 100
101 101
102 102
103 lock (OdeScene.OdeLock) 103 lock (OdeScene.OdeLock)
104 { 104 {
105 if (mesh != null) 105 if (mesh != null)
106 { 106 {
107 setMesh(parent_scene, mesh); 107 setMesh(parent_scene, mesh);
108 } 108 }
109 else 109 else
110 { 110 {
111 prim_geom = d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z); 111 prim_geom = d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z);
112 } 112 }
113 113
114 d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z); 114 d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z);
115 d.Quaternion myrot = new d.Quaternion(); 115 d.Quaternion myrot = new d.Quaternion();
116 myrot.W = rotation.w; 116 myrot.W = rotation.w;
117 myrot.X = rotation.x; 117 myrot.X = rotation.x;
118 myrot.Y = rotation.y; 118 myrot.Y = rotation.y;
119 myrot.Z = rotation.z; 119 myrot.Z = rotation.z;
120 d.GeomSetQuaternion(prim_geom, ref myrot); 120 d.GeomSetQuaternion(prim_geom, ref myrot);
121 121
122 122
123 if (m_isphysical && Body == (IntPtr)0) 123 if (m_isphysical && Body == (IntPtr)0)
124 { 124 {
125 enableBody(); 125 enableBody();
126 } 126 }
127 parent_scene.geom_name_map[prim_geom] = primName; 127 parent_scene.geom_name_map[prim_geom] = primName;
128 parent_scene.actor_name_map[prim_geom] = (PhysicsActor)this; 128 parent_scene.actor_name_map[prim_geom] = (PhysicsActor)this;
129 // don't do .add() here; old geoms get recycled with the same hash 129 // don't do .add() here; old geoms get recycled with the same hash
130 } 130 }
131 } 131 }
132 public override int PhysicsActorType 132 public override int PhysicsActorType
133 { 133 {
134 get { return (int)ActorTypes.Prim; } 134 get { return (int)ActorTypes.Prim; }
135 set { return; } 135 set { return; }
136 } 136 }
137 public override bool SetAlwaysRun 137 public override bool SetAlwaysRun
138 { 138 {
139 get { return false; } 139 get { return false; }
140 set { return; } 140 set { return; }
141 } 141 }
142 public void enableBody() 142 public void enableBody()
143 { 143 {
144 // Sets the geom to a body 144 // Sets the geom to a body
145 Body = d.BodyCreate(_parent_scene.world); 145 Body = d.BodyCreate(_parent_scene.world);
146 146
147 setMass(); 147 setMass();
148 d.BodySetPosition(Body, _position.X, _position.Y, _position.Z); 148 d.BodySetPosition(Body, _position.X, _position.Y, _position.Z);
149 d.Quaternion myrot = new d.Quaternion(); 149 d.Quaternion myrot = new d.Quaternion();
150 myrot.W = _orientation.w; 150 myrot.W = _orientation.w;
151 myrot.X = _orientation.x; 151 myrot.X = _orientation.x;
152 myrot.Y = _orientation.y; 152 myrot.Y = _orientation.y;
153 myrot.Z = _orientation.z; 153 myrot.Z = _orientation.z;
154 d.BodySetQuaternion(Body, ref myrot); 154 d.BodySetQuaternion(Body, ref myrot);
155 d.GeomSetBody(prim_geom, Body); 155 d.GeomSetBody(prim_geom, Body);
156 d.BodySetAutoDisableFlag(Body, true); 156 d.BodySetAutoDisableFlag(Body, true);
157 d.BodySetAutoDisableSteps(Body, 20); 157 d.BodySetAutoDisableSteps(Body, 20);
158 158
159 _parent_scene.addActivePrim(this); 159 _parent_scene.addActivePrim(this);
160 } 160 }
161 public void setMass() 161 public void setMass()
162 { 162 {
163 //Sets Mass based on member MassMultiplier. 163 //Sets Mass based on member MassMultiplier.
164 if (Body != (IntPtr)0) 164 if (Body != (IntPtr)0)
165 { 165 {
166 d.MassSetBox(out pMass, (_size.X * _size.Y * _size.Z * MassMultiplier), _size.X, _size.Y, _size.Z); 166 d.MassSetBox(out pMass, (_size.X * _size.Y * _size.Z * MassMultiplier), _size.X, _size.Y, _size.Z);
167 d.BodySetMass(Body, ref pMass); 167 d.BodySetMass(Body, ref pMass);
168 } 168 }
169 } 169 }
170 public void disableBody() 170 public void disableBody()
171 { 171 {
172 //this kills the body so things like 'mesh' can re-create it. 172 //this kills the body so things like 'mesh' can re-create it.
173 if (Body != (IntPtr)0) 173 if (Body != (IntPtr)0)
174 { 174 {
175 _parent_scene.remActivePrim(this); 175 _parent_scene.remActivePrim(this);
176 d.BodyDestroy(Body); 176 d.BodyDestroy(Body);
177 Body = (IntPtr)0; 177 Body = (IntPtr)0;
178 } 178 }
179 } 179 }
180 public void setMesh(OdeScene parent_scene, IMesh mesh) 180 public void setMesh(OdeScene parent_scene, IMesh mesh)
181 { 181 {
182 //Kill Body so that mesh can re-make the geom 182 //Kill Body so that mesh can re-make the geom
183 if (IsPhysical && Body != (IntPtr)0) 183 if (IsPhysical && Body != (IntPtr)0)
184 { 184 {
185 disableBody(); 185 disableBody();
186 } 186 }
187 float[] vertexList = mesh.getVertexListAsFloatLocked(); // Note, that vertextList is pinned in memory 187 float[] vertexList = mesh.getVertexListAsFloatLocked(); // Note, that vertextList is pinned in memory
188 int[] indexList = mesh.getIndexListAsIntLocked(); // Also pinned, needs release after usage 188 int[] indexList = mesh.getIndexListAsIntLocked(); // Also pinned, needs release after usage
189 int VertexCount = vertexList.GetLength(0) / 3; 189 int VertexCount = vertexList.GetLength(0) / 3;
190 int IndexCount = indexList.GetLength(0); 190 int IndexCount = indexList.GetLength(0);
191 191
192 _triMeshData = d.GeomTriMeshDataCreate(); 192 _triMeshData = d.GeomTriMeshDataCreate();
193 193
194 d.GeomTriMeshDataBuildSimple(_triMeshData, vertexList, 3 * sizeof(float), VertexCount, indexList, IndexCount, 194 d.GeomTriMeshDataBuildSimple(_triMeshData, vertexList, 3 * sizeof(float), VertexCount, indexList, IndexCount,
195 3 * sizeof(int)); 195 3 * sizeof(int));
196 d.GeomTriMeshDataPreprocess(_triMeshData); 196 d.GeomTriMeshDataPreprocess(_triMeshData);
197 197
198 prim_geom = d.CreateTriMesh(m_targetSpace, _triMeshData, parent_scene.triCallback, null, null); 198 prim_geom = d.CreateTriMesh(m_targetSpace, _triMeshData, parent_scene.triCallback, null, null);
199 199
200 if (IsPhysical && Body == (IntPtr)0) 200 if (IsPhysical && Body == (IntPtr)0)
201 { 201 {
202 // Recreate the body 202 // Recreate the body
203 enableBody(); 203 enableBody();
204 } 204 }
205 } 205 }
206 public void ProcessTaints(float timestep) 206 public void ProcessTaints(float timestep)
207 { 207 {
208 if (m_taintposition != _position) 208 if (m_taintposition != _position)
209 Move(timestep); 209 Move(timestep);
210 210
211 if (m_taintrot != _orientation) 211 if (m_taintrot != _orientation)
212 rotate(timestep); 212 rotate(timestep);
213 // 213 //
214 214
215 if (m_taintPhysics != m_isphysical) 215 if (m_taintPhysics != m_isphysical)
216 changePhysicsStatus(timestep); 216 changePhysicsStatus(timestep);
217 // 217 //
218 218
219 if (m_taintsize != _size) 219 if (m_taintsize != _size)
220 changesize(timestep); 220 changesize(timestep);
221 // 221 //
222 222
223 if (m_taintshape) 223 if (m_taintshape)
224 changeshape(timestep); 224 changeshape(timestep);
225 // 225 //
226 226
227 } 227 }
228 public void Move(float timestep) 228 public void Move(float timestep)
229 { 229 {
230 if (m_isphysical) 230 if (m_isphysical)
231 { 231 {
232 // This is a fallback.. May no longer be necessary. 232 // This is a fallback.. May no longer be necessary.
233 if (Body == (IntPtr)0) 233 if (Body == (IntPtr)0)
234 enableBody(); 234 enableBody();
235 //Prim auto disable after 20 frames, 235 //Prim auto disable after 20 frames,
236 ///if you move it, re-enable the prim manually. 236 ///if you move it, re-enable the prim manually.
237 d.BodyEnable(Body); 237 d.BodyEnable(Body);
238 d.BodySetPosition(Body, _position.X, _position.Y, _position.Z); 238 d.BodySetPosition(Body, _position.X, _position.Y, _position.Z);
239 } 239 }
240 else 240 else
241 { 241 {
242 string primScenAvatarIn = _parent_scene.whichspaceamIin(_position); 242 string primScenAvatarIn = _parent_scene.whichspaceamIin(_position);
243 int[] arrayitem = _parent_scene.calculateSpaceArrayItemFromPos(_position); 243 int[] arrayitem = _parent_scene.calculateSpaceArrayItemFromPos(_position);
244 if (primScenAvatarIn == "0") 244 if (primScenAvatarIn == "0")
245 { 245 {
246 OpenSim.Framework.Console.MainLog.Instance.Verbose("Physics", "Prim " + m_primName + " in space with no prim: " + primScenAvatarIn + ". Expected to be at: " + m_targetSpace.ToString() + " . Arr:': " + arrayitem[0].ToString() + "," + arrayitem[1].ToString()); 246 OpenSim.Framework.Console.MainLog.Instance.Verbose("Physics", "Prim " + m_primName + " in space with no prim: " + primScenAvatarIn + ". Expected to be at: " + m_targetSpace.ToString() + " . Arr:': " + arrayitem[0].ToString() + "," + arrayitem[1].ToString());
247 } 247 }
248 else 248 else
249 { 249 {
250 OpenSim.Framework.Console.MainLog.Instance.Verbose("Physics", "Prim " + m_primName + " in Prim space with prim: " + primScenAvatarIn + ". Expected to be at: " + m_targetSpace.ToString() + ". Arr:" + arrayitem[0].ToString() + "," + arrayitem[1].ToString()); 250 OpenSim.Framework.Console.MainLog.Instance.Verbose("Physics", "Prim " + m_primName + " in Prim space with prim: " + primScenAvatarIn + ". Expected to be at: " + m_targetSpace.ToString() + ". Arr:" + arrayitem[0].ToString() + "," + arrayitem[1].ToString());
251 } 251 }
252 m_targetSpace = _parent_scene.recalculateSpaceForGeom(prim_geom, _position, m_targetSpace); 252 m_targetSpace = _parent_scene.recalculateSpaceForGeom(prim_geom, _position, m_targetSpace);
253 d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z); 253 d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z);
254 d.SpaceAdd(m_targetSpace, prim_geom); 254 d.SpaceAdd(m_targetSpace, prim_geom);
255 } 255 }
256 256
257 m_taintposition = _position; 257 m_taintposition = _position;
258 } 258 }
259 public void rotate(float timestep) 259 public void rotate(float timestep)
260 { 260 {
261 261
262 d.Quaternion myrot = new d.Quaternion(); 262 d.Quaternion myrot = new d.Quaternion();
263 myrot.W = _orientation.w; 263 myrot.W = _orientation.w;
264 myrot.X = _orientation.x; 264 myrot.X = _orientation.x;
265 myrot.Y = _orientation.y; 265 myrot.Y = _orientation.y;
266 myrot.Z = _orientation.z; 266 myrot.Z = _orientation.z;
267 d.GeomSetQuaternion(prim_geom, ref myrot); 267 d.GeomSetQuaternion(prim_geom, ref myrot);
268 if (m_isphysical && Body != (IntPtr)0) 268 if (m_isphysical && Body != (IntPtr)0)
269 { 269 {
270 d.BodySetQuaternion(Body, ref myrot); 270 d.BodySetQuaternion(Body, ref myrot);
271 } 271 }
272 272
273 m_taintrot = _orientation; 273 m_taintrot = _orientation;
274 } 274 }
275 public void changePhysicsStatus(float timestap) 275 public void changePhysicsStatus(float timestap)
276 { 276 {
277 if (m_isphysical == true) 277 if (m_isphysical == true)
278 { 278 {
279 if (Body == (IntPtr)0) 279 if (Body == (IntPtr)0)
280 { 280 {
281 enableBody(); 281 enableBody();
282 } 282 }
283 283
284 } 284 }
285 else 285 else
286 { 286 {
287 if (Body != (IntPtr)0) 287 if (Body != (IntPtr)0)
288 { 288 {
289 disableBody(); 289 disableBody();
290 } 290 }
291 } 291 }
292 292
293 293
294 m_taintPhysics = m_isphysical; 294 m_taintPhysics = m_isphysical;
295 } 295 }
296 public void changesize(float timestamp) 296 public void changesize(float timestamp)
297 { 297 {
298 string oldname = _parent_scene.geom_name_map[prim_geom]; 298 string oldname = _parent_scene.geom_name_map[prim_geom];
299 299
300 // Cleanup of old prim geometry 300 // Cleanup of old prim geometry
301 if (_mesh != null) 301 if (_mesh != null)
302 { 302 {
303 // Cleanup meshing here 303 // Cleanup meshing here
304 } 304 }
305 //kill body to rebuild 305 //kill body to rebuild
306 if (IsPhysical && Body != (IntPtr)0) 306 if (IsPhysical && Body != (IntPtr)0)
307 { 307 {
308 disableBody(); 308 disableBody();
309 } 309 }
310 if (d.SpaceQuery(m_targetSpace, prim_geom)) 310 if (d.SpaceQuery(m_targetSpace, prim_geom))
311 { 311 {
312 d.SpaceRemove(m_targetSpace, prim_geom); 312 d.SpaceRemove(m_targetSpace, prim_geom);
313 } 313 }
314 d.GeomDestroy(prim_geom); 314 d.GeomDestroy(prim_geom);
315 315
316 // we don't need to do space calculation because the client sends a position update also. 316 // we don't need to do space calculation because the client sends a position update also.
317 317
318 // Construction of new prim 318 // Construction of new prim
319 if (this._parent_scene.needsMeshing(_pbs)) 319 if (this._parent_scene.needsMeshing(_pbs))
320 { 320 {
321 321
322 322
323 // Don't need to re-enable body.. it's done in SetMesh 323 // Don't need to re-enable body.. it's done in SetMesh
324 IMesh mesh = _parent_scene.mesher.CreateMesh(oldname, _pbs, _size); 324 IMesh mesh = _parent_scene.mesher.CreateMesh(oldname, _pbs, _size);
325 // createmesh returns null when it's a shape that isn't a cube. 325 // createmesh returns null when it's a shape that isn't a cube.
326 if (mesh != null) 326 if (mesh != null)
327 { 327 {
328 setMesh(_parent_scene, mesh); 328 setMesh(_parent_scene, mesh);
329 } 329 }
330 else 330 else
331 { 331 {
332 prim_geom = d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z); 332 prim_geom = d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z);
333 d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z); 333 d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z);
334 d.Quaternion myrot = new d.Quaternion(); 334 d.Quaternion myrot = new d.Quaternion();
335 myrot.W = _orientation.w; 335 myrot.W = _orientation.w;
336 myrot.X = _orientation.x; 336 myrot.X = _orientation.x;
337 myrot.Y = _orientation.y; 337 myrot.Y = _orientation.y;
338 myrot.Z = _orientation.z; 338 myrot.Z = _orientation.z;
339 d.GeomSetQuaternion(prim_geom, ref myrot); 339 d.GeomSetQuaternion(prim_geom, ref myrot);
340 340
341 341
342 } 342 }
343 } 343 }
344 else 344 else
345 { 345 {
346 prim_geom = d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z); 346 prim_geom = d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z);
347 d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z); 347 d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z);
348 d.Quaternion myrot = new d.Quaternion(); 348 d.Quaternion myrot = new d.Quaternion();
349 myrot.W = _orientation.w; 349 myrot.W = _orientation.w;
350 myrot.X = _orientation.x; 350 myrot.X = _orientation.x;
351 myrot.Y = _orientation.y; 351 myrot.Y = _orientation.y;
352 myrot.Z = _orientation.z; 352 myrot.Z = _orientation.z;
353 d.GeomSetQuaternion(prim_geom, ref myrot); 353 d.GeomSetQuaternion(prim_geom, ref myrot);
354 354
355 355
356 //d.GeomBoxSetLengths(prim_geom, _size.X, _size.Y, _size.Z); 356 //d.GeomBoxSetLengths(prim_geom, _size.X, _size.Y, _size.Z);
357 if (IsPhysical && Body == (IntPtr)0) 357 if (IsPhysical && Body == (IntPtr)0)
358 { 358 {
359 // Re creates body on size. 359 // Re creates body on size.
360 // EnableBody also does setMass() 360 // EnableBody also does setMass()
361 enableBody(); 361 enableBody();
362 d.BodyEnable(Body); 362 d.BodyEnable(Body);
363 } 363 }
364 364
365 } 365 }
366 366
367 367
368 _parent_scene.geom_name_map[prim_geom] = oldname; 368 _parent_scene.geom_name_map[prim_geom] = oldname;
369 369
370 370
371 m_taintsize = _size; 371 m_taintsize = _size;
372 } 372 }
373 public void changeshape(float timestamp) 373 public void changeshape(float timestamp)
374 { 374 {
375 string oldname = _parent_scene.geom_name_map[prim_geom]; 375 string oldname = _parent_scene.geom_name_map[prim_geom];
376 376
377 // Cleanup of old prim geometry and Bodies 377 // Cleanup of old prim geometry and Bodies
378 if (IsPhysical && Body != (IntPtr)0) 378 if (IsPhysical && Body != (IntPtr)0)
379 { 379 {
380 disableBody(); 380 disableBody();
381 } 381 }
382 d.GeomDestroy(prim_geom); 382 d.GeomDestroy(prim_geom);
383 if (_mesh != null) 383 if (_mesh != null)
384 { 384 {
385 385
386 d.GeomBoxSetLengths(prim_geom, _size.X, _size.Y, _size.Z); 386 d.GeomBoxSetLengths(prim_geom, _size.X, _size.Y, _size.Z);
387 387
388 } 388 }
389 389
390 // Construction of new prim 390 // Construction of new prim
391 if (this._parent_scene.needsMeshing(_pbs)) 391 if (this._parent_scene.needsMeshing(_pbs))
392 { 392 {
393 IMesh mesh = _parent_scene.mesher.CreateMesh(oldname, _pbs, _size); 393 IMesh mesh = _parent_scene.mesher.CreateMesh(oldname, _pbs, _size);
394 if (mesh != null) 394 if (mesh != null)
395 { 395 {
396 setMesh(_parent_scene, mesh); 396 setMesh(_parent_scene, mesh);
397 } 397 }
398 else 398 else
399 { 399 {
400 prim_geom = d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z); 400 prim_geom = d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z);
401 } 401 }
402 } 402 }
403 else 403 else
404 { 404 {
405 prim_geom = d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z); 405 prim_geom = d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z);
406 } 406 }
407 if (IsPhysical && Body == (IntPtr)0) 407 if (IsPhysical && Body == (IntPtr)0)
408 { 408 {
409 //re-create new body 409 //re-create new body
410 enableBody(); 410 enableBody();
411 } 411 }
412 else 412 else
413 { 413 {
414 d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z); 414 d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z);
415 d.Quaternion myrot = new d.Quaternion(); 415 d.Quaternion myrot = new d.Quaternion();
416 myrot.W = _orientation.w; 416 myrot.W = _orientation.w;
417 myrot.X = _orientation.x; 417 myrot.X = _orientation.x;
418 myrot.Y = _orientation.y; 418 myrot.Y = _orientation.y;
419 myrot.Z = _orientation.z; 419 myrot.Z = _orientation.z;
420 d.GeomSetQuaternion(prim_geom, ref myrot); 420 d.GeomSetQuaternion(prim_geom, ref myrot);
421 } 421 }
422 _parent_scene.geom_name_map[prim_geom] = oldname; 422 _parent_scene.geom_name_map[prim_geom] = oldname;
423 423
424 424
425 425
426 426
427 m_taintshape = false; 427 m_taintshape = false;
428 } 428 }
429 public override bool IsPhysical 429 public override bool IsPhysical
430 { 430 {
431 get { return m_isphysical; } 431 get { return m_isphysical; }
432 set { m_isphysical = value; } 432 set { m_isphysical = value; }
433 } 433 }
434 public void setPrimForRemoval() 434 public void setPrimForRemoval()
435 { 435 {
436 m_taintremove = true; 436 m_taintremove = true;
437 } 437 }
438 438
439 public override bool Flying 439 public override bool Flying
440 { 440 {
441 get 441 get
442 { 442 {
443 return false; //no flying prims for you 443 return false; //no flying prims for you
444 } 444 }
445 set { } 445 set { }
446 } 446 }
447 447
448 public override bool IsColliding 448 public override bool IsColliding
449 { 449 {
450 get { return iscolliding; } 450 get { return iscolliding; }
451 set { iscolliding = value; } 451 set { iscolliding = value; }
452 } 452 }
453 public override bool CollidingGround 453 public override bool CollidingGround
454 { 454 {
455 get { return false; } 455 get { return false; }
456 set { return; } 456 set { return; }
457 } 457 }
458 public override bool CollidingObj 458 public override bool CollidingObj
459 { 459 {
460 get { return false; } 460 get { return false; }
461 set { return; } 461 set { return; }
462 } 462 }
463 public override bool ThrottleUpdates 463 public override bool ThrottleUpdates
464 { 464 {
465 get { return m_throttleUpdates; } 465 get { return m_throttleUpdates; }
466 set { m_throttleUpdates = value; } 466 set { m_throttleUpdates = value; }
467 } 467 }
468 468
469 public override PhysicsVector Position 469 public override PhysicsVector Position
470 { 470 {
471 get { return _position; } 471 get { return _position; }
472 472
473 473
474 set 474 set
475 { 475 {
476 _position = value; 476 _position = value;
477 477
478 } 478 }
479 } 479 }
480 480
481 public override PhysicsVector Size 481 public override PhysicsVector Size
482 { 482 {
483 get { return _size; } 483 get { return _size; }
484 set 484 set
485 { 485 {
486 _size = value; 486 _size = value;
487 487
488 } 488 }
489 } 489 }
490 490
491 public override PrimitiveBaseShape Shape 491 public override PrimitiveBaseShape Shape
492 { 492 {
493 set 493 set
494 { 494 {
495 _pbs = value; 495 _pbs = value;
496 496
497 } 497 }
498 } 498 }
499 499
500 public override PhysicsVector Velocity 500 public override PhysicsVector Velocity
501 { 501 {
502 get 502 get
503 { 503 {
504 // Averate previous velocity with the new one so 504 // Averate previous velocity with the new one so
505 // client object interpolation works a 'little' better 505 // client object interpolation works a 'little' better
506 PhysicsVector returnVelocity = new PhysicsVector(); 506 PhysicsVector returnVelocity = new PhysicsVector();
507 returnVelocity.X = (m_lastVelocity.X + _velocity.X) / 2; 507 returnVelocity.X = (m_lastVelocity.X + _velocity.X) / 2;
508 returnVelocity.Y = (m_lastVelocity.Y + _velocity.Y) / 2; 508 returnVelocity.Y = (m_lastVelocity.Y + _velocity.Y) / 2;
509 returnVelocity.Z = (m_lastVelocity.Z + _velocity.Z) / 2; 509 returnVelocity.Z = (m_lastVelocity.Z + _velocity.Z) / 2;
510 return returnVelocity; 510 return returnVelocity;
511 } 511 }
512 set { _velocity = value; } 512 set { _velocity = value; }
513 } 513 }
514 514
515 public override bool Kinematic 515 public override bool Kinematic
516 { 516 {
517 get { return false; } 517 get { return false; }
518 set { } 518 set { }
519 } 519 }
520 520
521 public override Quaternion Orientation 521 public override Quaternion Orientation
522 { 522 {
523 get { return _orientation; } 523 get { return _orientation; }
524 set 524 set
525 { 525 {
526 _orientation = value; 526 _orientation = value;
527 527
528 } 528 }
529 } 529 }
530 530
531 public override PhysicsVector Acceleration 531 public override PhysicsVector Acceleration
532 { 532 {
533 get { return _acceleration; } 533 get { return _acceleration; }
534 } 534 }
535 535
536 536
537 public void SetAcceleration(PhysicsVector accel) 537 public void SetAcceleration(PhysicsVector accel)
538 { 538 {
539 _acceleration = accel; 539 _acceleration = accel;
540 } 540 }
541 541
542 public override void AddForce(PhysicsVector force) 542 public override void AddForce(PhysicsVector force)
543 { 543 {
544 } 544 }
545 545
546 public override PhysicsVector RotationalVelocity 546 public override PhysicsVector RotationalVelocity
547 { 547 {
548 get { return m_rotationalVelocity; } 548 get { return m_rotationalVelocity; }
549 set { m_rotationalVelocity = value; } 549 set { m_rotationalVelocity = value; }
550 } 550 }
551 551
552 public void UpdatePositionAndVelocity() 552 public void UpdatePositionAndVelocity()
553 { 553 {
554 // no lock; called from Simulate() -- if you call this from elsewhere, gotta lock or do Monitor.Enter/Exit! 554 // no lock; called from Simulate() -- if you call this from elsewhere, gotta lock or do Monitor.Enter/Exit!
555 555
556 if (Body != (IntPtr)0) 556 if (Body != (IntPtr)0)
557 { 557 {
558 d.Vector3 vec = d.BodyGetPosition(Body); 558 d.Vector3 vec = d.BodyGetPosition(Body);
559 d.Quaternion ori = d.BodyGetQuaternion(Body); 559 d.Quaternion ori = d.BodyGetQuaternion(Body);
560 d.Vector3 vel = d.BodyGetLinearVel(Body); 560 d.Vector3 vel = d.BodyGetLinearVel(Body);
561 d.Vector3 rotvel = d.BodyGetAngularVel(Body); 561 d.Vector3 rotvel = d.BodyGetAngularVel(Body);
562 562
563 PhysicsVector l_position = new PhysicsVector(); 563 PhysicsVector l_position = new PhysicsVector();
564 // kluge to keep things in bounds. ODE lets dead avatars drift away (they should be removed!) 564 // kluge to keep things in bounds. ODE lets dead avatars drift away (they should be removed!)
565 if (vec.X < 0.0f) vec.X = 0.0f; 565 if (vec.X < 0.0f) vec.X = 0.0f;
566 if (vec.Y < 0.0f) vec.Y = 0.0f; 566 if (vec.Y < 0.0f) vec.Y = 0.0f;
567 if (vec.X > 255.95f) vec.X = 255.95f; 567 if (vec.X > 255.95f) vec.X = 255.95f;
568 if (vec.Y > 255.95f) vec.Y = 255.95f; 568 if (vec.Y > 255.95f) vec.Y = 255.95f;
569 m_lastposition = _position; 569 m_lastposition = _position;
570 570
571 l_position.X = vec.X; 571 l_position.X = vec.X;
572 l_position.Y = vec.Y; 572 l_position.Y = vec.Y;
573 l_position.Z = vec.Z; 573 l_position.Z = vec.Z;
574 if (l_position.Z < 0) 574 if (l_position.Z < 0)
575 { 575 {
576 // This is so prim that get lost underground don't fall forever and suck up 576 // This is so prim that get lost underground don't fall forever and suck up
577 // 577 //
578 // Sim resources and memory. 578 // Sim resources and memory.
579 // Disables the prim's movement physics.... 579 // Disables the prim's movement physics....
580 // It's a hack and will generate a console message if it fails. 580 // It's a hack and will generate a console message if it fails.
581 581
582 582
583 583
584 584
585 //IsPhysical = false; 585 //IsPhysical = false;
586 base.RaiseOutOfBounds(_position); 586 base.RaiseOutOfBounds(_position);
587 _velocity.X = 0; 587 _velocity.X = 0;
588 _velocity.Y = 0; 588 _velocity.Y = 0;
589 _velocity.Z = 0; 589 _velocity.Z = 0;
590 m_rotationalVelocity.X = 0; 590 m_rotationalVelocity.X = 0;
591 m_rotationalVelocity.Y = 0; 591 m_rotationalVelocity.Y = 0;
592 m_rotationalVelocity.Z = 0; 592 m_rotationalVelocity.Z = 0;
593 base.RequestPhysicsterseUpdate(); 593 base.RequestPhysicsterseUpdate();
594 m_throttleUpdates = false; 594 m_throttleUpdates = false;
595 throttleCounter = 0; 595 throttleCounter = 0;
596 _zeroFlag = true; 596 _zeroFlag = true;
597 //outofBounds = true; 597 //outofBounds = true;
598 } 598 }
599 599
600 if ((Math.Abs(m_lastposition.X - l_position.X) < 0.02) 600 if ((Math.Abs(m_lastposition.X - l_position.X) < 0.02)
601 && (Math.Abs(m_lastposition.Y - l_position.Y) < 0.02) 601 && (Math.Abs(m_lastposition.Y - l_position.Y) < 0.02)
602 && (Math.Abs(m_lastposition.Z - l_position.Z) < 0.02)) 602 && (Math.Abs(m_lastposition.Z - l_position.Z) < 0.02))
603 { 603 {
604 604
605 _zeroFlag = true; 605 _zeroFlag = true;
606 } 606 }
607 else 607 else
608 { 608 {
609 //System.Console.WriteLine(Math.Abs(m_lastposition.X - l_position.X).ToString()); 609 //System.Console.WriteLine(Math.Abs(m_lastposition.X - l_position.X).ToString());
610 _zeroFlag = false; 610 _zeroFlag = false;
611 } 611 }
612 612
613 613
614 614
615 if (_zeroFlag) 615 if (_zeroFlag)
616 { 616 {
617 // Supposedly this is supposed to tell SceneObjectGroup that 617 // Supposedly this is supposed to tell SceneObjectGroup that
618 // no more updates need to be sent.. 618 // no more updates need to be sent..
619 // but it seems broken. 619 // but it seems broken.
620 _velocity.X = 0.0f; 620 _velocity.X = 0.0f;
621 _velocity.Y = 0.0f; 621 _velocity.Y = 0.0f;
622 _velocity.Z = 0.0f; 622 _velocity.Z = 0.0f;
623 //_orientation.w = 0f; 623 //_orientation.w = 0f;
624 //_orientation.x = 0f; 624 //_orientation.x = 0f;
625 //_orientation.y = 0f; 625 //_orientation.y = 0f;
626 //_orientation.z = 0f; 626 //_orientation.z = 0f;
627 m_rotationalVelocity.X = 0; 627 m_rotationalVelocity.X = 0;
628 m_rotationalVelocity.Y = 0; 628 m_rotationalVelocity.Y = 0;
629 m_rotationalVelocity.Z = 0; 629 m_rotationalVelocity.Z = 0;
630 if (!m_lastUpdateSent) 630 if (!m_lastUpdateSent)
631 { 631 {
632 m_throttleUpdates = false; 632 m_throttleUpdates = false;
633 throttleCounter = 0; 633 throttleCounter = 0;
634 base.RequestPhysicsterseUpdate(); 634 base.RequestPhysicsterseUpdate();
635 m_lastUpdateSent = true; 635 m_lastUpdateSent = true;
636 } 636 }
637 637
638 } 638 }
639 else 639 else
640 { 640 {
641 m_lastVelocity = _velocity; 641 m_lastVelocity = _velocity;
642 642
643 _position = l_position; 643 _position = l_position;
644 644
645 _velocity.X = vel.X; 645 _velocity.X = vel.X;
646 _velocity.Y = vel.Y; 646 _velocity.Y = vel.Y;
647 _velocity.Z = vel.Z; 647 _velocity.Z = vel.Z;
648 648
649 m_rotationalVelocity.X = rotvel.X; 649 m_rotationalVelocity.X = rotvel.X;
650 m_rotationalVelocity.Y = rotvel.Y; 650 m_rotationalVelocity.Y = rotvel.Y;
651 m_rotationalVelocity.Z = rotvel.Z; 651 m_rotationalVelocity.Z = rotvel.Z;
652 //System.Console.WriteLine("ODE: " + m_rotationalVelocity.ToString()); 652 //System.Console.WriteLine("ODE: " + m_rotationalVelocity.ToString());
653 _orientation.w = ori.W; 653 _orientation.w = ori.W;
654 _orientation.x = ori.X; 654 _orientation.x = ori.X;
655 _orientation.y = ori.Y; 655 _orientation.y = ori.Y;
656 _orientation.z = ori.Z; 656 _orientation.z = ori.Z;
657 m_lastUpdateSent = false; 657 m_lastUpdateSent = false;
658 if (!m_throttleUpdates || throttleCounter > 15) 658 if (!m_throttleUpdates || throttleCounter > 15)
659 { 659 {
660 base.RequestPhysicsterseUpdate(); 660 base.RequestPhysicsterseUpdate();
661 } 661 }
662 else 662 else
663 { 663 {
664 throttleCounter++; 664 throttleCounter++;
665 } 665 }
666 } 666 }
667 m_lastposition = l_position; 667 m_lastposition = l_position;
668 } 668 }
669 else 669 else
670 { 670 {
671 // Not a body.. so Make sure the client isn't interpolating 671 // Not a body.. so Make sure the client isn't interpolating
672 _velocity.X = 0; 672 _velocity.X = 0;
673 _velocity.Y = 0; 673 _velocity.Y = 0;
674 _velocity.Z = 0; 674 _velocity.Z = 0;
675 m_rotationalVelocity.X = 0; 675 m_rotationalVelocity.X = 0;
676 m_rotationalVelocity.Y = 0; 676 m_rotationalVelocity.Y = 0;
677 m_rotationalVelocity.Z = 0; 677 m_rotationalVelocity.Z = 0;
678 _zeroFlag = true; 678 _zeroFlag = true;
679 } 679 }
680 680
681 } 681 }
682 public override void SetMomentum(PhysicsVector momentum) 682 public override void SetMomentum(PhysicsVector momentum)
683 { 683 {
684 } 684 }
685 } 685 }
686} 686}