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