aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs')
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs441
1 files changed, 181 insertions, 260 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
index 526dbad..b88ec3c 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
@@ -28,7 +28,7 @@ using System;
28using System.Collections.Generic; 28using System.Collections.Generic;
29using System.Reflection; 29using System.Reflection;
30using log4net; 30using log4net;
31using OpenMetaverse; 31using OMV = OpenMetaverse;
32using OpenSim.Framework; 32using OpenSim.Framework;
33using OpenSim.Region.Physics.Manager; 33using OpenSim.Region.Physics.Manager;
34 34
@@ -39,48 +39,35 @@ public class BSCharacter : BSPhysObject
39 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 39 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
40 private static readonly string LogHeader = "[BULLETS CHAR]"; 40 private static readonly string LogHeader = "[BULLETS CHAR]";
41 41
42 public BSScene Scene { get; private set; }
43 private String _avName;
44 // private bool _stopped; 42 // private bool _stopped;
45 private Vector3 _size; 43 private OMV.Vector3 _size;
46 private Vector3 _scale; 44 private OMV.Vector3 _scale;
47 private PrimitiveBaseShape _pbs; 45 private PrimitiveBaseShape _pbs;
48 private uint _localID = 0;
49 private bool _grabbed; 46 private bool _grabbed;
50 private bool _selected; 47 private bool _selected;
51 private Vector3 _position; 48 private OMV.Vector3 _position;
52 private float _mass; 49 private float _mass;
53 public float _density; 50 private float _avatarDensity;
54 public float _avatarVolume; 51 private float _avatarVolume;
55 private Vector3 _force; 52 private OMV.Vector3 _force;
56 private Vector3 _velocity; 53 private OMV.Vector3 _velocity;
57 private Vector3 _torque; 54 private OMV.Vector3 _torque;
58 private float _collisionScore; 55 private float _collisionScore;
59 private Vector3 _acceleration; 56 private OMV.Vector3 _acceleration;
60 private Quaternion _orientation; 57 private OMV.Quaternion _orientation;
61 private int _physicsActorType; 58 private int _physicsActorType;
62 private bool _isPhysical; 59 private bool _isPhysical;
63 private bool _flying; 60 private bool _flying;
64 private bool _setAlwaysRun; 61 private bool _setAlwaysRun;
65 private bool _throttleUpdates; 62 private bool _throttleUpdates;
66 private bool _isColliding; 63 private bool _isColliding;
67 private long _collidingStep;
68 private bool _collidingGround;
69 private long _collidingGroundStep;
70 private bool _collidingObj; 64 private bool _collidingObj;
71 private bool _floatOnWater; 65 private bool _floatOnWater;
72 private Vector3 _rotationalVelocity; 66 private OMV.Vector3 _rotationalVelocity;
73 private bool _kinematic; 67 private bool _kinematic;
74 private float _buoyancy; 68 private float _buoyancy;
75 69
76 public override BulletBody BSBody { get; set; } 70 private OMV.Vector3 _PIDTarget;
77 public override BulletShape BSShape { get; set; }
78 public override BSLinkset Linkset { get; set; }
79
80 private int _subscribedEventsMs = 0;
81 private int _nextCollisionOkTime = 0;
82
83 private Vector3 _PIDTarget;
84 private bool _usePID; 71 private bool _usePID;
85 private float _PIDTau; 72 private float _PIDTau;
86 private bool _useHoverPID; 73 private bool _useHoverPID;
@@ -88,28 +75,26 @@ public class BSCharacter : BSPhysObject
88 private PIDHoverType _PIDHoverType; 75 private PIDHoverType _PIDHoverType;
89 private float _PIDHoverTao; 76 private float _PIDHoverTao;
90 77
91 public BSCharacter(uint localID, String avName, BSScene parent_scene, Vector3 pos, Vector3 size, bool isFlying) 78 public BSCharacter(uint localID, String avName, BSScene parent_scene, OMV.Vector3 pos, OMV.Vector3 size, bool isFlying)
92 { 79 {
93 _localID = localID; 80 base.BaseInitialize(parent_scene, localID, avName, "BSCharacter");
94 _avName = avName;
95 Scene = parent_scene;
96 _physicsActorType = (int)ActorTypes.Agent; 81 _physicsActorType = (int)ActorTypes.Agent;
97 _position = pos; 82 _position = pos;
98 _size = size; 83 _size = size;
99 _flying = isFlying; 84 _flying = isFlying;
100 _orientation = Quaternion.Identity; 85 _orientation = OMV.Quaternion.Identity;
101 _velocity = Vector3.Zero; 86 _velocity = OMV.Vector3.Zero;
102 _buoyancy = ComputeBuoyancyFromFlying(isFlying); 87 _buoyancy = ComputeBuoyancyFromFlying(isFlying);
88
103 // The dimensions of the avatar capsule are kept in the scale. 89 // The dimensions of the avatar capsule are kept in the scale.
104 // Physics creates a unit capsule which is scaled by the physics engine. 90 // Physics creates a unit capsule which is scaled by the physics engine.
105 _scale = new Vector3(Scene.Params.avatarCapsuleRadius, Scene.Params.avatarCapsuleRadius, size.Z); 91 ComputeAvatarScale(_size);
106 _density = Scene.Params.avatarDensity; 92 _avatarDensity = PhysicsScene.Params.avatarDensity;
107 ComputeAvatarVolumeAndMass(); // set _avatarVolume and _mass based on capsule size, _density and _scale 93 // set _avatarVolume and _mass based on capsule size, _density and _scale
108 94 ComputeAvatarVolumeAndMass();
109 Linkset = new BSLinkset(Scene, this);
110 95
111 ShapeData shapeData = new ShapeData(); 96 ShapeData shapeData = new ShapeData();
112 shapeData.ID = _localID; 97 shapeData.ID = LocalID;
113 shapeData.Type = ShapeData.PhysicsShapeType.SHAPE_AVATAR; 98 shapeData.Type = ShapeData.PhysicsShapeType.SHAPE_AVATAR;
114 shapeData.Position = _position; 99 shapeData.Position = _position;
115 shapeData.Rotation = _orientation; 100 shapeData.Rotation = _orientation;
@@ -118,21 +103,25 @@ public class BSCharacter : BSPhysObject
118 shapeData.Mass = _mass; 103 shapeData.Mass = _mass;
119 shapeData.Buoyancy = _buoyancy; 104 shapeData.Buoyancy = _buoyancy;
120 shapeData.Static = ShapeData.numericFalse; 105 shapeData.Static = ShapeData.numericFalse;
121 shapeData.Friction = Scene.Params.avatarFriction; 106 shapeData.Friction = PhysicsScene.Params.avatarFriction;
122 shapeData.Restitution = Scene.Params.avatarRestitution; 107 shapeData.Restitution = PhysicsScene.Params.avatarRestitution;
123 108
124 // do actual create at taint time 109 // do actual create at taint time
125 Scene.TaintedObject("BSCharacter.create", delegate() 110 PhysicsScene.TaintedObject("BSCharacter.create", delegate()
126 { 111 {
127 DetailLog("{0},BSCharacter.create", _localID); 112 DetailLog("{0},BSCharacter.create,taint", LocalID);
128 BulletSimAPI.CreateObject(Scene.WorldID, shapeData); 113 BulletSimAPI.CreateObject(PhysicsScene.WorldID, shapeData);
129 114
130 // Set the buoyancy for flying. This will be refactored when all the settings happen in C# 115 // Set the buoyancy for flying. This will be refactored when all the settings happen in C#.
131 BulletSimAPI.SetObjectBuoyancy(Scene.WorldID, LocalID, _buoyancy); 116 // If not set at creation, the avatar will stop flying when created after crossing a region boundry.
117 BulletSimAPI.SetObjectBuoyancy(PhysicsScene.WorldID, LocalID, _buoyancy);
132 118
133 BSBody = new BulletBody(LocalID, BulletSimAPI.GetBodyHandle2(Scene.World.Ptr, LocalID)); 119 BSBody = new BulletBody(LocalID, BulletSimAPI.GetBodyHandle2(PhysicsScene.World.ptr, LocalID));
120
121 // This works here because CreateObject has already put the character into the physical world.
122 BulletSimAPI.SetCollisionFilterMask2(BSBody.ptr,
123 (uint)CollisionFilterGroups.AvatarFilter, (uint)CollisionFilterGroups.AvatarMask);
134 }); 124 });
135
136 return; 125 return;
137 } 126 }
138 127
@@ -140,9 +129,9 @@ public class BSCharacter : BSPhysObject
140 public override void Destroy() 129 public override void Destroy()
141 { 130 {
142 DetailLog("{0},BSCharacter.Destroy", LocalID); 131 DetailLog("{0},BSCharacter.Destroy", LocalID);
143 Scene.TaintedObject("BSCharacter.destroy", delegate() 132 PhysicsScene.TaintedObject("BSCharacter.destroy", delegate()
144 { 133 {
145 BulletSimAPI.DestroyObject(Scene.WorldID, _localID); 134 BulletSimAPI.DestroyObject(PhysicsScene.WorldID, LocalID);
146 }); 135 });
147 } 136 }
148 137
@@ -151,70 +140,83 @@ public class BSCharacter : BSPhysObject
151 base.RequestPhysicsterseUpdate(); 140 base.RequestPhysicsterseUpdate();
152 } 141 }
153 // No one calls this method so I don't know what it could possibly mean 142 // No one calls this method so I don't know what it could possibly mean
154 public override bool Stopped { 143 public override bool Stopped {
155 get { return false; } 144 get { return false; }
156 } 145 }
157 public override Vector3 Size { 146 public override OMV.Vector3 Size {
158 get 147 get
159 { 148 {
160 // Avatar capsule size is kept in the scale parameter. 149 // Avatar capsule size is kept in the scale parameter.
161 return new Vector3(_scale.X * 2, _scale.Y * 2, _scale.Z); 150 return new OMV.Vector3(_scale.X * 2, _scale.Y * 2, _scale.Z);
162 } 151 }
163 152
164 set { 153 set {
165 // When an avatar's size is set, only the height is changed 154 // When an avatar's size is set, only the height is changed
166 // and that really only depends on the radius. 155 // and that really only depends on the radius.
167 _size = value; 156 _size = value;
168 _scale.Z = (_size.Z * 1.15f) - (_scale.X + _scale.Y); 157 ComputeAvatarScale(_size);
169 158
170 // TODO: something has to be done with the avatar's vertical position 159 // TODO: something has to be done with the avatar's vertical position
171 160
172 ComputeAvatarVolumeAndMass(); 161 ComputeAvatarVolumeAndMass();
173 162
174 Scene.TaintedObject("BSCharacter.setSize", delegate() 163 PhysicsScene.TaintedObject("BSCharacter.setSize", delegate()
175 { 164 {
176 BulletSimAPI.SetObjectScaleMass(Scene.WorldID, LocalID, _scale, _mass, true); 165 BulletSimAPI.SetObjectScaleMass(PhysicsScene.WorldID, LocalID, _scale, _mass, true);
177 }); 166 });
178 167
179 } 168 }
180 }
181 public override PrimitiveBaseShape Shape {
182 set { _pbs = value;
183 }
184 } 169 }
185 public override uint LocalID { 170 public override PrimitiveBaseShape Shape {
186 set { _localID = value; 171 set { _pbs = value;
187 } 172 }
188 get { return _localID; }
189 } 173 }
190 public override bool Grabbed { 174 public override bool Grabbed {
191 set { _grabbed = value; 175 set { _grabbed = value;
192 } 176 }
193 } 177 }
194 public override bool Selected { 178 public override bool Selected {
195 set { _selected = value; 179 set { _selected = value;
196 } 180 }
197 } 181 }
198 public override void CrossingFailure() { return; } 182 public override void CrossingFailure() { return; }
199 public override void link(PhysicsActor obj) { return; } 183 public override void link(PhysicsActor obj) { return; }
200 public override void delink() { return; } 184 public override void delink() { return; }
201 public override void LockAngularMotion(Vector3 axis) { return; }
202 185
203 public override Vector3 Position { 186 // Set motion values to zero.
187 // Do it to the properties so the values get set in the physics engine.
188 // Push the setting of the values to the viewer.
189 // Called at taint time!
190 public override void ZeroMotion()
191 {
192 _velocity = OMV.Vector3.Zero;
193 _acceleration = OMV.Vector3.Zero;
194 _rotationalVelocity = OMV.Vector3.Zero;
195
196 // Zero some other properties directly into the physics engine
197 BulletSimAPI.SetLinearVelocity2(BSBody.ptr, OMV.Vector3.Zero);
198 BulletSimAPI.SetAngularVelocity2(BSBody.ptr, OMV.Vector3.Zero);
199 BulletSimAPI.SetInterpolationVelocity2(BSBody.ptr, OMV.Vector3.Zero, OMV.Vector3.Zero);
200 BulletSimAPI.ClearForces2(BSBody.ptr);
201 }
202
203 public override void LockAngularMotion(OMV.Vector3 axis) { return; }
204
205 public override OMV.Vector3 Position {
204 get { 206 get {
205 // _position = BulletSimAPI.GetObjectPosition(Scene.WorldID, _localID); 207 // _position = BulletSimAPI.GetObjectPosition(Scene.WorldID, _localID);
206 return _position; 208 return _position;
207 } 209 }
208 set { 210 set {
209 _position = value; 211 _position = value;
210 PositionSanityCheck(); 212 PositionSanityCheck();
211 213
212 Scene.TaintedObject("BSCharacter.setPosition", delegate() 214 PhysicsScene.TaintedObject("BSCharacter.setPosition", delegate()
213 { 215 {
214 DetailLog("{0},BSCharacter.SetPosition,taint,pos={1},orient={2}", LocalID, _position, _orientation); 216 DetailLog("{0},BSCharacter.SetPosition,taint,pos={1},orient={2}", LocalID, _position, _orientation);
215 BulletSimAPI.SetObjectTranslation(Scene.WorldID, _localID, _position, _orientation); 217 BulletSimAPI.SetObjectTranslation(PhysicsScene.WorldID, LocalID, _position, _orientation);
216 }); 218 });
217 } 219 }
218 } 220 }
219 221
220 // Check that the current position is sane and, if not, modify the position to make it so. 222 // Check that the current position is sane and, if not, modify the position to make it so.
@@ -223,9 +225,9 @@ public class BSCharacter : BSPhysObject
223 private bool PositionSanityCheck() 225 private bool PositionSanityCheck()
224 { 226 {
225 bool ret = false; 227 bool ret = false;
226 228
227 // If below the ground, move the avatar up 229 // If below the ground, move the avatar up
228 float terrainHeight = Scene.TerrainManager.GetTerrainHeightAtXYZ(_position); 230 float terrainHeight = PhysicsScene.TerrainManager.GetTerrainHeightAtXYZ(_position);
229 if (Position.Z < terrainHeight) 231 if (Position.Z < terrainHeight)
230 { 232 {
231 DetailLog("{0},BSCharacter.PositionAdjustUnderGround,call,pos={1},terrain={2}", LocalID, _position, terrainHeight); 233 DetailLog("{0},BSCharacter.PositionAdjustUnderGround,call,pos={1},terrain={2}", LocalID, _position, terrainHeight);
@@ -247,200 +249,200 @@ public class BSCharacter : BSPhysObject
247 { 249 {
248 // The new position value must be pushed into the physics engine but we can't 250 // The new position value must be pushed into the physics engine but we can't
249 // just assign to "Position" because of potential call loops. 251 // just assign to "Position" because of potential call loops.
250 Scene.TaintedObject("BSCharacter.PositionSanityCheck", delegate() 252 PhysicsScene.TaintedObject("BSCharacter.PositionSanityCheck", delegate()
251 { 253 {
252 DetailLog("{0},BSCharacter.PositionSanityCheck,taint,pos={1},orient={2}", LocalID, _position, _orientation); 254 DetailLog("{0},BSCharacter.PositionSanityCheck,taint,pos={1},orient={2}", LocalID, _position, _orientation);
253 BulletSimAPI.SetObjectTranslation(Scene.WorldID, _localID, _position, _orientation); 255 BulletSimAPI.SetObjectTranslation(PhysicsScene.WorldID, LocalID, _position, _orientation);
254 }); 256 });
255 ret = true; 257 ret = true;
256 } 258 }
257 return ret; 259 return ret;
258 } 260 }
259 261
260 public override float Mass { 262 public override float Mass {
261 get { 263 get {
262 return _mass; 264 return _mass;
263 } 265 }
264 } 266 }
265 267
266 // used when we only want this prim's mass and not the linkset thing 268 // used when we only want this prim's mass and not the linkset thing
267 public override float MassRaw { get {return _mass; } } 269 public override float MassRaw { get {return _mass; } }
268 270
269 public override Vector3 Force { 271 public override OMV.Vector3 Force {
270 get { return _force; } 272 get { return _force; }
271 set { 273 set {
272 _force = value; 274 _force = value;
273 // m_log.DebugFormat("{0}: Force = {1}", LogHeader, _force); 275 // m_log.DebugFormat("{0}: Force = {1}", LogHeader, _force);
274 Scene.TaintedObject("BSCharacter.SetForce", delegate() 276 PhysicsScene.TaintedObject("BSCharacter.SetForce", delegate()
275 { 277 {
276 DetailLog("{0},BSCharacter.setForce,taint,force={1}", LocalID, _force); 278 DetailLog("{0},BSCharacter.setForce,taint,force={1}", LocalID, _force);
277 BulletSimAPI.SetObjectForce(Scene.WorldID, LocalID, _force); 279 BulletSimAPI.SetObjectForce(PhysicsScene.WorldID, LocalID, _force);
278 }); 280 });
279 } 281 }
280 } 282 }
281 283
282 public override int VehicleType { 284 public override int VehicleType {
283 get { return 0; } 285 get { return 0; }
284 set { return; } 286 set { return; }
285 } 287 }
286 public override void VehicleFloatParam(int param, float value) { } 288 public override void VehicleFloatParam(int param, float value) { }
287 public override void VehicleVectorParam(int param, Vector3 value) {} 289 public override void VehicleVectorParam(int param, OMV.Vector3 value) {}
288 public override void VehicleRotationParam(int param, Quaternion rotation) { } 290 public override void VehicleRotationParam(int param, OMV.Quaternion rotation) { }
289 public override void VehicleFlags(int param, bool remove) { } 291 public override void VehicleFlags(int param, bool remove) { }
290 292
291 // Allows the detection of collisions with inherently non-physical prims. see llVolumeDetect for more 293 // Allows the detection of collisions with inherently non-physical prims. see llVolumeDetect for more
292 public override void SetVolumeDetect(int param) { return; } 294 public override void SetVolumeDetect(int param) { return; }
293 295
294 public override Vector3 GeometricCenter { get { return Vector3.Zero; } } 296 public override OMV.Vector3 GeometricCenter { get { return OMV.Vector3.Zero; } }
295 public override Vector3 CenterOfMass { get { return Vector3.Zero; } } 297 public override OMV.Vector3 CenterOfMass { get { return OMV.Vector3.Zero; } }
296 public override Vector3 Velocity { 298 public override OMV.Vector3 Velocity {
297 get { return _velocity; } 299 get { return _velocity; }
298 set { 300 set {
299 _velocity = value; 301 _velocity = value;
300 // m_log.DebugFormat("{0}: set velocity = {1}", LogHeader, _velocity); 302 // m_log.DebugFormat("{0}: set velocity = {1}", LogHeader, _velocity);
301 Scene.TaintedObject("BSCharacter.setVelocity", delegate() 303 PhysicsScene.TaintedObject("BSCharacter.setVelocity", delegate()
302 { 304 {
303 DetailLog("{0},BSCharacter.setVelocity,taint,vel={1}", LocalID, _velocity); 305 DetailLog("{0},BSCharacter.setVelocity,taint,vel={1}", LocalID, _velocity);
304 BulletSimAPI.SetObjectVelocity(Scene.WorldID, _localID, _velocity); 306 BulletSimAPI.SetObjectVelocity(PhysicsScene.WorldID, LocalID, _velocity);
305 }); 307 });
306 } 308 }
307 } 309 }
308 public override Vector3 Torque { 310 public override OMV.Vector3 Torque {
309 get { return _torque; } 311 get { return _torque; }
310 set { _torque = value; 312 set { _torque = value;
311 } 313 }
312 } 314 }
313 public override float CollisionScore { 315 public override float CollisionScore {
314 get { return _collisionScore; } 316 get { return _collisionScore; }
315 set { _collisionScore = value; 317 set { _collisionScore = value;
316 } 318 }
317 } 319 }
318 public override Vector3 Acceleration { 320 public override OMV.Vector3 Acceleration {
319 get { return _acceleration; } 321 get { return _acceleration; }
320 set { _acceleration = value; } 322 set { _acceleration = value; }
321 } 323 }
322 public override Quaternion Orientation { 324 public override OMV.Quaternion Orientation {
323 get { return _orientation; } 325 get { return _orientation; }
324 set { 326 set {
325 _orientation = value; 327 _orientation = value;
326 // m_log.DebugFormat("{0}: set orientation to {1}", LogHeader, _orientation); 328 // m_log.DebugFormat("{0}: set orientation to {1}", LogHeader, _orientation);
327 Scene.TaintedObject("BSCharacter.setOrientation", delegate() 329 PhysicsScene.TaintedObject("BSCharacter.setOrientation", delegate()
328 { 330 {
329 // _position = BulletSimAPI.GetObjectPosition(Scene.WorldID, _localID); 331 // _position = BulletSimAPI.GetObjectPosition(Scene.WorldID, _localID);
330 BulletSimAPI.SetObjectTranslation(Scene.WorldID, _localID, _position, _orientation); 332 BulletSimAPI.SetObjectTranslation(PhysicsScene.WorldID, LocalID, _position, _orientation);
331 }); 333 });
332 } 334 }
333 } 335 }
334 public override int PhysicsActorType { 336 public override int PhysicsActorType {
335 get { return _physicsActorType; } 337 get { return _physicsActorType; }
336 set { _physicsActorType = value; 338 set { _physicsActorType = value;
337 } 339 }
338 } 340 }
339 public override bool IsPhysical { 341 public override bool IsPhysical {
340 get { return _isPhysical; } 342 get { return _isPhysical; }
341 set { _isPhysical = value; 343 set { _isPhysical = value;
342 } 344 }
343 } 345 }
344 public override bool Flying { 346 public override bool Flying {
345 get { return _flying; } 347 get { return _flying; }
346 set { 348 set {
347 _flying = value; 349 _flying = value;
348 // simulate flying by changing the effect of gravity 350 // simulate flying by changing the effect of gravity
349 this.Buoyancy = ComputeBuoyancyFromFlying(_flying); 351 this.Buoyancy = ComputeBuoyancyFromFlying(_flying);
350 } 352 }
351 } 353 }
352 // Flying is implimented by changing the avatar's buoyancy. 354 // Flying is implimented by changing the avatar's buoyancy.
353 // Would this be done better with a vehicle type? 355 // Would this be done better with a vehicle type?
354 private float ComputeBuoyancyFromFlying(bool ifFlying) { 356 private float ComputeBuoyancyFromFlying(bool ifFlying) {
355 return ifFlying ? 1f : 0f; 357 return ifFlying ? 1f : 0f;
356 } 358 }
357 public override bool 359 public override bool
358 SetAlwaysRun { 360 SetAlwaysRun {
359 get { return _setAlwaysRun; } 361 get { return _setAlwaysRun; }
360 set { _setAlwaysRun = value; } 362 set { _setAlwaysRun = value; }
361 } 363 }
362 public override bool ThrottleUpdates { 364 public override bool ThrottleUpdates {
363 get { return _throttleUpdates; } 365 get { return _throttleUpdates; }
364 set { _throttleUpdates = value; } 366 set { _throttleUpdates = value; }
365 } 367 }
366 public override bool IsColliding { 368 public override bool IsColliding {
367 get { return (_collidingStep == Scene.SimulationStep); } 369 get { return (CollidingStep == PhysicsScene.SimulationStep); }
368 set { _isColliding = value; } 370 set { _isColliding = value; }
369 } 371 }
370 public override bool CollidingGround { 372 public override bool CollidingGround {
371 get { return (_collidingGroundStep == Scene.SimulationStep); } 373 get { return (CollidingGroundStep == PhysicsScene.SimulationStep); }
372 set { _collidingGround = value; } 374 set { CollidingGround = value; }
373 } 375 }
374 public override bool CollidingObj { 376 public override bool CollidingObj {
375 get { return _collidingObj; } 377 get { return _collidingObj; }
376 set { _collidingObj = value; } 378 set { _collidingObj = value; }
377 } 379 }
378 public override bool FloatOnWater { 380 public override bool FloatOnWater {
379 set { _floatOnWater = value; } 381 set { _floatOnWater = value; }
380 } 382 }
381 public override Vector3 RotationalVelocity { 383 public override OMV.Vector3 RotationalVelocity {
382 get { return _rotationalVelocity; } 384 get { return _rotationalVelocity; }
383 set { _rotationalVelocity = value; } 385 set { _rotationalVelocity = value; }
384 } 386 }
385 public override bool Kinematic { 387 public override bool Kinematic {
386 get { return _kinematic; } 388 get { return _kinematic; }
387 set { _kinematic = value; } 389 set { _kinematic = value; }
388 } 390 }
389 // neg=fall quickly, 0=1g, 1=0g, pos=float up 391 // neg=fall quickly, 0=1g, 1=0g, pos=float up
390 public override float Buoyancy { 392 public override float Buoyancy {
391 get { return _buoyancy; } 393 get { return _buoyancy; }
392 set { _buoyancy = value; 394 set { _buoyancy = value;
393 Scene.TaintedObject("BSCharacter.setBuoyancy", delegate() 395 PhysicsScene.TaintedObject("BSCharacter.setBuoyancy", delegate()
394 { 396 {
395 DetailLog("{0},BSCharacter.setBuoyancy,taint,buoy={1}", LocalID, _buoyancy); 397 DetailLog("{0},BSCharacter.setBuoyancy,taint,buoy={1}", LocalID, _buoyancy);
396 BulletSimAPI.SetObjectBuoyancy(Scene.WorldID, LocalID, _buoyancy); 398 BulletSimAPI.SetObjectBuoyancy(PhysicsScene.WorldID, LocalID, _buoyancy);
397 }); 399 });
398 } 400 }
399 } 401 }
400 402
401 // Used for MoveTo 403 // Used for MoveTo
402 public override Vector3 PIDTarget { 404 public override OMV.Vector3 PIDTarget {
403 set { _PIDTarget = value; } 405 set { _PIDTarget = value; }
404 } 406 }
405 public override bool PIDActive { 407 public override bool PIDActive {
406 set { _usePID = value; } 408 set { _usePID = value; }
407 } 409 }
408 public override float PIDTau { 410 public override float PIDTau {
409 set { _PIDTau = value; } 411 set { _PIDTau = value; }
410 } 412 }
411 413
412 // Used for llSetHoverHeight and maybe vehicle height 414 // Used for llSetHoverHeight and maybe vehicle height
413 // Hover Height will override MoveTo target's Z 415 // Hover Height will override MoveTo target's Z
414 public override bool PIDHoverActive { 416 public override bool PIDHoverActive {
415 set { _useHoverPID = value; } 417 set { _useHoverPID = value; }
416 } 418 }
417 public override float PIDHoverHeight { 419 public override float PIDHoverHeight {
418 set { _PIDHoverHeight = value; } 420 set { _PIDHoverHeight = value; }
419 } 421 }
420 public override PIDHoverType PIDHoverType { 422 public override PIDHoverType PIDHoverType {
421 set { _PIDHoverType = value; } 423 set { _PIDHoverType = value; }
422 } 424 }
423 public override float PIDHoverTau { 425 public override float PIDHoverTau {
424 set { _PIDHoverTao = value; } 426 set { _PIDHoverTao = value; }
425 } 427 }
426 428
427 // For RotLookAt 429 // For RotLookAt
428 public override Quaternion APIDTarget { set { return; } } 430 public override OMV.Quaternion APIDTarget { set { return; } }
429 public override bool APIDActive { set { return; } } 431 public override bool APIDActive { set { return; } }
430 public override float APIDStrength { set { return; } } 432 public override float APIDStrength { set { return; } }
431 public override float APIDDamping { set { return; } } 433 public override float APIDDamping { set { return; } }
432 434
433 public override void AddForce(Vector3 force, bool pushforce) { 435 public override void AddForce(OMV.Vector3 force, bool pushforce) {
434 if (force.IsFinite()) 436 if (force.IsFinite())
435 { 437 {
436 _force.X += force.X; 438 _force.X += force.X;
437 _force.Y += force.Y; 439 _force.Y += force.Y;
438 _force.Z += force.Z; 440 _force.Z += force.Z;
439 // m_log.DebugFormat("{0}: AddForce. adding={1}, newForce={2}", LogHeader, force, _force); 441 // m_log.DebugFormat("{0}: AddForce. adding={1}, newForce={2}", LogHeader, force, _force);
440 Scene.TaintedObject("BSCharacter.AddForce", delegate() 442 PhysicsScene.TaintedObject("BSCharacter.AddForce", delegate()
441 { 443 {
442 DetailLog("{0},BSCharacter.setAddForce,taint,addedForce={1}", LocalID, _force); 444 DetailLog("{0},BSCharacter.setAddForce,taint,addedForce={1}", LocalID, _force);
443 BulletSimAPI.SetObjectForce2(BSBody.Ptr, _force); 445 BulletSimAPI.SetObjectForce2(BSBody.ptr, _force);
444 }); 446 });
445 } 447 }
446 else 448 else
@@ -450,42 +452,19 @@ public class BSCharacter : BSPhysObject
450 //m_lastUpdateSent = false; 452 //m_lastUpdateSent = false;
451 } 453 }
452 454
453 public override void AddAngularForce(Vector3 force, bool pushforce) { 455 public override void AddAngularForce(OMV.Vector3 force, bool pushforce) {
454 } 456 }
455 public override void SetMomentum(Vector3 momentum) { 457 public override void SetMomentum(OMV.Vector3 momentum) {
456 } 458 }
457 459
458 // Turn on collision events at a rate no faster than one every the given milliseconds 460 private void ComputeAvatarScale(OMV.Vector3 size)
459 public override void SubscribeEvents(int ms) {
460 _subscribedEventsMs = ms;
461 if (ms > 0)
462 {
463 // make sure first collision happens
464 _nextCollisionOkTime = Util.EnvironmentTickCount() - _subscribedEventsMs;
465
466 Scene.TaintedObject("BSCharacter.SubscribeEvents", delegate()
467 {
468 BulletSimAPI.AddToCollisionFlags2(BSBody.Ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS);
469 });
470 }
471 }
472
473 public override void ZeroMotion()
474 { 461 {
475 return; 462 _scale.X = PhysicsScene.Params.avatarCapsuleRadius;
476 } 463 _scale.Y = PhysicsScene.Params.avatarCapsuleRadius;
477 464
478 // Stop collision events 465 // The 1.15 came from ODE but it seems to cause the avatar to float off the ground
479 public override void UnSubscribeEvents() { 466 // _scale.Z = (_size.Z * 1.15f) - (_scale.X + _scale.Y);
480 _subscribedEventsMs = 0; 467 _scale.Z = (_size.Z) - (_scale.X + _scale.Y);
481 Scene.TaintedObject("BSCharacter.UnSubscribeEvents", delegate()
482 {
483 BulletSimAPI.RemoveFromCollisionFlags2(BSBody.Ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS);
484 });
485 }
486 // Return 'true' if someone has subscribed to events
487 public override bool SubscribedEvents() {
488 return (_subscribedEventsMs > 0);
489 } 468 }
490 469
491 // set _avatarVolume and _mass based on capsule size, _density and _scale 470 // set _avatarVolume and _mass based on capsule size, _density and _scale
@@ -502,7 +481,7 @@ public class BSCharacter : BSPhysObject
502 * Math.Min(_scale.X, _scale.Y) 481 * Math.Min(_scale.X, _scale.Y)
503 * _scale.Y // plus the volume of the capsule end caps 482 * _scale.Y // plus the volume of the capsule end caps
504 ); 483 );
505 _mass = _density * _avatarVolume; 484 _mass = _avatarDensity * _avatarVolume;
506 } 485 }
507 486
508 // The physics engine says that properties have updated. Update same and inform 487 // The physics engine says that properties have updated. Update same and inform
@@ -520,67 +499,9 @@ public class BSCharacter : BSPhysObject
520 // Do some sanity checking for the avatar. Make sure it's above ground and inbounds. 499 // Do some sanity checking for the avatar. Make sure it's above ground and inbounds.
521 PositionSanityCheck2(); 500 PositionSanityCheck2();
522 501
523 float heightHere = Scene.TerrainManager.GetTerrainHeightAtXYZ(_position); // only for debug 502 float heightHere = PhysicsScene.TerrainManager.GetTerrainHeightAtXYZ(_position); // only for debug
524 DetailLog("{0},BSCharacter.UpdateProperties,call,pos={1},orient={2},vel={3},accel={4},rotVel={5},terrain={6}", 503 DetailLog("{0},BSCharacter.UpdateProperties,call,pos={1},orient={2},vel={3},accel={4},rotVel={5},terrain={6}",
525 LocalID, _position, _orientation, _velocity, _acceleration, _rotationalVelocity, heightHere); 504 LocalID, _position, _orientation, _velocity, _acceleration, _rotationalVelocity, heightHere);
526 } 505 }
527
528 // Called by the scene when a collision with this object is reported
529 // The collision, if it should be reported to the character, is placed in a collection
530 // that will later be sent to the simulator when SendCollisions() is called.
531 CollisionEventUpdate collisionCollection = null;
532 public override bool Collide(uint collidingWith, BSPhysObject collidee, Vector3 contactPoint, Vector3 contactNormal, float pentrationDepth)
533 {
534 bool ret = false;
535
536 // The following makes IsColliding() and IsCollidingGround() work
537 _collidingStep = Scene.SimulationStep;
538 if (collidingWith <= Scene.TerrainManager.HighestTerrainID)
539 {
540 _collidingGroundStep = Scene.SimulationStep;
541 }
542 // DetailLog("{0},BSCharacter.Collison,call,with={1}", LocalID, collidingWith);
543
544 // throttle collisions to the rate specified in the subscription
545 if (SubscribedEvents()) {
546 int nowTime = Scene.SimulationNowTime;
547 if (nowTime >= _nextCollisionOkTime) {
548 _nextCollisionOkTime = nowTime + _subscribedEventsMs;
549
550 if (collisionCollection == null)
551 collisionCollection = new CollisionEventUpdate();
552 collisionCollection.AddCollider(collidingWith, new ContactPoint(contactPoint, contactNormal, pentrationDepth));
553 ret = true;
554 }
555 }
556 return ret;
557 }
558
559 public override void SendCollisions()
560 {
561 /*
562 if (collisionCollection != null && collisionCollection.Count > 0)
563 {
564 base.SendCollisionUpdate(collisionCollection);
565 collisionCollection = null;
566 }
567 */
568 // Kludge to make a collision call even if there are no collisions.
569 // This causes the avatar animation to get updated.
570 if (collisionCollection == null)
571 collisionCollection = new CollisionEventUpdate();
572 base.SendCollisionUpdate(collisionCollection);
573 // If there were any collisions in the collection, make sure we don't use the
574 // same instance next time.
575 if (collisionCollection.Count > 0)
576 collisionCollection = null;
577 // End kludge
578 }
579
580 // Invoke the detailed logger and output something if it's enabled.
581 private void DetailLog(string msg, params Object[] args)
582 {
583 Scene.PhysicsLogging.Write(msg, args);
584 }
585} 506}
586} 507}