diff options
Diffstat (limited to 'OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs')
-rw-r--r-- | OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs | 441 |
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; | |||
28 | using System.Collections.Generic; | 28 | using System.Collections.Generic; |
29 | using System.Reflection; | 29 | using System.Reflection; |
30 | using log4net; | 30 | using log4net; |
31 | using OpenMetaverse; | 31 | using OMV = OpenMetaverse; |
32 | using OpenSim.Framework; | 32 | using OpenSim.Framework; |
33 | using OpenSim.Region.Physics.Manager; | 33 | using 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 | } |