protected void TriggerPreUpdatePropertyAction(ref EntityProperties entprop) { PreUpdatePropertyAction actions = OnPreUpdateProperty; if (actions != null) { actions(ref entprop); } }
// Called just as the property update is received from the physics engine. // Do any mode necessary for avatar movement. private void Process_OnPreUpdateProperty(ref EntityProperties entprop) { // Don't change position if standing on a stationary object. if (m_controllingPrim.IsStationary) { entprop.Position = m_controllingPrim.RawPosition; entprop.Velocity = OMV.Vector3.Zero; m_physicsScene.PE.SetTranslation(m_controllingPrim.PhysBody, entprop.Position, entprop.Rotation); } }
// The physics engine says that properties have updated. Update same and inform // the world that things have changed. public override void UpdateProperties(EntityProperties entprop) { // Let anyone (like the actors) modify the updated properties before they are pushed into the object and the simulator. TriggerPreUpdatePropertyAction(ref entprop); RawPosition = entprop.Position; RawOrientation = entprop.Rotation; // Smooth velocity. OpenSimulator is VERY sensitive to changes in velocity of the avatar // and will send agent updates to the clients if velocity changes by more than // 0.001m/s. Bullet introduces a lot of jitter in the velocity which causes many // extra updates. // // XXX: Contrary to the above comment, setting an update threshold here above 0.4 actually introduces jitter to // avatar movement rather than removes it. The larger the threshold, the bigger the jitter. // This is most noticeable in level flight and can be seen with // the "show updates" option in a viewer. With an update threshold, the RawVelocity cycles between a lower // bound and an upper bound, where the difference between the two is enough to trigger a large delta v update // and subsequently trigger an update in ScenePresence.SendTerseUpdateToAllClients(). The cause of this cycle (feedback?) // has not yet been identified. // // If there is a threshold below 0.4 or no threshold check at all (as in ODE), then RawVelocity stays constant and extra // updates are not triggered in ScenePresence.SendTerseUpdateToAllClients(). // if (!entprop.Velocity.ApproxEquals(RawVelocity, 0.1f)) RawVelocity = entprop.Velocity; _acceleration = entprop.Acceleration; _rotationalVelocity = entprop.RotationalVelocity; // Do some sanity checking for the avatar. Make sure it's above ground and inbounds. if (PositionSanityCheck(true)) { DetailLog("{0},BSCharacter.UpdateProperties,updatePosForSanity,pos={1}", LocalID, RawPosition); entprop.Position = RawPosition; } // remember the current and last set values LastEntityProperties = CurrentEntityProperties; CurrentEntityProperties = entprop; // Tell the linkset about value changes // Linkset.UpdateProperties(UpdatedProperties.EntPropUpdates, this); // Avatars don't report their changes the usual way. Changes are checked for in the heartbeat loop. // PhysScene.PostUpdate(this); DetailLog("{0},BSCharacter.UpdateProperties,call,pos={1},orient={2},vel={3},accel={4},rotVel={5}", LocalID, RawPosition, RawOrientation, RawVelocity, _acceleration, _rotationalVelocity); }
public override void UpdateProperties(EntityProperties entprop) { // Undo any center-of-mass displacement that might have been done. if (PositionDisplacement != OMV.Vector3.Zero) { // The origional shape was offset from 'zero' by PositionDisplacement. // These physical location must be back converted to be centered around the displaced // root shape. // Move the returned center-of-mass location to the root prim location. OMV.Vector3 displacement = PositionDisplacement * entprop.Rotation; OMV.Vector3 displacedPos = entprop.Position - displacement; DetailLog("{0},BSPrimDisplaced.UpdateProperties,physPos={1},disp={2},simPos={3}", LocalID, entprop.Position, displacement, displacedPos); entprop.Position = displacedPos; } base.UpdateProperties(entprop); }
// Called after a simulation step for the changes in physical object properties. // Do any filtering/modification needed for linksets. public override void UpdateProperties(EntityProperties entprop) { if (Linkset.IsRoot(this) || Linkset.ShouldReportPropertyUpdates(this)) { // Properties are only updated for the roots of a linkset. // TODO: this will have to change when linksets are articulated. base.UpdateProperties(entprop); } /* * else * { * // For debugging, report the movement of children * DetailLog("{0},BSPrim.UpdateProperties,child,pos={1},orient={2},vel={3},accel={4},rotVel={5}", * LocalID, entprop.Position, entprop.Rotation, entprop.Velocity, * entprop.Acceleration, entprop.RotationalVelocity); * } */ // The linkset might like to know about changing locations Linkset.UpdateProperties(UpdatedProperties.EntPropUpdates, this); }
// Initialization and simulation public override BulletWorld Initialize(Vector3 maxPosition, ConfigurationParameters parms, int maxCollisions, ref CollisionDesc[] collisionArray, int maxUpdates, ref EntityProperties[] updateArray ) { // Pin down the memory that will be used to pass object collisions and updates back from unmanaged code m_paramsHandle = GCHandle.Alloc(parms, GCHandleType.Pinned); m_collisionArrayPinnedHandle = GCHandle.Alloc(collisionArray, GCHandleType.Pinned); m_updateArrayPinnedHandle = GCHandle.Alloc(updateArray, GCHandleType.Pinned); // If Debug logging level, enable logging from the unmanaged code m_DebugLogCallbackHandle = null; if (BSScene.m_log.IsDebugEnabled && PhysicsScene.PhysicsLogging.Enabled) { BSScene.m_log.DebugFormat("{0}: Initialize: Setting debug callback for unmanaged code", BSScene.LogHeader); if (PhysicsScene.PhysicsLogging.Enabled) // The handle is saved in a variable to make sure it doesn't get freed after this call m_DebugLogCallbackHandle = new BSAPICPP.DebugLogCallback(BulletLoggerPhysLog); else m_DebugLogCallbackHandle = new BSAPICPP.DebugLogCallback(BulletLogger); } // Get the version of the DLL // TODO: this doesn't work yet. Something wrong with marshaling the returned string. // BulletEngineVersion = BulletSimAPI.GetVersion2(); BulletEngineVersion = ""; // Call the unmanaged code with the buffers and other information return new BulletWorldUnman(0, PhysicsScene, BSAPICPP.Initialize2(maxPosition, m_paramsHandle.AddrOfPinnedObject(), maxCollisions, m_collisionArrayPinnedHandle.AddrOfPinnedObject(), maxUpdates, m_updateArrayPinnedHandle.AddrOfPinnedObject(), m_DebugLogCallbackHandle)); }
// Update the physical location and motion of the object. Called with data from Bullet. public abstract void UpdateProperties(EntityProperties entprop);
// The physics engine says that properties have updated. Update same and inform // the world that things have changed. // NOTE: BSPrim.UpdateProperties is overloaded by BSPrimLinkable which modifies updates from root and children prims. // NOTE: BSPrim.UpdateProperties is overloaded by BSPrimDisplaced which handles mapping physical position to simulator position. public override void UpdateProperties(EntityProperties entprop) { // Let anyone (like the actors) modify the updated properties before they are pushed into the object and the simulator. TriggerPreUpdatePropertyAction(ref entprop); // DetailLog("{0},BSPrim.UpdateProperties,entry,entprop={1}", LocalID, entprop); // DEBUG DEBUG // Assign directly to the local variables so the normal set actions do not happen RawPosition = entprop.Position; RawOrientation = entprop.Rotation; // DEBUG DEBUG DEBUG -- smooth velocity changes a bit. The simulator seems to be // very sensitive to velocity changes. if (entprop.Velocity == OMV.Vector3.Zero || !entprop.Velocity.ApproxEquals(RawVelocity, BSParam.UpdateVelocityChangeThreshold)) RawVelocity = entprop.Velocity; _acceleration = entprop.Acceleration; _rotationalVelocity = entprop.RotationalVelocity; // DetailLog("{0},BSPrim.UpdateProperties,afterAssign,entprop={1}", LocalID, entprop); // DEBUG DEBUG // The sanity check can change the velocity and/or position. if (PositionSanityCheck(true /* inTaintTime */ )) { entprop.Position = RawPosition; entprop.Velocity = RawVelocity; entprop.RotationalVelocity = _rotationalVelocity; entprop.Acceleration = _acceleration; } OMV.Vector3 direction = OMV.Vector3.UnitX * RawOrientation; // DEBUG DEBUG DEBUG DetailLog("{0},BSPrim.UpdateProperties,call,entProp={1},dir={2}", LocalID, entprop, direction); // remember the current and last set values LastEntityProperties = CurrentEntityProperties; CurrentEntityProperties = entprop; PhysScene.PostUpdate(this); }
// Called just as the property update is received from the physics engine. // Do any mode necessary for avatar movement. private void Process_OnPreUpdateProperty(ref EntityProperties entprop) { // Don't change position if standing on a stationary object. if (m_controllingPrim.IsStationary) { entprop.Position = m_controllingPrim.RawPosition; // Suppress small movement velocity if (entprop.Velocity.LengthSquared() < BSParam.AvatarStopZeroThresholdSquared) { m_physicsScene.DetailLog("{0},BSCharacter.MoveMotor,OnPreUpdate,zeroing velocity={1}", m_controllingPrim.LocalID, entprop.Velocity); entprop.Velocity = OMV.Vector3.Zero; } m_physicsScene.PE.SetTranslation(m_controllingPrim.PhysBody, entprop.Position, entprop.Rotation); } }
// Called after a simulation step for the changes in physical object properties. // Do any filtering/modification needed for linksets. public override void UpdateProperties(EntityProperties entprop) { if (Linkset.IsRoot(this) || Linkset.ShouldReportPropertyUpdates(this)) { // Properties are only updated for the roots of a linkset. // TODO: this will have to change when linksets are articulated. base.UpdateProperties(entprop); } /* else { // For debugging, report the movement of children DetailLog("{0},BSPrim.UpdateProperties,child,pos={1},orient={2},vel={3},accel={4},rotVel={5}", LocalID, entprop.Position, entprop.Rotation, entprop.Velocity, entprop.Acceleration, entprop.RotationalVelocity); } */ // The linkset might like to know about changing locations Linkset.UpdateProperties(UpdatedProperties.EntPropUpdates, this); }
private void PreUpdateProperty(ref EntityProperties entprop) { // A temporary kludge to suppress the rotational effects introduced on vehicles by Bullet // TODO: handle physics introduced by Bullet with computed vehicle physics. if (IsActive) { entprop.RotationalVelocity = Vector3.Zero; } }
// Initialization and simulation public abstract BulletWorld Initialize(Vector3 maxPosition, ConfigurationParameters parms, int maxCollisions, ref CollisionDesc[] collisionArray, int maxUpdates, ref EntityProperties[] updateArray );
protected void TriggerPreUpdatePropertyAction(ref EntityProperties entprop) { PreUpdatePropertyAction actions = OnPreUpdateProperty; if (actions != null) actions(ref entprop); }