public void EntityAddOrUpdate(object sender, ISceneEntity entity, UpdateFlags updateFlags, uint extraFlags) { const float TOLERANCE = 0.01f; const float SIGNIFICANT_MOVEMENT_SQ = 2f * 2f; bool isNew = false; #region Entity Creation if (m_sceneGraph.AddOrUpdate(entity)) { isNew = true; // If this is a scene presence, fire the callback for a new presence being added if (entity is IScenePresence) { IScenePresence presence = (IScenePresence)entity; m_log.Debug("Added scene presence " + presence.Name + " to scene " + this.Name); EventHandler <PresenceArgs> presenceCallback = OnPresenceAdd; if (presenceCallback != null) { presenceCallback(sender, new PresenceArgs { Presence = presence }); } } } #endregion Entity Creation #region Update Damping UpdateFlags unchangedFlags = 0; if (updateFlags.HasFlag(UpdateFlags.Position) && entity.RelativePosition.ApproxEquals(entity.LastRelativePosition, TOLERANCE)) { unchangedFlags |= UpdateFlags.Position; } if (updateFlags.HasFlag(UpdateFlags.Rotation) && entity.RelativeRotation.ApproxEquals(entity.LastRelativeRotation, TOLERANCE)) { unchangedFlags |= UpdateFlags.Rotation; } if (entity is IPhysical) { IPhysical physical = (IPhysical)entity; if (updateFlags.HasFlag(UpdateFlags.Acceleration) && physical.Acceleration == physical.LastAcceleration) { unchangedFlags |= UpdateFlags.Acceleration; } if (updateFlags.HasFlag(UpdateFlags.AngularVelocity) && physical.AngularVelocity == physical.LastAngularVelocity) { unchangedFlags |= UpdateFlags.AngularVelocity; } if (updateFlags.HasFlag(UpdateFlags.Velocity) && physical.Velocity == physical.LastVelocity) { unchangedFlags |= UpdateFlags.Velocity; } } if (updateFlags != UpdateFlags.FullUpdate) { updateFlags &= ~unchangedFlags; if (updateFlags == 0 && extraFlags == 0) { return; } } #endregion Update Damping // If this is a physical entity and the scale or shape changed, reset any cached mass calculations if (entity is IPhysical && (updateFlags.HasFlag(UpdateFlags.Scale) || updateFlags.HasFlag(UpdateFlags.Shape))) { ((IPhysical)entity).ResetMass(); } // Mark updated entities as modified if (!isNew) { entity.MarkAsModified(); } #region Callbacks // Fire the callback for an entity being added or updated EventHandler <EntityAddOrUpdateArgs> addUpdateCallback = OnEntityAddOrUpdate; if (addUpdateCallback != null) { addUpdateCallback(sender, new EntityAddOrUpdateArgs { Entity = entity, UpdateFlags = updateFlags, ExtraFlags = extraFlags, IsNew = isNew }); } // Check for significant movement Vector3 scenePosition = entity.ScenePosition; if (Vector3.DistanceSquared(entity.LastSignificantPosition, scenePosition) > SIGNIFICANT_MOVEMENT_SQ) { // Fire the significant movement callback EventHandler <EntitySignificantMovementArgs> sigMovementCallback = OnEntitySignificantMovement; if (sigMovementCallback != null) { sigMovementCallback(sender, new EntitySignificantMovementArgs { Entity = entity }); } // Update LastSignificantPosition after the callback entity.LastSignificantPosition = scenePosition; } #endregion Callbacks #region Update ISceneEntity.Last* Properties if (!unchangedFlags.HasFlag(UpdateFlags.Position)) { entity.LastRelativePosition = entity.RelativePosition; } if (!unchangedFlags.HasFlag(UpdateFlags.Rotation)) { entity.LastRelativeRotation = entity.RelativeRotation; } if (entity is IPhysical) { IPhysical physical = (IPhysical)entity; if (!unchangedFlags.HasFlag(UpdateFlags.Acceleration)) { physical.LastAcceleration = physical.Acceleration; } if (!unchangedFlags.HasFlag(UpdateFlags.AngularVelocity)) { physical.LastAngularVelocity = physical.AngularVelocity; } if (!unchangedFlags.HasFlag(UpdateFlags.Velocity)) { physical.LastVelocity = physical.Velocity; } } #endregion Update ISceneEntity.Last* Properties }