diff options
Diffstat (limited to 'OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs')
-rw-r--r-- | OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs | 385 |
1 files changed, 145 insertions, 240 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs index 103d8fc..542f732 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs | |||
@@ -45,11 +45,7 @@ public sealed class BSCharacter : BSPhysObject | |||
45 | private bool _selected; | 45 | private bool _selected; |
46 | private OMV.Vector3 _position; | 46 | private OMV.Vector3 _position; |
47 | private float _mass; | 47 | private float _mass; |
48 | private float _avatarDensity; | ||
49 | private float _avatarVolume; | 48 | private float _avatarVolume; |
50 | private OMV.Vector3 _force; | ||
51 | private OMV.Vector3 _velocity; | ||
52 | private OMV.Vector3 _torque; | ||
53 | private float _collisionScore; | 49 | private float _collisionScore; |
54 | private OMV.Vector3 _acceleration; | 50 | private OMV.Vector3 _acceleration; |
55 | private OMV.Quaternion _orientation; | 51 | private OMV.Quaternion _orientation; |
@@ -58,25 +54,17 @@ public sealed class BSCharacter : BSPhysObject | |||
58 | private bool _flying; | 54 | private bool _flying; |
59 | private bool _setAlwaysRun; | 55 | private bool _setAlwaysRun; |
60 | private bool _throttleUpdates; | 56 | private bool _throttleUpdates; |
61 | private bool _isColliding; | ||
62 | private bool _collidingObj; | ||
63 | private bool _floatOnWater; | 57 | private bool _floatOnWater; |
64 | private OMV.Vector3 _rotationalVelocity; | 58 | private OMV.Vector3 _rotationalVelocity; |
65 | private bool _kinematic; | 59 | private bool _kinematic; |
66 | private float _buoyancy; | 60 | private float _buoyancy; |
67 | 61 | ||
68 | // The friction and velocity of the avatar is modified depending on whether walking or not. | 62 | private BSActorAvatarMove m_moveActor; |
69 | private float _currentFriction; // the friction currently being used (changed by setVelocity). | 63 | private const string AvatarMoveActorName = "BSCharacter.AvatarMove"; |
70 | |||
71 | private BSVMotor _velocityMotor; | ||
72 | 64 | ||
73 | private OMV.Vector3 _PIDTarget; | 65 | private OMV.Vector3 _PIDTarget; |
74 | private bool _usePID; | 66 | private bool _usePID; |
75 | private float _PIDTau; | 67 | private float _PIDTau; |
76 | private bool _useHoverPID; | ||
77 | private float _PIDHoverHeight; | ||
78 | private PIDHoverType _PIDHoverType; | ||
79 | private float _PIDHoverTao; | ||
80 | 68 | ||
81 | public BSCharacter(uint localID, String avName, BSScene parent_scene, OMV.Vector3 pos, OMV.Vector3 size, bool isFlying) | 69 | public BSCharacter(uint localID, String avName, BSScene parent_scene, OMV.Vector3 pos, OMV.Vector3 size, bool isFlying) |
82 | : base(parent_scene, localID, avName, "BSCharacter") | 70 | : base(parent_scene, localID, avName, "BSCharacter") |
@@ -86,10 +74,10 @@ public sealed class BSCharacter : BSPhysObject | |||
86 | 74 | ||
87 | _flying = isFlying; | 75 | _flying = isFlying; |
88 | _orientation = OMV.Quaternion.Identity; | 76 | _orientation = OMV.Quaternion.Identity; |
89 | _velocity = OMV.Vector3.Zero; | 77 | RawVelocity = OMV.Vector3.Zero; |
90 | _buoyancy = ComputeBuoyancyFromFlying(isFlying); | 78 | _buoyancy = ComputeBuoyancyFromFlying(isFlying); |
91 | _currentFriction = BSParam.AvatarStandingFriction; | 79 | Friction = BSParam.AvatarStandingFriction; |
92 | _avatarDensity = BSParam.AvatarDensity; | 80 | Density = BSParam.AvatarDensity / BSParam.DensityScaleFactor; |
93 | 81 | ||
94 | // Old versions of ScenePresence passed only the height. If width and/or depth are zero, | 82 | // Old versions of ScenePresence passed only the height. If width and/or depth are zero, |
95 | // replace with the default values. | 83 | // replace with the default values. |
@@ -103,17 +91,22 @@ public sealed class BSCharacter : BSPhysObject | |||
103 | // set _avatarVolume and _mass based on capsule size, _density and Scale | 91 | // set _avatarVolume and _mass based on capsule size, _density and Scale |
104 | ComputeAvatarVolumeAndMass(); | 92 | ComputeAvatarVolumeAndMass(); |
105 | 93 | ||
106 | SetupMovementMotor(); | 94 | // The avatar's movement is controlled by this motor that speeds up and slows down |
95 | // the avatar seeking to reach the motor's target speed. | ||
96 | // This motor runs as a prestep action for the avatar so it will keep the avatar | ||
97 | // standing as well as moving. Destruction of the avatar will destroy the pre-step action. | ||
98 | m_moveActor = new BSActorAvatarMove(PhysScene, this, AvatarMoveActorName); | ||
99 | PhysicalActors.Add(AvatarMoveActorName, m_moveActor); | ||
107 | 100 | ||
108 | DetailLog("{0},BSCharacter.create,call,size={1},scale={2},density={3},volume={4},mass={5}", | 101 | DetailLog("{0},BSCharacter.create,call,size={1},scale={2},density={3},volume={4},mass={5}", |
109 | LocalID, _size, Scale, _avatarDensity, _avatarVolume, RawMass); | 102 | LocalID, _size, Scale, Density, _avatarVolume, RawMass); |
110 | 103 | ||
111 | // do actual creation in taint time | 104 | // do actual creation in taint time |
112 | PhysicsScene.TaintedObject("BSCharacter.create", delegate() | 105 | PhysScene.TaintedObject("BSCharacter.create", delegate() |
113 | { | 106 | { |
114 | DetailLog("{0},BSCharacter.create,taint", LocalID); | 107 | DetailLog("{0},BSCharacter.create,taint", LocalID); |
115 | // New body and shape into PhysBody and PhysShape | 108 | // New body and shape into PhysBody and PhysShape |
116 | PhysicsScene.Shapes.GetBodyAndShape(true, PhysicsScene.World, this); | 109 | PhysScene.Shapes.GetBodyAndShape(true, PhysScene.World, this); |
117 | 110 | ||
118 | SetPhysicalProperties(); | 111 | SetPhysicalProperties(); |
119 | }); | 112 | }); |
@@ -126,114 +119,63 @@ public sealed class BSCharacter : BSPhysObject | |||
126 | base.Destroy(); | 119 | base.Destroy(); |
127 | 120 | ||
128 | DetailLog("{0},BSCharacter.Destroy", LocalID); | 121 | DetailLog("{0},BSCharacter.Destroy", LocalID); |
129 | PhysicsScene.TaintedObject("BSCharacter.destroy", delegate() | 122 | PhysScene.TaintedObject("BSCharacter.destroy", delegate() |
130 | { | 123 | { |
131 | PhysicsScene.Shapes.DereferenceBody(PhysBody, true, null); | 124 | PhysScene.Shapes.DereferenceBody(PhysBody, null /* bodyCallback */); |
132 | PhysBody.Clear(); | 125 | PhysBody.Clear(); |
133 | PhysicsScene.Shapes.DereferenceShape(PhysShape, true, null); | 126 | PhysShape.Dereference(PhysScene); |
134 | PhysShape.Clear(); | 127 | PhysShape = new BSShapeNull(); |
135 | }); | 128 | }); |
136 | } | 129 | } |
137 | 130 | ||
138 | private void SetPhysicalProperties() | 131 | private void SetPhysicalProperties() |
139 | { | 132 | { |
140 | PhysicsScene.PE.RemoveObjectFromWorld(PhysicsScene.World, PhysBody); | 133 | PhysScene.PE.RemoveObjectFromWorld(PhysScene.World, PhysBody); |
141 | 134 | ||
142 | ZeroMotion(true); | 135 | ZeroMotion(true); |
143 | ForcePosition = _position; | 136 | ForcePosition = _position; |
144 | 137 | ||
145 | // Set the velocity and compute the proper friction | 138 | // Set the velocity |
146 | _velocityMotor.Reset(); | 139 | if (m_moveActor != null) |
147 | _velocityMotor.SetTarget(_velocity); | 140 | m_moveActor.SetVelocityAndTarget(RawVelocity, RawVelocity, false); |
148 | _velocityMotor.SetCurrent(_velocity); | 141 | |
149 | ForceVelocity = _velocity; | 142 | ForceVelocity = RawVelocity; |
150 | 143 | ||
151 | // This will enable or disable the flying buoyancy of the avatar. | 144 | // This will enable or disable the flying buoyancy of the avatar. |
152 | // Needs to be reset especially when an avatar is recreated after crossing a region boundry. | 145 | // Needs to be reset especially when an avatar is recreated after crossing a region boundry. |
153 | Flying = _flying; | 146 | Flying = _flying; |
154 | 147 | ||
155 | PhysicsScene.PE.SetRestitution(PhysBody, BSParam.AvatarRestitution); | 148 | PhysScene.PE.SetRestitution(PhysBody, BSParam.AvatarRestitution); |
156 | PhysicsScene.PE.SetMargin(PhysShape, PhysicsScene.Params.collisionMargin); | 149 | PhysScene.PE.SetMargin(PhysShape.physShapeInfo, PhysScene.Params.collisionMargin); |
157 | PhysicsScene.PE.SetLocalScaling(PhysShape, Scale); | 150 | PhysScene.PE.SetLocalScaling(PhysShape.physShapeInfo, Scale); |
158 | PhysicsScene.PE.SetContactProcessingThreshold(PhysBody, BSParam.ContactProcessingThreshold); | 151 | PhysScene.PE.SetContactProcessingThreshold(PhysBody, BSParam.ContactProcessingThreshold); |
159 | if (BSParam.CcdMotionThreshold > 0f) | 152 | if (BSParam.CcdMotionThreshold > 0f) |
160 | { | 153 | { |
161 | PhysicsScene.PE.SetCcdMotionThreshold(PhysBody, BSParam.CcdMotionThreshold); | 154 | PhysScene.PE.SetCcdMotionThreshold(PhysBody, BSParam.CcdMotionThreshold); |
162 | PhysicsScene.PE.SetCcdSweptSphereRadius(PhysBody, BSParam.CcdSweptSphereRadius); | 155 | PhysScene.PE.SetCcdSweptSphereRadius(PhysBody, BSParam.CcdSweptSphereRadius); |
163 | } | 156 | } |
164 | 157 | ||
165 | UpdatePhysicalMassProperties(RawMass, false); | 158 | UpdatePhysicalMassProperties(RawMass, false); |
166 | 159 | ||
167 | // Make so capsule does not fall over | 160 | // Make so capsule does not fall over |
168 | PhysicsScene.PE.SetAngularFactorV(PhysBody, OMV.Vector3.Zero); | 161 | PhysScene.PE.SetAngularFactorV(PhysBody, OMV.Vector3.Zero); |
169 | 162 | ||
170 | PhysicsScene.PE.AddToCollisionFlags(PhysBody, CollisionFlags.CF_CHARACTER_OBJECT); | 163 | // The avatar mover sets some parameters. |
164 | PhysicalActors.Refresh(); | ||
171 | 165 | ||
172 | PhysicsScene.PE.AddObjectToWorld(PhysicsScene.World, PhysBody); | 166 | PhysScene.PE.AddToCollisionFlags(PhysBody, CollisionFlags.CF_CHARACTER_OBJECT); |
167 | |||
168 | PhysScene.PE.AddObjectToWorld(PhysScene.World, PhysBody); | ||
173 | 169 | ||
174 | // PhysicsScene.PE.ForceActivationState(PhysBody, ActivationState.ACTIVE_TAG); | 170 | // PhysicsScene.PE.ForceActivationState(PhysBody, ActivationState.ACTIVE_TAG); |
175 | PhysicsScene.PE.ForceActivationState(PhysBody, ActivationState.DISABLE_DEACTIVATION); | 171 | PhysScene.PE.ForceActivationState(PhysBody, ActivationState.DISABLE_DEACTIVATION); |
176 | PhysicsScene.PE.UpdateSingleAabb(PhysicsScene.World, PhysBody); | 172 | PhysScene.PE.UpdateSingleAabb(PhysScene.World, PhysBody); |
177 | 173 | ||
178 | // Do this after the object has been added to the world | 174 | // Do this after the object has been added to the world |
179 | PhysBody.collisionType = CollisionType.Avatar; | 175 | PhysBody.collisionType = CollisionType.Avatar; |
180 | PhysBody.ApplyCollisionMask(PhysicsScene); | 176 | PhysBody.ApplyCollisionMask(PhysScene); |
181 | } | 177 | } |
182 | 178 | ||
183 | // The avatar's movement is controlled by this motor that speeds up and slows down | ||
184 | // the avatar seeking to reach the motor's target speed. | ||
185 | // This motor runs as a prestep action for the avatar so it will keep the avatar | ||
186 | // standing as well as moving. Destruction of the avatar will destroy the pre-step action. | ||
187 | private void SetupMovementMotor() | ||
188 | { | ||
189 | |||
190 | // Someday, use a PID motor for asymmetric speed up and slow down | ||
191 | // _velocityMotor = new BSPIDVMotor("BSCharacter.Velocity", 3f, 5f, BSMotor.InfiniteVector, 1f); | ||
192 | |||
193 | // Infinite decay and timescale values so motor only changes current to target values. | ||
194 | _velocityMotor = new BSVMotor("BSCharacter.Velocity", | ||
195 | 0.2f, // time scale | ||
196 | BSMotor.Infinite, // decay time scale | ||
197 | BSMotor.InfiniteVector, // friction timescale | ||
198 | 1f // efficiency | ||
199 | ); | ||
200 | // _velocityMotor.PhysicsScene = PhysicsScene; // DEBUG DEBUG so motor will output detail log messages. | ||
201 | |||
202 | RegisterPreStepAction("BSCharactor.Movement", LocalID, delegate(float timeStep) | ||
203 | { | ||
204 | // TODO: Decide if the step parameters should be changed depending on the avatar's | ||
205 | // state (flying, colliding, ...). There is code in ODE to do this. | ||
206 | |||
207 | OMV.Vector3 stepVelocity = _velocityMotor.Step(timeStep); | ||
208 | |||
209 | // If falling, we keep the world's downward vector no matter what the other axis specify. | ||
210 | if (!Flying && !IsColliding) | ||
211 | { | ||
212 | stepVelocity.Z = _velocity.Z; | ||
213 | // DetailLog("{0},BSCharacter.MoveMotor,taint,overrideStepZWithWorldZ,stepVel={1}", LocalID, stepVelocity); | ||
214 | } | ||
215 | |||
216 | // 'stepVelocity' is now the speed we'd like the avatar to move in. Turn that into an instantanous force. | ||
217 | OMV.Vector3 moveForce = (stepVelocity - _velocity) * Mass / PhysicsScene.LastTimeStep; | ||
218 | |||
219 | /* | ||
220 | // If moveForce is very small, zero things so we don't keep sending microscopic updates to the user | ||
221 | float moveForceMagnitudeSquared = moveForce.LengthSquared(); | ||
222 | if (moveForceMagnitudeSquared < 0.0001) | ||
223 | { | ||
224 | DetailLog("{0},BSCharacter.MoveMotor,zeroMovement,stepVel={1},vel={2},mass={3},magSq={4},moveForce={5}", | ||
225 | LocalID, stepVelocity, _velocity, Mass, moveForceMagnitudeSquared, moveForce); | ||
226 | ForceVelocity = OMV.Vector3.Zero; | ||
227 | } | ||
228 | else | ||
229 | { | ||
230 | AddForce(moveForce, false, true); | ||
231 | } | ||
232 | */ | ||
233 | // DetailLog("{0},BSCharacter.MoveMotor,move,stepVel={1},vel={2},mass={3},moveForce={4}", LocalID, stepVelocity, _velocity, Mass, moveForce); | ||
234 | AddForce(moveForce, false, true); | ||
235 | }); | ||
236 | } | ||
237 | 179 | ||
238 | public override void RequestPhysicsterseUpdate() | 180 | public override void RequestPhysicsterseUpdate() |
239 | { | 181 | { |
@@ -259,16 +201,16 @@ public sealed class BSCharacter : BSPhysObject | |||
259 | Scale = ComputeAvatarScale(_size); | 201 | Scale = ComputeAvatarScale(_size); |
260 | ComputeAvatarVolumeAndMass(); | 202 | ComputeAvatarVolumeAndMass(); |
261 | DetailLog("{0},BSCharacter.setSize,call,size={1},scale={2},density={3},volume={4},mass={5}", | 203 | DetailLog("{0},BSCharacter.setSize,call,size={1},scale={2},density={3},volume={4},mass={5}", |
262 | LocalID, _size, Scale, _avatarDensity, _avatarVolume, RawMass); | 204 | LocalID, _size, Scale, Density, _avatarVolume, RawMass); |
263 | 205 | ||
264 | PhysicsScene.TaintedObject("BSCharacter.setSize", delegate() | 206 | PhysScene.TaintedObject("BSCharacter.setSize", delegate() |
265 | { | 207 | { |
266 | if (PhysBody.HasPhysicalBody && PhysShape.HasPhysicalShape) | 208 | if (PhysBody.HasPhysicalBody && PhysShape.physShapeInfo.HasPhysicalShape) |
267 | { | 209 | { |
268 | PhysicsScene.PE.SetLocalScaling(PhysShape, Scale); | 210 | PhysScene.PE.SetLocalScaling(PhysShape.physShapeInfo, Scale); |
269 | UpdatePhysicalMassProperties(RawMass, true); | 211 | UpdatePhysicalMassProperties(RawMass, true); |
270 | // Make sure this change appears as a property update event | 212 | // Make sure this change appears as a property update event |
271 | PhysicsScene.PE.PushUpdate(PhysBody); | 213 | PhysScene.PE.PushUpdate(PhysBody); |
272 | } | 214 | } |
273 | }); | 215 | }); |
274 | 216 | ||
@@ -279,11 +221,6 @@ public sealed class BSCharacter : BSPhysObject | |||
279 | { | 221 | { |
280 | set { BaseShape = value; } | 222 | set { BaseShape = value; } |
281 | } | 223 | } |
282 | // I want the physics engine to make an avatar capsule | ||
283 | public override BSPhysicsShapeType PreferredPhysicalShape | ||
284 | { | ||
285 | get {return BSPhysicsShapeType.SHAPE_CAPSULE; } | ||
286 | } | ||
287 | 224 | ||
288 | public override bool Grabbed { | 225 | public override bool Grabbed { |
289 | set { _grabbed = value; } | 226 | set { _grabbed = value; } |
@@ -291,6 +228,10 @@ public sealed class BSCharacter : BSPhysObject | |||
291 | public override bool Selected { | 228 | public override bool Selected { |
292 | set { _selected = value; } | 229 | set { _selected = value; } |
293 | } | 230 | } |
231 | public override bool IsSelected | ||
232 | { | ||
233 | get { return _selected; } | ||
234 | } | ||
294 | public override void CrossingFailure() { return; } | 235 | public override void CrossingFailure() { return; } |
295 | public override void link(PhysicsActor obj) { return; } | 236 | public override void link(PhysicsActor obj) { return; } |
296 | public override void delink() { return; } | 237 | public override void delink() { return; } |
@@ -301,29 +242,29 @@ public sealed class BSCharacter : BSPhysObject | |||
301 | // Called at taint time! | 242 | // Called at taint time! |
302 | public override void ZeroMotion(bool inTaintTime) | 243 | public override void ZeroMotion(bool inTaintTime) |
303 | { | 244 | { |
304 | _velocity = OMV.Vector3.Zero; | 245 | RawVelocity = OMV.Vector3.Zero; |
305 | _acceleration = OMV.Vector3.Zero; | 246 | _acceleration = OMV.Vector3.Zero; |
306 | _rotationalVelocity = OMV.Vector3.Zero; | 247 | _rotationalVelocity = OMV.Vector3.Zero; |
307 | 248 | ||
308 | // Zero some other properties directly into the physics engine | 249 | // Zero some other properties directly into the physics engine |
309 | PhysicsScene.TaintedObject(inTaintTime, "BSCharacter.ZeroMotion", delegate() | 250 | PhysScene.TaintedObject(inTaintTime, "BSCharacter.ZeroMotion", delegate() |
310 | { | 251 | { |
311 | if (PhysBody.HasPhysicalBody) | 252 | if (PhysBody.HasPhysicalBody) |
312 | PhysicsScene.PE.ClearAllForces(PhysBody); | 253 | PhysScene.PE.ClearAllForces(PhysBody); |
313 | }); | 254 | }); |
314 | } | 255 | } |
315 | public override void ZeroAngularMotion(bool inTaintTime) | 256 | public override void ZeroAngularMotion(bool inTaintTime) |
316 | { | 257 | { |
317 | _rotationalVelocity = OMV.Vector3.Zero; | 258 | _rotationalVelocity = OMV.Vector3.Zero; |
318 | 259 | ||
319 | PhysicsScene.TaintedObject(inTaintTime, "BSCharacter.ZeroMotion", delegate() | 260 | PhysScene.TaintedObject(inTaintTime, "BSCharacter.ZeroMotion", delegate() |
320 | { | 261 | { |
321 | if (PhysBody.HasPhysicalBody) | 262 | if (PhysBody.HasPhysicalBody) |
322 | { | 263 | { |
323 | PhysicsScene.PE.SetInterpolationAngularVelocity(PhysBody, OMV.Vector3.Zero); | 264 | PhysScene.PE.SetInterpolationAngularVelocity(PhysBody, OMV.Vector3.Zero); |
324 | PhysicsScene.PE.SetAngularVelocity(PhysBody, OMV.Vector3.Zero); | 265 | PhysScene.PE.SetAngularVelocity(PhysBody, OMV.Vector3.Zero); |
325 | // The next also get rid of applied linear force but the linear velocity is untouched. | 266 | // The next also get rid of applied linear force but the linear velocity is untouched. |
326 | PhysicsScene.PE.ClearForces(PhysBody); | 267 | PhysScene.PE.ClearForces(PhysBody); |
327 | } | 268 | } |
328 | }); | 269 | }); |
329 | } | 270 | } |
@@ -344,25 +285,26 @@ public sealed class BSCharacter : BSPhysObject | |||
344 | } | 285 | } |
345 | set { | 286 | set { |
346 | _position = value; | 287 | _position = value; |
347 | PositionSanityCheck(); | ||
348 | 288 | ||
349 | PhysicsScene.TaintedObject("BSCharacter.setPosition", delegate() | 289 | PhysScene.TaintedObject("BSCharacter.setPosition", delegate() |
350 | { | 290 | { |
351 | DetailLog("{0},BSCharacter.SetPosition,taint,pos={1},orient={2}", LocalID, _position, _orientation); | 291 | DetailLog("{0},BSCharacter.SetPosition,taint,pos={1},orient={2}", LocalID, _position, _orientation); |
352 | if (PhysBody.HasPhysicalBody) | 292 | PositionSanityCheck(); |
353 | PhysicsScene.PE.SetTranslation(PhysBody, _position, _orientation); | 293 | ForcePosition = _position; |
354 | }); | 294 | }); |
355 | } | 295 | } |
356 | } | 296 | } |
357 | public override OMV.Vector3 ForcePosition { | 297 | public override OMV.Vector3 ForcePosition { |
358 | get { | 298 | get { |
359 | _position = PhysicsScene.PE.GetPosition(PhysBody); | 299 | _position = PhysScene.PE.GetPosition(PhysBody); |
360 | return _position; | 300 | return _position; |
361 | } | 301 | } |
362 | set { | 302 | set { |
363 | _position = value; | 303 | _position = value; |
364 | PositionSanityCheck(); | 304 | if (PhysBody.HasPhysicalBody) |
365 | PhysicsScene.PE.SetTranslation(PhysBody, _position, _orientation); | 305 | { |
306 | PhysScene.PE.SetTranslation(PhysBody, _position, _orientation); | ||
307 | } | ||
366 | } | 308 | } |
367 | } | 309 | } |
368 | 310 | ||
@@ -375,25 +317,27 @@ public sealed class BSCharacter : BSPhysObject | |||
375 | bool ret = false; | 317 | bool ret = false; |
376 | 318 | ||
377 | // TODO: check for out of bounds | 319 | // TODO: check for out of bounds |
378 | if (!PhysicsScene.TerrainManager.IsWithinKnownTerrain(_position)) | 320 | if (!PhysScene.TerrainManager.IsWithinKnownTerrain(RawPosition)) |
379 | { | 321 | { |
380 | // The character is out of the known/simulated area. | 322 | // The character is out of the known/simulated area. |
381 | // Upper levels of code will handle the transition to other areas so, for | 323 | // Force the avatar position to be within known. ScenePresence will use the position |
382 | // the time, we just ignore the position. | 324 | // plus the velocity to decide if the avatar is moving out of the region. |
383 | return ret; | 325 | RawPosition = PhysScene.TerrainManager.ClampPositionIntoKnownTerrain(RawPosition); |
326 | DetailLog("{0},BSCharacter.PositionSanityCheck,notWithinKnownTerrain,clampedPos={1}", LocalID, RawPosition); | ||
327 | return true; | ||
384 | } | 328 | } |
385 | 329 | ||
386 | // If below the ground, move the avatar up | 330 | // If below the ground, move the avatar up |
387 | float terrainHeight = PhysicsScene.TerrainManager.GetTerrainHeightAtXYZ(_position); | 331 | float terrainHeight = PhysScene.TerrainManager.GetTerrainHeightAtXYZ(RawPosition); |
388 | if (Position.Z < terrainHeight) | 332 | if (Position.Z < terrainHeight) |
389 | { | 333 | { |
390 | DetailLog("{0},BSCharacter.PositionAdjustUnderGround,call,pos={1},terrain={2}", LocalID, _position, terrainHeight); | 334 | DetailLog("{0},BSCharacter.PositionSanityCheck,adjustForUnderGround,pos={1},terrain={2}", LocalID, _position, terrainHeight); |
391 | _position.Z = terrainHeight + 2.0f; | 335 | _position.Z = terrainHeight + BSParam.AvatarBelowGroundUpCorrectionMeters; |
392 | ret = true; | 336 | ret = true; |
393 | } | 337 | } |
394 | if ((CurrentCollisionFlags & CollisionFlags.BS_FLOATS_ON_WATER) != 0) | 338 | if ((CurrentCollisionFlags & CollisionFlags.BS_FLOATS_ON_WATER) != 0) |
395 | { | 339 | { |
396 | float waterHeight = PhysicsScene.TerrainManager.GetWaterLevelAtXYZ(_position); | 340 | float waterHeight = PhysScene.TerrainManager.GetWaterLevelAtXYZ(_position); |
397 | if (Position.Z < waterHeight) | 341 | if (Position.Z < waterHeight) |
398 | { | 342 | { |
399 | _position.Z = waterHeight; | 343 | _position.Z = waterHeight; |
@@ -414,11 +358,10 @@ public sealed class BSCharacter : BSPhysObject | |||
414 | { | 358 | { |
415 | // The new position value must be pushed into the physics engine but we can't | 359 | // The new position value must be pushed into the physics engine but we can't |
416 | // just assign to "Position" because of potential call loops. | 360 | // just assign to "Position" because of potential call loops. |
417 | PhysicsScene.TaintedObject(inTaintTime, "BSCharacter.PositionSanityCheck", delegate() | 361 | PhysScene.TaintedObject(inTaintTime, "BSCharacter.PositionSanityCheck", delegate() |
418 | { | 362 | { |
419 | DetailLog("{0},BSCharacter.PositionSanityCheck,taint,pos={1},orient={2}", LocalID, _position, _orientation); | 363 | DetailLog("{0},BSCharacter.PositionSanityCheck,taint,pos={1},orient={2}", LocalID, _position, _orientation); |
420 | if (PhysBody.HasPhysicalBody) | 364 | ForcePosition = _position; |
421 | PhysicsScene.PE.SetTranslation(PhysBody, _position, _orientation); | ||
422 | }); | 365 | }); |
423 | ret = true; | 366 | ret = true; |
424 | } | 367 | } |
@@ -428,25 +371,25 @@ public sealed class BSCharacter : BSPhysObject | |||
428 | public override float Mass { get { return _mass; } } | 371 | public override float Mass { get { return _mass; } } |
429 | 372 | ||
430 | // used when we only want this prim's mass and not the linkset thing | 373 | // used when we only want this prim's mass and not the linkset thing |
431 | public override float RawMass { | 374 | public override float RawMass { |
432 | get {return _mass; } | 375 | get {return _mass; } |
433 | } | 376 | } |
434 | public override void UpdatePhysicalMassProperties(float physMass, bool inWorld) | 377 | public override void UpdatePhysicalMassProperties(float physMass, bool inWorld) |
435 | { | 378 | { |
436 | OMV.Vector3 localInertia = PhysicsScene.PE.CalculateLocalInertia(PhysShape, physMass); | 379 | OMV.Vector3 localInertia = PhysScene.PE.CalculateLocalInertia(PhysShape.physShapeInfo, physMass); |
437 | PhysicsScene.PE.SetMassProps(PhysBody, physMass, localInertia); | 380 | PhysScene.PE.SetMassProps(PhysBody, physMass, localInertia); |
438 | } | 381 | } |
439 | 382 | ||
440 | public override OMV.Vector3 Force { | 383 | public override OMV.Vector3 Force { |
441 | get { return _force; } | 384 | get { return RawForce; } |
442 | set { | 385 | set { |
443 | _force = value; | 386 | RawForce = value; |
444 | // m_log.DebugFormat("{0}: Force = {1}", LogHeader, _force); | 387 | // m_log.DebugFormat("{0}: Force = {1}", LogHeader, _force); |
445 | PhysicsScene.TaintedObject("BSCharacter.SetForce", delegate() | 388 | PhysScene.TaintedObject("BSCharacter.SetForce", delegate() |
446 | { | 389 | { |
447 | DetailLog("{0},BSCharacter.setForce,taint,force={1}", LocalID, _force); | 390 | DetailLog("{0},BSCharacter.setForce,taint,force={1}", LocalID, RawForce); |
448 | if (PhysBody.HasPhysicalBody) | 391 | if (PhysBody.HasPhysicalBody) |
449 | PhysicsScene.PE.SetObjectForce(PhysBody, _force); | 392 | PhysScene.PE.SetObjectForce(PhysBody, RawForce); |
450 | }); | 393 | }); |
451 | } | 394 | } |
452 | } | 395 | } |
@@ -469,77 +412,49 @@ public sealed class BSCharacter : BSPhysObject | |||
469 | { | 412 | { |
470 | get | 413 | get |
471 | { | 414 | { |
472 | return _velocityMotor.TargetValue; | 415 | return base.m_targetVelocity; |
473 | } | 416 | } |
474 | set | 417 | set |
475 | { | 418 | { |
476 | DetailLog("{0},BSCharacter.setTargetVelocity,call,vel={1}", LocalID, value); | 419 | DetailLog("{0},BSCharacter.setTargetVelocity,call,vel={1}", LocalID, value); |
420 | m_targetVelocity = value; | ||
477 | OMV.Vector3 targetVel = value; | 421 | OMV.Vector3 targetVel = value; |
478 | if (_setAlwaysRun) | 422 | if (_setAlwaysRun) |
479 | targetVel *= BSParam.AvatarAlwaysRunFactor; | 423 | targetVel *= new OMV.Vector3(BSParam.AvatarAlwaysRunFactor, BSParam.AvatarAlwaysRunFactor, 0f); |
480 | 424 | ||
481 | PhysicsScene.TaintedObject("BSCharacter.setTargetVelocity", delegate() | 425 | if (m_moveActor != null) |
482 | { | 426 | m_moveActor.SetVelocityAndTarget(RawVelocity, targetVel, false /* inTaintTime */); |
483 | _velocityMotor.Reset(); | ||
484 | _velocityMotor.SetTarget(targetVel); | ||
485 | _velocityMotor.SetCurrent(_velocity); | ||
486 | _velocityMotor.Enabled = true; | ||
487 | }); | ||
488 | } | 427 | } |
489 | } | 428 | } |
490 | // Directly setting velocity means this is what the user really wants now. | 429 | // Directly setting velocity means this is what the user really wants now. |
491 | public override OMV.Vector3 Velocity { | 430 | public override OMV.Vector3 Velocity { |
492 | get { return _velocity; } | 431 | get { return RawVelocity; } |
493 | set { | 432 | set { |
494 | _velocity = value; | 433 | RawVelocity = value; |
495 | // m_log.DebugFormat("{0}: set velocity = {1}", LogHeader, _velocity); | 434 | // m_log.DebugFormat("{0}: set velocity = {1}", LogHeader, RawVelocity); |
496 | PhysicsScene.TaintedObject("BSCharacter.setVelocity", delegate() | 435 | PhysScene.TaintedObject("BSCharacter.setVelocity", delegate() |
497 | { | 436 | { |
498 | _velocityMotor.Reset(); | 437 | if (m_moveActor != null) |
499 | _velocityMotor.SetCurrent(_velocity); | 438 | m_moveActor.SetVelocityAndTarget(RawVelocity, RawVelocity, true /* inTaintTime */); |
500 | _velocityMotor.SetTarget(_velocity); | 439 | |
501 | // Even though the motor is initialized, it's not used and the velocity goes straight into the avatar. | 440 | DetailLog("{0},BSCharacter.setVelocity,taint,vel={1}", LocalID, RawVelocity); |
502 | _velocityMotor.Enabled = false; | 441 | ForceVelocity = RawVelocity; |
503 | |||
504 | DetailLog("{0},BSCharacter.setVelocity,taint,vel={1}", LocalID, _velocity); | ||
505 | ForceVelocity = _velocity; | ||
506 | }); | 442 | }); |
507 | } | 443 | } |
508 | } | 444 | } |
509 | public override OMV.Vector3 ForceVelocity { | 445 | public override OMV.Vector3 ForceVelocity { |
510 | get { return _velocity; } | 446 | get { return RawVelocity; } |
511 | set { | 447 | set { |
512 | PhysicsScene.AssertInTaintTime("BSCharacter.ForceVelocity"); | 448 | PhysScene.AssertInTaintTime("BSCharacter.ForceVelocity"); |
513 | 449 | ||
514 | _velocity = value; | 450 | RawVelocity = value; |
515 | // Depending on whether the avatar is moving or not, change the friction | 451 | PhysScene.PE.SetLinearVelocity(PhysBody, RawVelocity); |
516 | // to keep the avatar from slipping around | 452 | PhysScene.PE.Activate(PhysBody, true); |
517 | if (_velocity.Length() == 0) | ||
518 | { | ||
519 | if (_currentFriction != BSParam.AvatarStandingFriction) | ||
520 | { | ||
521 | _currentFriction = BSParam.AvatarStandingFriction; | ||
522 | if (PhysBody.HasPhysicalBody) | ||
523 | PhysicsScene.PE.SetFriction(PhysBody, _currentFriction); | ||
524 | } | ||
525 | } | ||
526 | else | ||
527 | { | ||
528 | if (_currentFriction != BSParam.AvatarFriction) | ||
529 | { | ||
530 | _currentFriction = BSParam.AvatarFriction; | ||
531 | if (PhysBody.HasPhysicalBody) | ||
532 | PhysicsScene.PE.SetFriction(PhysBody, _currentFriction); | ||
533 | } | ||
534 | } | ||
535 | |||
536 | PhysicsScene.PE.SetLinearVelocity(PhysBody, _velocity); | ||
537 | PhysicsScene.PE.Activate(PhysBody, true); | ||
538 | } | 453 | } |
539 | } | 454 | } |
540 | public override OMV.Vector3 Torque { | 455 | public override OMV.Vector3 Torque { |
541 | get { return _torque; } | 456 | get { return RawTorque; } |
542 | set { _torque = value; | 457 | set { RawTorque = value; |
543 | } | 458 | } |
544 | } | 459 | } |
545 | public override float CollisionScore { | 460 | public override float CollisionScore { |
@@ -564,7 +479,7 @@ public sealed class BSCharacter : BSPhysObject | |||
564 | if (_orientation != value) | 479 | if (_orientation != value) |
565 | { | 480 | { |
566 | _orientation = value; | 481 | _orientation = value; |
567 | PhysicsScene.TaintedObject("BSCharacter.setOrientation", delegate() | 482 | PhysScene.TaintedObject("BSCharacter.setOrientation", delegate() |
568 | { | 483 | { |
569 | ForceOrientation = _orientation; | 484 | ForceOrientation = _orientation; |
570 | }); | 485 | }); |
@@ -576,7 +491,7 @@ public sealed class BSCharacter : BSPhysObject | |||
576 | { | 491 | { |
577 | get | 492 | get |
578 | { | 493 | { |
579 | _orientation = PhysicsScene.PE.GetOrientation(PhysBody); | 494 | _orientation = PhysScene.PE.GetOrientation(PhysBody); |
580 | return _orientation; | 495 | return _orientation; |
581 | } | 496 | } |
582 | set | 497 | set |
@@ -585,7 +500,7 @@ public sealed class BSCharacter : BSPhysObject | |||
585 | if (PhysBody.HasPhysicalBody) | 500 | if (PhysBody.HasPhysicalBody) |
586 | { | 501 | { |
587 | // _position = PhysicsScene.PE.GetPosition(BSBody); | 502 | // _position = PhysicsScene.PE.GetPosition(BSBody); |
588 | PhysicsScene.PE.SetTranslation(PhysBody, _position, _orientation); | 503 | PhysScene.PE.SetTranslation(PhysBody, _position, _orientation); |
589 | } | 504 | } |
590 | } | 505 | } |
591 | } | 506 | } |
@@ -605,6 +520,9 @@ public sealed class BSCharacter : BSPhysObject | |||
605 | public override bool IsStatic { | 520 | public override bool IsStatic { |
606 | get { return false; } | 521 | get { return false; } |
607 | } | 522 | } |
523 | public override bool IsPhysicallyActive { | ||
524 | get { return true; } | ||
525 | } | ||
608 | public override bool Flying { | 526 | public override bool Flying { |
609 | get { return _flying; } | 527 | get { return _flying; } |
610 | set { | 528 | set { |
@@ -631,14 +549,14 @@ public sealed class BSCharacter : BSPhysObject | |||
631 | public override bool FloatOnWater { | 549 | public override bool FloatOnWater { |
632 | set { | 550 | set { |
633 | _floatOnWater = value; | 551 | _floatOnWater = value; |
634 | PhysicsScene.TaintedObject("BSCharacter.setFloatOnWater", delegate() | 552 | PhysScene.TaintedObject("BSCharacter.setFloatOnWater", delegate() |
635 | { | 553 | { |
636 | if (PhysBody.HasPhysicalBody) | 554 | if (PhysBody.HasPhysicalBody) |
637 | { | 555 | { |
638 | if (_floatOnWater) | 556 | if (_floatOnWater) |
639 | CurrentCollisionFlags = PhysicsScene.PE.AddToCollisionFlags(PhysBody, CollisionFlags.BS_FLOATS_ON_WATER); | 557 | CurrentCollisionFlags = PhysScene.PE.AddToCollisionFlags(PhysBody, CollisionFlags.BS_FLOATS_ON_WATER); |
640 | else | 558 | else |
641 | CurrentCollisionFlags = PhysicsScene.PE.RemoveFromCollisionFlags(PhysBody, CollisionFlags.BS_FLOATS_ON_WATER); | 559 | CurrentCollisionFlags = PhysScene.PE.RemoveFromCollisionFlags(PhysBody, CollisionFlags.BS_FLOATS_ON_WATER); |
642 | } | 560 | } |
643 | }); | 561 | }); |
644 | } | 562 | } |
@@ -659,7 +577,7 @@ public sealed class BSCharacter : BSPhysObject | |||
659 | public override float Buoyancy { | 577 | public override float Buoyancy { |
660 | get { return _buoyancy; } | 578 | get { return _buoyancy; } |
661 | set { _buoyancy = value; | 579 | set { _buoyancy = value; |
662 | PhysicsScene.TaintedObject("BSCharacter.setBuoyancy", delegate() | 580 | PhysScene.TaintedObject("BSCharacter.setBuoyancy", delegate() |
663 | { | 581 | { |
664 | DetailLog("{0},BSCharacter.setBuoyancy,taint,buoy={1}", LocalID, _buoyancy); | 582 | DetailLog("{0},BSCharacter.setBuoyancy,taint,buoy={1}", LocalID, _buoyancy); |
665 | ForceBuoyancy = _buoyancy; | 583 | ForceBuoyancy = _buoyancy; |
@@ -668,15 +586,16 @@ public sealed class BSCharacter : BSPhysObject | |||
668 | } | 586 | } |
669 | public override float ForceBuoyancy { | 587 | public override float ForceBuoyancy { |
670 | get { return _buoyancy; } | 588 | get { return _buoyancy; } |
671 | set { | 589 | set { |
672 | PhysicsScene.AssertInTaintTime("BSCharacter.ForceBuoyancy"); | 590 | PhysScene.AssertInTaintTime("BSCharacter.ForceBuoyancy"); |
673 | 591 | ||
674 | _buoyancy = value; | 592 | _buoyancy = value; |
675 | DetailLog("{0},BSCharacter.setForceBuoyancy,taint,buoy={1}", LocalID, _buoyancy); | 593 | DetailLog("{0},BSCharacter.setForceBuoyancy,taint,buoy={1}", LocalID, _buoyancy); |
676 | // Buoyancy is faked by changing the gravity applied to the object | 594 | // Buoyancy is faked by changing the gravity applied to the object |
677 | float grav = PhysicsScene.Params.gravity * (1f - _buoyancy); | 595 | float grav = BSParam.Gravity * (1f - _buoyancy); |
596 | Gravity = new OMV.Vector3(0f, 0f, grav); | ||
678 | if (PhysBody.HasPhysicalBody) | 597 | if (PhysBody.HasPhysicalBody) |
679 | PhysicsScene.PE.SetGravity(PhysBody, new OMV.Vector3(0f, 0f, grav)); | 598 | PhysScene.PE.SetGravity(PhysBody, Gravity); |
680 | } | 599 | } |
681 | } | 600 | } |
682 | 601 | ||
@@ -691,53 +610,25 @@ public sealed class BSCharacter : BSPhysObject | |||
691 | set { _PIDTau = value; } | 610 | set { _PIDTau = value; } |
692 | } | 611 | } |
693 | 612 | ||
694 | // Used for llSetHoverHeight and maybe vehicle height | ||
695 | // Hover Height will override MoveTo target's Z | ||
696 | public override bool PIDHoverActive { | ||
697 | set { _useHoverPID = value; } | ||
698 | } | ||
699 | public override float PIDHoverHeight { | ||
700 | set { _PIDHoverHeight = value; } | ||
701 | } | ||
702 | public override PIDHoverType PIDHoverType { | ||
703 | set { _PIDHoverType = value; } | ||
704 | } | ||
705 | public override float PIDHoverTau { | ||
706 | set { _PIDHoverTao = value; } | ||
707 | } | ||
708 | |||
709 | // For RotLookAt | ||
710 | public override OMV.Quaternion APIDTarget { set { return; } } | ||
711 | public override bool APIDActive { set { return; } } | ||
712 | public override float APIDStrength { set { return; } } | ||
713 | public override float APIDDamping { set { return; } } | ||
714 | |||
715 | public override void AddForce(OMV.Vector3 force, bool pushforce) | 613 | public override void AddForce(OMV.Vector3 force, bool pushforce) |
716 | { | 614 | { |
717 | // Since this force is being applied in only one step, make this a force per second. | 615 | // Since this force is being applied in only one step, make this a force per second. |
718 | OMV.Vector3 addForce = force / PhysicsScene.LastTimeStep; | 616 | OMV.Vector3 addForce = force / PhysScene.LastTimeStep; |
719 | AddForce(addForce, pushforce, false); | 617 | AddForce(addForce, pushforce, false); |
720 | } | 618 | } |
721 | private void AddForce(OMV.Vector3 force, bool pushforce, bool inTaintTime) { | 619 | private void AddForce(OMV.Vector3 force, bool pushforce, bool inTaintTime) { |
722 | if (force.IsFinite()) | 620 | if (force.IsFinite()) |
723 | { | 621 | { |
724 | float magnitude = force.Length(); | 622 | OMV.Vector3 addForce = Util.ClampV(force, BSParam.MaxAddForceMagnitude); |
725 | if (magnitude > BSParam.MaxAddForceMagnitude) | ||
726 | { | ||
727 | // Force has a limit | ||
728 | force = force / magnitude * BSParam.MaxAddForceMagnitude; | ||
729 | } | ||
730 | |||
731 | OMV.Vector3 addForce = force; | ||
732 | // DetailLog("{0},BSCharacter.addForce,call,force={1}", LocalID, addForce); | 623 | // DetailLog("{0},BSCharacter.addForce,call,force={1}", LocalID, addForce); |
733 | 624 | ||
734 | PhysicsScene.TaintedObject(inTaintTime, "BSCharacter.AddForce", delegate() | 625 | PhysScene.TaintedObject(inTaintTime, "BSCharacter.AddForce", delegate() |
735 | { | 626 | { |
736 | // Bullet adds this central force to the total force for this tick | 627 | // Bullet adds this central force to the total force for this tick |
737 | // DetailLog("{0},BSCharacter.addForce,taint,force={1}", LocalID, addForce); | 628 | // DetailLog("{0},BSCharacter.addForce,taint,force={1}", LocalID, addForce); |
738 | if (PhysBody.HasPhysicalBody) | 629 | if (PhysBody.HasPhysicalBody) |
739 | { | 630 | { |
740 | PhysicsScene.PE.ApplyCentralForce(PhysBody, addForce); | 631 | PhysScene.PE.ApplyCentralForce(PhysBody, addForce); |
741 | } | 632 | } |
742 | }); | 633 | }); |
743 | } | 634 | } |
@@ -748,7 +639,7 @@ public sealed class BSCharacter : BSPhysObject | |||
748 | } | 639 | } |
749 | } | 640 | } |
750 | 641 | ||
751 | public override void AddAngularForce(OMV.Vector3 force, bool pushforce) { | 642 | public override void AddAngularForce(OMV.Vector3 force, bool pushforce, bool inTaintTime) { |
752 | } | 643 | } |
753 | public override void SetMomentum(OMV.Vector3 momentum) { | 644 | public override void SetMomentum(OMV.Vector3 momentum) { |
754 | } | 645 | } |
@@ -756,7 +647,7 @@ public sealed class BSCharacter : BSPhysObject | |||
756 | private OMV.Vector3 ComputeAvatarScale(OMV.Vector3 size) | 647 | private OMV.Vector3 ComputeAvatarScale(OMV.Vector3 size) |
757 | { | 648 | { |
758 | OMV.Vector3 newScale; | 649 | OMV.Vector3 newScale; |
759 | 650 | ||
760 | // Bullet's capsule total height is the "passed height + radius * 2"; | 651 | // Bullet's capsule total height is the "passed height + radius * 2"; |
761 | // The base capsule is 1 diameter and 2 height (passed radius=0.5, passed height = 1) | 652 | // The base capsule is 1 diameter and 2 height (passed radius=0.5, passed height = 1) |
762 | // The number we pass in for 'scaling' is the multiplier to get that base | 653 | // The number we pass in for 'scaling' is the multiplier to get that base |
@@ -794,34 +685,48 @@ public sealed class BSCharacter : BSPhysObject | |||
794 | * Math.Min(Size.X, Size.Y) / 2 | 685 | * Math.Min(Size.X, Size.Y) / 2 |
795 | * Size.Y / 2f // plus the volume of the capsule end caps | 686 | * Size.Y / 2f // plus the volume of the capsule end caps |
796 | ); | 687 | ); |
797 | _mass = _avatarDensity * _avatarVolume; | 688 | _mass = Density * BSParam.DensityScaleFactor * _avatarVolume; |
798 | } | 689 | } |
799 | 690 | ||
800 | // The physics engine says that properties have updated. Update same and inform | 691 | // The physics engine says that properties have updated. Update same and inform |
801 | // the world that things have changed. | 692 | // the world that things have changed. |
802 | public override void UpdateProperties(EntityProperties entprop) | 693 | public override void UpdateProperties(EntityProperties entprop) |
803 | { | 694 | { |
804 | _position = entprop.Position; | 695 | // Don't change position if standing on a stationary object. |
696 | if (!IsStationary) | ||
697 | _position = entprop.Position; | ||
698 | |||
805 | _orientation = entprop.Rotation; | 699 | _orientation = entprop.Rotation; |
806 | _velocity = entprop.Velocity; | 700 | |
701 | // Smooth velocity. OpenSimulator is VERY sensitive to changes in velocity of the avatar | ||
702 | // and will send agent updates to the clients if velocity changes by more than | ||
703 | // 0.001m/s. Bullet introduces a lot of jitter in the velocity which causes many | ||
704 | // extra updates. | ||
705 | if (!entprop.Velocity.ApproxEquals(RawVelocity, 0.1f)) | ||
706 | RawVelocity = entprop.Velocity; | ||
707 | |||
807 | _acceleration = entprop.Acceleration; | 708 | _acceleration = entprop.Acceleration; |
808 | _rotationalVelocity = entprop.RotationalVelocity; | 709 | _rotationalVelocity = entprop.RotationalVelocity; |
809 | 710 | ||
810 | // Do some sanity checking for the avatar. Make sure it's above ground and inbounds. | 711 | // Do some sanity checking for the avatar. Make sure it's above ground and inbounds. |
811 | PositionSanityCheck(true); | 712 | if (PositionSanityCheck(true)) |
713 | { | ||
714 | DetailLog("{0},BSCharacter.UpdateProperties,updatePosForSanity,pos={1}", LocalID, _position); | ||
715 | entprop.Position = _position; | ||
716 | } | ||
812 | 717 | ||
813 | // remember the current and last set values | 718 | // remember the current and last set values |
814 | LastEntityProperties = CurrentEntityProperties; | 719 | LastEntityProperties = CurrentEntityProperties; |
815 | CurrentEntityProperties = entprop; | 720 | CurrentEntityProperties = entprop; |
816 | 721 | ||
817 | // Tell the linkset about value changes | 722 | // Tell the linkset about value changes |
818 | Linkset.UpdateProperties(this, true); | 723 | // Linkset.UpdateProperties(UpdatedProperties.EntPropUpdates, this); |
819 | 724 | ||
820 | // Avatars don't report their changes the usual way. Changes are checked for in the heartbeat loop. | 725 | // Avatars don't report their changes the usual way. Changes are checked for in the heartbeat loop. |
821 | // base.RequestPhysicsterseUpdate(); | 726 | // base.RequestPhysicsterseUpdate(); |
822 | 727 | ||
823 | DetailLog("{0},BSCharacter.UpdateProperties,call,pos={1},orient={2},vel={3},accel={4},rotVel={5}", | 728 | DetailLog("{0},BSCharacter.UpdateProperties,call,pos={1},orient={2},vel={3},accel={4},rotVel={5}", |
824 | LocalID, _position, _orientation, _velocity, _acceleration, _rotationalVelocity); | 729 | LocalID, _position, _orientation, RawVelocity, _acceleration, _rotationalVelocity); |
825 | } | 730 | } |
826 | } | 731 | } |
827 | } | 732 | } |