// 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); }
// 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 (MainConsole.Instance.IsDebugEnabled) { MainConsole.Instance.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. 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 _position = entprop.Position; _orientation = entprop.Rotation; bool terseUpdate = false; if (entprop.Velocity != OMV.Vector3.Zero && entprop.Velocity.ApproxEquals(OMV.Vector3.Zero, 0.01f) && Velocity != OMV.Vector3.Zero) { entprop.Velocity = OMV.Vector3.Zero; entprop.Acceleration = OMV.Vector3.Zero; entprop.RotationalVelocity = OMV.Vector3.Zero; Velocity = RawVelocity = OMV.Vector3.Zero; ZeroMotion(true); terseUpdate = true; } // DEBUG DEBUG DEBUG -- smooth velocity changes a bit. The simulator seems to be // very sensitive to velocity changes. if (entprop.Velocity == OMV.Vector3.Zero || (VehicleType != 0 /*&& !entprop.Velocity.ApproxEquals(RawVelocity, 0.01f)*/) || !entprop.Velocity.ApproxEquals(RawVelocity, BSParam.UpdateVelocityChangeThreshold / 2f)) { terseUpdate = true; 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 = _position; entprop.Velocity = RawVelocity; entprop.RotationalVelocity = _rotationalVelocity; entprop.Acceleration = _acceleration; } OMV.Vector3 direction = OMV.Vector3.UnitX * _orientation; // 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; if (terseUpdate) base.RequestPhysicsterseUpdate(); /* 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); } */ }
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; } }
public override void UpdateProperties(EntityProperties entprop) { if (Linkset.IsRoot(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); }
// The physics engine says that properties have updated. Update same and inform // the world that things have changed. public override void UpdateProperties(EntityProperties entprop) { // Don't change position if standing on a stationary object. if (!IsStationary) _position = entprop.Position; _orientation = entprop.Rotation; if (entprop.Velocity != OMV.Vector3.Zero && entprop.Velocity.ApproxEquals(OMV.Vector3.Zero, 0.01f) && Velocity != OMV.Vector3.Zero) { entprop.Velocity = OMV.Vector3.Zero; entprop.Acceleration = OMV.Vector3.Zero; entprop.RotationalVelocity = OMV.Vector3.Zero; Velocity = OMV.Vector3.Zero; TriggerSignificantMovement(); TriggerMovementUpdate(); } if (!entprop.Velocity.ApproxEquals(RawVelocity, 0.4f)) { RawVelocity = entprop.Velocity; TriggerSignificantMovement(); TriggerMovementUpdate(); } _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, _position); entprop.Position = _position; } // 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. // base.RequestPhysicsterseUpdate(); DetailLog("{0},BSCharacter.UpdateProperties,call,pos={1},orient={2},vel={3},accel={4},rotVel={5}", LocalID, _position, _orientation, RawVelocity, _acceleration, _rotationalVelocity); }