// Routine to send the collected collisions into the simulator. // Also handles removal of this from the collection of objects with collisions if // there are no collisions from this object. Mechanism is create one last // collision event to make collision_end work. // Called at taint time from within the Step() function thus no locking problems // with CollisionCollection and ObjectsWithNoMoreCollisions. // Return 'true' if there were some actual collisions passed up public virtual bool SendCollisions() { bool ret = true; // throttle the collisions to the number of milliseconds specified in the subscription int nowTime = PhysicsScene.SimulationNowTime; if (nowTime >= NextCollisionOkTime) { NextCollisionOkTime = nowTime + SubscribedEventsMs; // We are called if we previously had collisions. If there are no collisions // this time, send up one last empty event so OpenSim can sense collision end. if (CollisionCollection.Count == 0) { // If I have no collisions this time, remove me from the list of objects with collisions. ret = false; } // DetailLog("{0},{1}.SendCollisionUpdate,call,numCollisions={2}", LocalID, TypeName, CollisionCollection.Count); base.SendCollisionUpdate(CollisionCollection); // The collisionCollection structure is passed around in the simulator. // Make sure we don't have a handle to that one and that a new one is used for next time. CollisionCollection = new CollisionEventUpdate(); } return(ret); }
// Send the collected collisions into the simulator. // Called at taint time from within the Step() function thus no locking problems // with CollisionCollection and ObjectsWithNoMoreCollisions. // Called with BSScene.CollisionLock locked to protect the collision lists. // Return 'true' if there were some actual collisions passed up public virtual bool SendCollisions() { bool ret = true; // If no collisions this call but there were collisions last call, force the collision // event to be happen right now so quick collision_end. bool force = (CollisionCollection.Count == 0 && CollisionsLastReported.Count != 0); // throttle the collisions to the number of milliseconds specified in the subscription if (force || (PhysScene.SimulationNowTime >= NextCollisionOkTime)) { NextCollisionOkTime = PhysScene.SimulationNowTime + SubscribedEventsMs; // We are called if we previously had collisions. If there are no collisions // this time, send up one last empty event so OpenSim can sense collision end. if (CollisionCollection.Count == 0) { // If I have no collisions this time, remove me from the list of objects with collisions. ret = false; } DetailLog("{0},{1}.SendCollisionUpdate,call,numCollisions={2}", LocalID, TypeName, CollisionCollection.Count); base.SendCollisionUpdate(CollisionCollection); // Remember the collisions from this tick for some collision specific processing. CollisionsLastReported = CollisionCollection; // The CollisionCollection instance is passed around in the simulator. // Make sure we don't have a handle to that one and that a new one is used for next time. // This fixes an interesting 'gotcha'. If we call CollisionCollection.Clear() here, // a race condition is created for the other users of this instance. CollisionCollection = new CollisionEventUpdate(); } return(ret); }
public void Collide(uint collidingWith, ActorTypes type, Vector3 contactPoint, Vector3 contactNormal, float pentrationDepth) { // m_log.DebugFormat("{0}: Collide: ms={1}, id={2}, with={3}", LogHeader, _subscribedEventsMs, LocalID, collidingWith); // The following makes IsColliding() and IsCollidingGround() work _collidingStep = _scene.SimulationStep; if (collidingWith == BSScene.TERRAIN_ID || collidingWith == BSScene.GROUNDPLANE_ID) { _collidingGroundStep = _scene.SimulationStep; } // throttle collisions to the rate specified in the subscription if (_subscribedEventsMs == 0) { return; // don't want collisions } int nowTime = _scene.SimulationNowTime; if (nowTime < (_lastCollisionTime + _subscribedEventsMs)) { return; } _lastCollisionTime = nowTime; Dictionary <uint, ContactPoint> contactPoints = new Dictionary <uint, ContactPoint>(); contactPoints.Add(collidingWith, new ContactPoint(contactPoint, contactNormal, pentrationDepth)); CollisionEventUpdate args = new CollisionEventUpdate(contactPoints); base.SendCollisionUpdate(args); }
public void AddCollision(uint collideWith, ContactPoint contact) { if (CollisionEventsThisFrame == null) { CollisionEventsThisFrame = new CollisionEventUpdate(); } CollisionEventsThisFrame.addCollider(collideWith, contact); }
public void SendCollisions() { if (m_eventsubscription > 0) { base.SendCollisionUpdate(CollisionEventsThisFrame); CollisionEventsThisFrame = new CollisionEventUpdate(); } }
public void PhysicsActor_OnCollisionUpdate(EventArgs e) { if (HasLeftCombat) { return; } if (e == null) { return; } CollisionEventUpdate collisionData = (CollisionEventUpdate)e; Dictionary <uint, ContactPoint> coldata = collisionData.m_objCollisionList; UUID killerObj = UUID.Zero; foreach (uint localid in coldata.Keys) { ISceneChildEntity part = m_part.ParentGroup.Scene.GetSceneObjectPart(localid); if (part != null && part.ParentEntity.Damage != -1.0f) { if (part.ParentEntity.Damage > MaximumDamageToInflict) { part.ParentEntity.Damage = MaximumDamageToInflict; } Health -= part.ParentEntity.Damage; if (Health <= 0.0f) { killerObj = part.UUID; } } else { float Z = Math.Abs(m_part.Velocity.Z); if (coldata[localid].PenetrationDepth >= 0.05f) { Health -= coldata[localid].PenetrationDepth * Z; } } //Regenerate health (this is approx 1 sec) if ((int)(Health + 0.0625) <= m_combatModule.MaximumHealth) { Health += 0.0625f; } if (Health > m_combatModule.MaximumHealth) { Health = m_combatModule.MaximumHealth; } } if (Health <= 0) { Die(killerObj); } }
/// <summary> /// Sends collision events concerning this object to the simulator. /// </summary> /// <returns>Whether any collisions were sent to the simulator</returns> public virtual bool SendCollisions() { bool sendEndEvent; bool moreEvents = true; // Check to see if this object is supposed to be sending out // collision events if (SubscribedEventInterval <= 0) { // This means that events should not be sent out, so exit return(false); } // Check to see if there are no more collisions, but collisions // were sent out last call; if so, go ahead and send an empty // collision to signify the end of the collisions sendEndEvent = false; if (Collisions.Count == 0 && CollisionsLastReported.Count != 0) { sendEndEvent = true; } // Check to see if an end event needs to be sent or if the minimum // event interval has passed if (sendEndEvent || ParentScene.CurrentSimulationTime >= NextCollisionEventTime) { // Calculate the time for sending out the next collision update NextCollisionEventTime = ParentScene.CurrentSimulationTime + SubscribedEventInterval; // Send the collision event base.SendCollisionUpdate(Collisions); // Check to see if there are no more collision events to send if (Collisions.Count == 0) { // Flag that there are no more collision events to send moreEvents = false; } // Store the collisions reported in this update for later // reference CollisionsLastReported = Collisions; // Create a new event update that will accrue future collisions Collisions = new CollisionEventUpdate(); } // Return whether this object has more collision events pending return(moreEvents); }
/// <summary> /// Constructor. /// </summary> /// <param name="parentScene">The scene to which this object /// belongs</param> /// <param name="localID">The unique identifier of the object</param> /// <param name="name">The name of the object</param> /// <param name="typeName">The type of the object</param> /// <param name="config">The configuration used to initialize this /// object</param> protected RemotePhysicsObject(RemotePhysicsScene parentScene, uint localID, String name, String typeName, RemotePhysicsConfiguration config) { // Initialize the parent physics scene ParentScene = parentScene; // Indicate that this object has not been fully initialized IsInitialized = false; // Initialize the handle to the configuration that will be used // initialize other properties ParentConfiguration = config; // Initialize the local ID of this object LocalID = localID; // Initialize the name of this physics object // Usually this is the same name as the OpenSim object Name = name; // Initialize the type of this object in string form TypeName = typeName; // Initialize the gravity modifier to be 1.0, so that the // gravity of the scene will be unmodified when it affects // this object GravModifier = 1.0f; // Initialize the gravity vector Gravity = new OpenMetaverse.Vector3(0.0f, 0.0f, config.Gravity); // Indicate that the object is not hovering HoverActive = false; // Create the list of pending and sent collisions Collisions = new CollisionEventUpdate(); CollisionsLastReported = Collisions; // Initialize the collision steps to be invalid steps, since no // collision has occurred yet GroundCollisionStep = RemotePhysicsScene.InvalidStep; ObjectCollisionStep = RemotePhysicsScene.InvalidStep; LastCollisionStep = RemotePhysicsScene.InvalidStep; // No collisions have occurred, so start the collision count at 0 NumCollisions = 0; // Initialize the object that will ensure the thread safety of the // collision step data m_collisionStepLock = new Object(); }
public void SendCollisions() { if (m_eventsubscription >= m_requestedUpdateFrequency) { if (CollisionEventsThisFrame != null) { base.SendCollisionUpdate(CollisionEventsThisFrame); } CollisionEventsThisFrame = new CollisionEventUpdate(); m_eventsubscription = 0; } return; }
protected void BaseInitialize(BSScene parentScene, uint localID, string name, string typeName) { PhysicsScene = parentScene; LocalID = localID; PhysObjectName = name; TypeName = typeName; Linkset = new BSLinkset(PhysicsScene, this); CollisionCollection = new CollisionEventUpdate(); SubscribedEventsMs = 0; CollidingStep = 0; CollidingGroundStep = 0; }
protected BSPhysObject(BSScene parentScene, uint localID, string name, string typeName) { IsInitialized = false; PhysScene = parentScene; LocalID = localID; PhysObjectName = name; Name = name; // PhysicsActor also has the name of the object. Someday consolidate. TypeName = typeName; // The collection of things that push me around PhysicalActors = new BSActorCollection(PhysScene); // Initialize variables kept in base. GravModifier = 1.0f; Gravity = new OMV.Vector3(0f, 0f, BSParam.Gravity); HoverActive = false; // We don't have any physical representation yet. PhysBody = new BulletBody(localID); PhysShape = new BSShapeNull(); UserSetCenterOfMassDisplacement = null; PrimAssetState = PrimAssetCondition.Unknown; // Default material type. Also sets Friction, Restitution and Density. SetMaterial((int)MaterialAttributes.Material.Wood); CollisionCollection = new CollisionEventUpdate(); CollisionsLastReported = CollisionCollection; CollisionsLastTick = new CollisionEventUpdate(); CollisionsLastTickStep = -1; SubscribedEventsMs = 0; // Crazy values that will never be true CollidingStep = BSScene.NotASimulationStep; CollidingGroundStep = BSScene.NotASimulationStep; CollisionAccumulation = BSScene.NotASimulationStep; ColliderIsMoving = false; CollisionScore = 0; // All axis free. LockedLinearAxis = LockedAxisFree; LockedAngularAxis = LockedAxisFree; }
public void PhysicsActor_OnCollisionUpdate(EventArgs e) { /*if (HasLeftCombat) * return; */ if (e == null) { return; } CollisionEventUpdate collisionData = (CollisionEventUpdate)e; /*Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList; * * UUID killerObj = UUID.Zero; * foreach (uint localid in coldata.Keys) * { * ISceneChildEntity part = m_part.Scene.GetSceneObjectPart(localid); * if (part != null && part.ParentEntity.Damage != -1.0f) * { * if (part.ParentEntity.Damage > MaximumDamageToInflict) * part.ParentEntity.Damage = MaximumDamageToInflict; * * Health -= part.ParentEntity.Damage; * if (Health <= 0.0f) * killerObj = part.UUID; * } * else * { * float Z = Math.Abs(m_part.Velocity.Z); * if (coldata[localid].PenetrationDepth >= 0.05f) * Health -= coldata[localid].PenetrationDepth*Z; * } * * //Regenerate health (this is approx 1 sec) * if ((int) (Health + 0.0625) <= m_combatModule.MaximumHealth) * Health += 0.0625f; * * if (Health > m_combatModule.MaximumHealth) * Health = m_combatModule.MaximumHealth; * } * if (Health <= 0) * { * Die(killerObj); * }*/ }
public virtual bool Collide(uint collidingWith, BSPhysObject collidee, OMV.Vector3 contactPoint, OMV.Vector3 contactNormal, float pentrationDepth) { bool ret = false; // The following lines make IsColliding(), CollidingGround() and CollidingObj work CollidingStep = PhysScene.SimulationStep; if (collidingWith <= PhysScene.TerrainManager.HighestTerrainID) { CollidingGroundStep = PhysScene.SimulationStep; } else { CollidingObjectStep = PhysScene.SimulationStep; } CollisionAccumulation++; // For movement tests, remember if we are colliding with an object that is moving. ColliderIsMoving = collidee != null ? (collidee.RawVelocity != OMV.Vector3.Zero) : false; ColliderIsVolumeDetect = collidee != null ? (collidee.IsVolumeDetect) : false; // Make a collection of the collisions that happened the last simulation tick. // This is different than the collection created for sending up to the simulator as it is cleared every tick. if (CollisionsLastTickStep != PhysScene.SimulationStep) { CollisionsLastTick = new CollisionEventUpdate(); CollisionsLastTickStep = PhysScene.SimulationStep; } CollisionsLastTick.AddCollider(collidingWith, new ContactPoint(contactPoint, contactNormal, pentrationDepth)); // If someone has subscribed for collision events log the collision so it will be reported up if (SubscribedEvents()) { lock (PhysScene.CollisionLock) { CollisionCollection.AddCollider(collidingWith, new ContactPoint(contactPoint, contactNormal, pentrationDepth)); } DetailLog("{0},{1}.Collision.AddCollider,call,with={2},point={3},normal={4},depth={5},colliderMoving={6}", LocalID, TypeName, collidingWith, contactPoint, contactNormal, pentrationDepth, ColliderIsMoving); ret = true; } return(ret); }
protected BSPhysObject(BSScene parentScene, uint localID, string name, string typeName) { PhysicsScene = parentScene; LocalID = localID; PhysObjectName = name; TypeName = typeName; Linkset = BSLinkset.Factory(PhysicsScene, this); LastAssetBuildFailed = false; // Default material type Material = MaterialAttributes.Material.Wood; CollisionCollection = new CollisionEventUpdate(); SubscribedEventsMs = 0; CollidingStep = 0; CollidingGroundStep = 0; }
protected BSPhysObject(BSScene parentScene, uint localID, string name, string typeName) { PhysicsScene = parentScene; LocalID = localID; PhysObjectName = name; Name = name; // PhysicsActor also has the name of the object. Someday consolidate. TypeName = typeName; // Oddity if object is destroyed and recreated very quickly it could still have the old body. if (!PhysBody.HasPhysicalBody) { PhysBody = new BulletBody(localID); } // The collection of things that push me around PhysicalActors = new BSActorCollection(PhysicsScene); // Initialize variables kept in base. GravityMultiplier = 1.0f; Gravity = new OMV.Vector3(0f, 0f, BSParam.Gravity); PrimAssetState = PrimAssetCondition.Unknown; // Default material type. Also sets Friction, Restitution and Density. SetMaterial((int)MaterialAttributes.Material.Wood); CollisionCollection = new CollisionEventUpdate(); CollisionsLastTick = CollisionCollection; SubscribedEventsMs = 0; CollidingStep = 0; TrueCollidingStep = 0; CollisionAccumulation = 0; ColliderIsMoving = false; CollisionScore = 0; // All axis free. LockedLinearAxis = LockedAxisFree; LockedAngularAxis = LockedAxisFree; }
protected BSPhysObject(BSScene parentScene, uint localID, string name, string typeName) { PhysicsScene = parentScene; LocalID = localID; PhysObjectName = name; TypeName = typeName; // We don't have any physical representation yet. PhysBody = new BulletBody(localID); PhysShape = new BulletShape(); // A linkset of just me Linkset = BSLinkset.Factory(PhysicsScene, this); LastAssetBuildFailed = false; // Default material type Material = MaterialAttributes.Material.Wood; CollisionCollection = new CollisionEventUpdate(); SubscribedEventsMs = 0; CollidingStep = 0; CollidingGroundStep = 0; }
public void AddCollisionEvent(uint CollidedWith, ContactPoint contact) { if (CollisionEventsThisFrame == null) CollisionEventsThisFrame = new CollisionEventUpdate(); CollisionEventsThisFrame.addCollider(CollidedWith, contact); }
public override void AddCollisionEvent(uint CollidedWith, ContactPoint contact) { if (CollisionEventsThisFrame == null) CollisionEventsThisFrame = new CollisionEventUpdate(); lock (CollisionEventsThisFrame) { CollisionEventsThisFrame.AddCollider(CollidedWith, contact); _parent_scene.AddCollisionEventReporting(this); } }
private void HandleCollisionEnded(CollisionEventUpdate update) { this.HandleGenericCollisionEvent(update, Scenes.ScriptEvents.collision_end, m_parentGroup.Scene.EventManager.TriggerScriptCollidingEnd, false); }
private void HandleLandCollisionBegan(CollisionEventUpdate update) { HandleGenericLandCollisionEvent(update, Scenes.ScriptEvents.land_collision_start, m_parentGroup.Scene.EventManager.TriggerScriptLandCollidingStart, true); }
private void HandleGenericCollisionEvent(CollisionEventUpdate update, Scenes.ScriptEvents eventType, EventManager.ScriptColliding callback, bool playSound) { // play the sound. if (playSound && CollisionSound != UUID.Zero && eventType == ScriptEvents.collision_start && CollisionSoundVolume > 0.0f) { SendSound(CollisionSound.ToString(), CollisionSoundVolume, true, (byte)0); } SceneObjectPart handlingPart = FindCollisionHandlingPart(eventType); if (handlingPart == null) return; //no one to handle the event ColliderArgs colliderArgs = new ColliderArgs(); List<DetectedObject> colliding = new List<DetectedObject>(); bool otherIsPrim; if (update.Type == CollisionEventUpdateType.CollisionBegan || update.Type == CollisionEventUpdateType.CollisionContinues || update.Type == CollisionEventUpdateType.BulkCollisionsContinue || update.Type == CollisionEventUpdateType.CollisionEnded) { otherIsPrim = true; } else { otherIsPrim = false; } if (update.BulkCollisionData == null) { TryExtractCollider(update.OtherColliderLocalId, colliding, otherIsPrim, update.OtherColliderUUID); } else { foreach (uint localId in update.BulkCollisionData) { TryExtractCollider(localId, colliding, otherIsPrim, update.OtherColliderUUID); } } if (colliding.Count > 0) { colliderArgs.Colliders = colliding; // always running this check because if the user deletes the object it would return a null reference. if (m_parentGroup == null) return; if (m_parentGroup.Scene == null) return; callback(handlingPart.LocalId, colliderArgs); } }
// I've collided with something public void Collide(uint collidingWith, ActorTypes type, OMV.Vector3 contactPoint, OMV.Vector3 contactNormal, float pentrationDepth) { // m_log.DebugFormat("{0}: Collide: ms={1}, id={2}, with={3}", LogHeader, _subscribedEventsMs, LocalID, collidingWith); // The following lines make IsColliding() and IsCollidingGround() work _collidingStep = _scene.SimulationStep; if (collidingWith == BSScene.TERRAIN_ID || collidingWith == BSScene.GROUNDPLANE_ID) { _collidingGroundStep = _scene.SimulationStep; } if (_subscribedEventsMs == 0) return; // nothing in the object is waiting for collision events // throttle the collisions to the number of milliseconds specified in the subscription int nowTime = _scene.SimulationNowTime; if (nowTime < (_lastCollisionTime + _subscribedEventsMs)) return; _lastCollisionTime = nowTime; // create the event for the collision Dictionary<uint, ContactPoint> contactPoints = new Dictionary<uint, ContactPoint>(); contactPoints.Add(collidingWith, new ContactPoint(contactPoint, contactNormal, pentrationDepth)); CollisionEventUpdate args = new CollisionEventUpdate(contactPoints); base.SendCollisionUpdate(args); }
public override void SubscribeEvents(int ms) { m_eventsubscription = ms; m_cureventsubscription = 0; if (CollisionEventsThisFrame == null) CollisionEventsThisFrame = new CollisionEventUpdate(); SentEmptyCollisionsEvent = false; }
public virtual bool Collide(uint collidingWith, BSPhysObject collidee, OMV.Vector3 contactPoint, OMV.Vector3 contactNormal, float pentrationDepth) { bool ret = false; // The following lines make IsColliding(), CollidingGround() and CollidingObj work CollidingStep = PhysScene.SimulationStep; if (collidingWith <= PhysScene.TerrainManager.HighestTerrainID) { CollidingGroundStep = PhysScene.SimulationStep; } else { CollidingObjectStep = PhysScene.SimulationStep; } CollisionAccumulation++; // For movement tests, remember if we are colliding with an object that is moving. ColliderIsMoving = collidee != null ? (collidee.RawVelocity != OMV.Vector3.Zero) : false; ColliderIsVolumeDetect = collidee != null ? (collidee.IsVolumeDetect) : false; // Make a collection of the collisions that happened the last simulation tick. // This is different than the collection created for sending up to the simulator as it is cleared every tick. if (CollisionsLastTickStep != PhysScene.SimulationStep) { CollisionsLastTick = new CollisionEventUpdate(); CollisionsLastTickStep = PhysScene.SimulationStep; } CollisionsLastTick.AddCollider(collidingWith, new ContactPoint(contactPoint, contactNormal, pentrationDepth)); // If someone has subscribed for collision events log the collision so it will be reported up if (SubscribedEvents()) { lock (PhysScene.CollisionLock) { CollisionCollection.AddCollider(collidingWith, new ContactPoint(contactPoint, contactNormal, pentrationDepth)); } DetailLog("{0},{1}.Collison.AddCollider,call,with={2},point={3},normal={4},depth={5},colliderMoving={6}", LocalID, TypeName, collidingWith, contactPoint, contactNormal, pentrationDepth, ColliderIsMoving); ret = true; } return ret; }
public void PhysicsActor_OnCollisionUpdate(EventArgs e) { if (m_SP == null || m_SP.Invulnerable) { return; } if (HasLeftCombat) { return; } if (e == null) { return; } CollisionEventUpdate collisionData = (CollisionEventUpdate)e; Dictionary <uint, ContactPoint> coldata = collisionData.m_objCollisionList; float starthealth = Health; uint killerObj = 0; foreach (uint localid in coldata.Keys) { ISceneChildEntity part = m_SP.Scene.GetSceneObjectPart(localid); if (part != null) { if (part.ParentEntity.Damage != -1.0f) { continue; } IScenePresence otherAvatar = m_SP.Scene.GetScenePresence(part.OwnerID); if (otherAvatar != null) // If the avatar is null, the person is not inworld, and not on a team { if (otherAvatar.RequestModuleInterface <ICombatPresence>().HasLeftCombat) { //If they have left combat, do not let them cause any damage. continue; } } if (part.ParentEntity.Damage > MaximumDamageToInflict) { part.ParentEntity.Damage = MaximumDamageToInflict; } if (AllowTeams) { if (otherAvatar != null) // If the avatar is null, the person is not inworld, and not on a team { ICombatPresence OtherAvatarCP = otherAvatar.RequestModuleInterface <ICombatPresence>(); if (OtherAvatarCP.Team == Team) { float Hits = 0; if (!TeamHits.TryGetValue(otherAvatar.UUID, out Hits)) { Hits = 0; } Hits++; if (SendTeamKillerInfo && Hits == TeamHitsBeforeSend) { otherAvatar.ControllingClient.SendAlertMessage("You have shot too many teammates and " + DamageToTeamKillers + " health has been taken from you!"); OtherAvatarCP.Health -= DamageToTeamKillers; otherAvatar.ControllingClient.SendHealth(OtherAvatarCP.Health); if (OtherAvatarCP.Health <= 0) { KillAvatar(otherAvatar.LocalId, true); } Hits = 0; } TeamHits[otherAvatar.UUID] = Hits; if (AllowTeamKilling) //Green light on team killing { Health -= part.ParentEntity.Damage; } } else //Object, hit em { Health -= part.ParentEntity.Damage; } } else //Other team, hit em { Health -= part.ParentEntity.Damage; } } else //Free for all, hit em { Health -= part.ParentEntity.Damage; } } else { float Z = m_SP.Velocity.Length() / 20; if (coldata[localid].PenetrationDepth >= 0.05f && Math.Abs(m_SP.Velocity.X) < 1 && Math.Abs(m_SP.Velocity.Y) < 1) { Z = Math.Min(Z, 1.5f); float damage = Math.Min(coldata[localid].PenetrationDepth, 15f); Health -= damage * Z; } } if (Health > m_combatModule.MaximumHealth) { Health = m_combatModule.MaximumHealth; } if (Health <= 0.0f) { if (localid != 0) { killerObj = localid; } } //m_log.Debug("[AVATAR]: Collision with localid: " + localid.ToString() + " at depth: " + coldata[localid].ToString()); } if (starthealth != Health) { m_SP.ControllingClient.SendHealth(Health); } if (Health <= 0) { KillAvatar(killerObj, true); } }
// Routine to send the collected collisions into the simulator. // Also handles removal of this from the collection of objects with collisions if // there are no collisions from this object. Mechanism is create one last // collision event to make collision_end work. // Called at taint time from within the Step() function thus no locking problems // with CollisionCollection and ObjectsWithNoMoreCollisions. // Return 'true' if there were some actual collisions passed up public virtual bool SendCollisions() { bool ret = true; // throttle the collisions to the number of milliseconds specified in the subscription int nowTime = PhysicsScene.SimulationNowTime; if (nowTime >= NextCollisionOkTime) { NextCollisionOkTime = nowTime + SubscribedEventsMs; // We are called if we previously had collisions. If there are no collisions // this time, send up one last empty event so OpenSim can sense collision end. if (CollisionCollection.Count == 0) { // If I have no collisions this time, remove me from the list of objects with collisions. ret = false; } // DetailLog("{0},{1}.SendCollisionUpdate,call,numCollisions={2}", LocalID, TypeName, CollisionCollection.Count); base.SendCollisionUpdate(CollisionCollection); // The collisionCollection structure is passed around in the simulator. // Make sure we don't have a handle to that one and that a new one is used for next time. CollisionCollection = new CollisionEventUpdate(); } return ret; }
public void SendCollisions() { if (CollisionEventsThisFrame == null) return; base.SendCollisionUpdate(CollisionEventsThisFrame); if (CollisionEventsThisFrame.m_objCollisionList.Count == 0) CollisionEventsThisFrame = null; else CollisionEventsThisFrame = new CollisionEventUpdate(); }
protected BSPhysObject(BSScene parentScene, uint localID, string name, string typeName) { PhysicsScene = parentScene; LocalID = localID; PhysObjectName = name; Name = name; // PhysicsActor also has the name of the object. Someday consolidate. TypeName = typeName; // Initialize variables kept in base. GravModifier = 1.0f; Gravity = new OMV.Vector3(0f, 0f, BSParam.Gravity); // We don't have any physical representation yet. PhysBody = new BulletBody(localID); PhysShape = new BulletShape(); LastAssetBuildFailed = false; // Default material type. Also sets Friction, Restitution and Density. SetMaterial((int)MaterialAttributes.Material.Wood); CollisionCollection = new CollisionEventUpdate(); CollisionsLastTick = CollisionCollection; SubscribedEventsMs = 0; CollidingStep = 0; CollidingGroundStep = 0; CollisionAccumulation = 0; ColliderIsMoving = false; CollisionScore = 0; // All axis free. LockedAxis = LockedAxisFree; }
private void HandleLandCollisionEnded(CollisionEventUpdate update) { HandleGenericLandCollisionEvent(update, Scenes.ScriptEvents.land_collision_end, m_parentGroup.Scene.EventManager.TriggerScriptLandCollidingEnd, false); }
// Send the collected collisions into the simulator. // Called at taint time from within the Step() function thus no locking problems // with CollisionCollection and ObjectsWithNoMoreCollisions. // Return 'true' if there were some actual collisions passed up public virtual bool SendCollisions() { bool ret = true; // If the 'no collision' call, force it to happen right now so quick collision_end bool force = (CollisionCollection.Count == 0); // throttle the collisions to the number of milliseconds specified in the subscription if (force || (PhysicsScene.SimulationNowTime >= NextCollisionOkTime)) { NextCollisionOkTime = PhysicsScene.SimulationNowTime + SubscribedEventsMs; // We are called if we previously had collisions. If there are no collisions // this time, send up one last empty event so OpenSim can sense collision end. if (CollisionCollection.Count == 0) { // If I have no collisions this time, remove me from the list of objects with collisions. ret = false; } // DetailLog("{0},{1}.SendCollisionUpdate,call,numCollisions={2}", LocalID, TypeName, CollisionCollection.Count); base.SendCollisionUpdate(CollisionCollection); // The CollisionCollection instance is passed around in the simulator. // Make sure we don't have a handle to that one and that a new one is used for next time. // This fixes an interesting 'gotcha'. If we call CollisionCollection.Clear() here, // a race condition is created for the other users of this instance. CollisionCollection = new CollisionEventUpdate(); } return ret; }
private void HandleGenericLandCollisionEvent(CollisionEventUpdate update, Scenes.ScriptEvents eventType, EventManager.ScriptLandColliding callback, bool playSound) { // play the sound. if (playSound && CollisionSound != UUID.Zero && eventType == ScriptEvents.collision_start && CollisionSoundVolume > 0.0f) { SendSound(CollisionSound, CollisionSoundVolume, (byte)SoundFlags.None, true); } SceneObjectPart handlingPart = FindCollisionHandlingPart(eventType); if (handlingPart == null) return; //no one to handle the event if (m_parentGroup == null) return; if (m_parentGroup.Scene == null) return; callback(handlingPart.LocalId, update.CollisionLocation); }
public void AddCollisionEvent(uint CollidedWith, float depth) { if (CollisionEventsThisFrame == null) CollisionEventsThisFrame = new CollisionEventUpdate(); CollisionEventsThisFrame.addCollider(CollidedWith,depth); }
private void HandleCollisionBegan(CollisionEventUpdate update) { this.HandleGenericCollisionEvent(update, Scenes.ScriptEvents.collision_start, m_parentGroup.Scene.EventManager.TriggerScriptCollidingStart, true); }
// The simulation step is telling this object about a collision. // I'm the 'collider', the thing I'm colliding with is the 'collidee'. // Return 'true' if a collision was processed and should be sent up. // Return 'false' if this object is not enabled/subscribed/appropriate for or has already seen this collision. // Called at taint time from within the Step() function public virtual bool Collide(BSPhysObject collidee, OMV.Vector3 contactPoint, OMV.Vector3 contactNormal, float pentrationDepth) { bool ret = false; // if 'collidee' is null, that means it is terrain uint collideeLocalID = (collidee == null) ? BSScene.TERRAIN_ID : collidee.LocalID; // All terrain goes by the TERRAIN_ID id when passed up as a collision if (collideeLocalID <= PhysScene.TerrainManager.HighestTerrainID) { collideeLocalID = BSScene.TERRAIN_ID; } // The following lines make IsColliding(), CollidingGround() and CollidingObj work CollidingStep = PhysScene.SimulationStep; if (collideeLocalID == BSScene.TERRAIN_ID) { CollidingGroundStep = PhysScene.SimulationStep; } else { CollidingObjectStep = PhysScene.SimulationStep; } CollisionAccumulation++; // For movement tests, if the collider is me, remember if we are colliding with an object that is moving. // Here the 'collider'/'collidee' thing gets messed up. In the larger context, when something is checking // if the thing it is colliding with is moving, for instance, it asks if the its collider is moving. ColliderIsMoving = collidee != null ? (collidee.RawVelocity != OMV.Vector3.Zero || collidee.RotationalVelocity != OMV.Vector3.Zero) : false; ColliderIsVolumeDetect = collidee != null ? (collidee.IsVolumeDetect) : false; // Make a collection of the collisions that happened the last simulation tick. // This is different than the collection created for sending up to the simulator as it is cleared every tick. if (CollisionsLastTickStep != PhysScene.SimulationStep) { CollisionsLastTick = new CollisionEventUpdate(); CollisionsLastTickStep = PhysScene.SimulationStep; } CollisionsLastTick.AddCollider(collideeLocalID, new ContactPoint(contactPoint, contactNormal, pentrationDepth)); // If someone has subscribed for collision events log the collision so it will be reported up if (SubscribedEvents()) { ContactPoint newContact = new ContactPoint(contactPoint, contactNormal, pentrationDepth); // Collision sound requires a velocity to know it should happen. This is a lot of computation for a little used feature. OMV.Vector3 relvel = OMV.Vector3.Zero; if (IsPhysical) { relvel = RawVelocity; } if (collidee != null && collidee.IsPhysical) { relvel -= collidee.RawVelocity; } newContact.RelativeSpeed = -OMV.Vector3.Dot(relvel, contactNormal); // DetailLog("{0},{1}.Collision.AddCollider,vel={2},contee.vel={3},relvel={4},relspeed={5}", // LocalID, TypeName, RawVelocity, (collidee == null ? OMV.Vector3.Zero : collidee.RawVelocity), relvel, newContact.RelativeSpeed); lock (PhysScene.CollisionLock) { CollisionCollection.AddCollider(collideeLocalID, newContact); } DetailLog("{0},{1}.Collision.AddCollider,call,with={2},point={3},normal={4},depth={5},speed={6},colliderMoving={7}", LocalID, TypeName, collideeLocalID, contactPoint, contactNormal, pentrationDepth, newContact.RelativeSpeed, ColliderIsMoving); ret = true; } return(ret); }
private void HandleBulkCollisionsContinue(CollisionEventUpdate update) { HandleGenericCollisionEvent(update, Scenes.ScriptEvents.collision, m_parentGroup.Scene.EventManager.TriggerScriptColliding, false); }
public override void AddCollisionEvent (uint CollidedWith, ContactPoint contact) { if (base.SubscribedToCollisions () && SubscribedEvents())//If we don't have anything that we are going to trigger, don't even add { if (CollisionEventsThisFrame == null) CollisionEventsThisFrame = new CollisionEventUpdate (); CollisionEventsThisFrame.addCollider (CollidedWith, contact); } }
public override void SendCollisions () { if (CollisionEventsThisFrame == null || m_frozen)//No collisions or frozen, don't mess with it return; base.SendCollisionUpdate (CollisionEventsThisFrame); if (CollisionEventsThisFrame.m_objCollisionList.Count == 0) CollisionEventsThisFrame = null; else CollisionEventsThisFrame = new CollisionEventUpdate (); }
private void ReportContinuingCollisions() { if (_touchCounts.IsValueCreated && _touchCounts.Value.Count > 0) { List<uint> continuingList = new List<uint>(_touchCounts.Value.Count); foreach (PhysxPrim prim in _touchCounts.Value.Keys) { if (this.GroupVelocity != OpenMetaverse.Vector3.Zero || prim._velocity != OpenMetaverse.Vector3.Zero) { continuingList.Add(prim._localId); } } if (continuingList.Count > 0) { CollisionEventUpdate upd = new CollisionEventUpdate { Type = CollisionEventUpdateType.BulkCollisionsContinue, BulkCollisionData = continuingList }; SendCollisionUpdate(upd); } } if (_groundTouchCounts > 0 && this.GroupVelocity != OpenMetaverse.Vector3.Zero) { OpenMetaverse.Vector3 currentLoc = DecomposeGroupPosition(); SendCollisionUpdate(new CollisionEventUpdate { Type = CollisionEventUpdateType.LandCollisionContinues, CollisionLocation = currentLoc}); } if (_avatarTouchCounts.IsValueCreated && _avatarTouchCounts.Value.Count > 0) { List<uint> continuingList = new List<uint>(_avatarTouchCounts.Value.Count); foreach (PhysxCharacter avatar in _avatarTouchCounts.Value.Keys) { continuingList.Add(avatar.LocalID); } if (continuingList.Count > 0) { CollisionEventUpdate upd = new CollisionEventUpdate { Type = CollisionEventUpdateType.BulkAvatarCollisionsContinue, BulkCollisionData = continuingList }; SendCollisionUpdate(upd); } } }
public override void UnSubscribeEvents() { if (CollisionEventsThisFrame != null) { lock (CollisionEventsThisFrame) { CollisionEventsThisFrame.Clear(); CollisionEventsThisFrame = null; } } m_eventsubscription = 0; }
public void Collide(uint collidingWith, ActorTypes type, Vector3 contactPoint, Vector3 contactNormal, float pentrationDepth) { // m_log.DebugFormat("{0}: Collide: ms={1}, id={2}, with={3}", LogHeader, _subscribedEventsMs, LocalID, collidingWith); // The following makes IsColliding() and IsCollidingGround() work _collidingStep = _scene.SimulationStep; if (collidingWith == BSScene.TERRAIN_ID || collidingWith == BSScene.GROUNDPLANE_ID) { _collidingGroundStep = _scene.SimulationStep; } // throttle collisions to the rate specified in the subscription if (_subscribedEventsMs == 0) return; // don't want collisions int nowTime = _scene.SimulationNowTime; if (nowTime < (_lastCollisionTime + _subscribedEventsMs)) return; _lastCollisionTime = nowTime; Dictionary<uint, ContactPoint> contactPoints = new Dictionary<uint, ContactPoint>(); contactPoints.Add(collidingWith, new ContactPoint(contactPoint, contactNormal, pentrationDepth)); CollisionEventUpdate args = new CollisionEventUpdate(LocalID, (int)type, 1, contactPoints); base.SendCollisionUpdate(args); }
public void PhysicsActor_OnCollisionUpdate(EventArgs e) { if (m_SP == null || m_SP.Scene == null || m_SP.Invulnerable || HasLeftCombat || e == null) { return; } CollisionEventUpdate collisionData = (CollisionEventUpdate)e; Dictionary <uint, ContactPoint> coldata = collisionData.GetCollisionEvents(); float starthealth = Health; IScenePresence killingAvatar = null; foreach (uint localid in coldata.Keys) { ISceneChildEntity part = m_SP.Scene.GetSceneObjectPart(localid); IScenePresence otherAvatar = null; if (part != null && part.ParentEntity.Damage > 0) { otherAvatar = m_SP.Scene.GetScenePresence(part.OwnerID); ICombatPresence OtherAvatarCP = otherAvatar == null ? null : otherAvatar.RequestModuleInterface <ICombatPresence> (); if (OtherAvatarCP != null && OtherAvatarCP.HasLeftCombat) { // If the avatar is null, the person is not inworld, and not on a team //If they have left combat, do not let them cause any damage. continue; } //Check max damage to inflict if (part.ParentEntity.Damage > m_combatModule.MaximumDamageToInflict) { part.ParentEntity.Damage = m_combatModule.MaximumDamageToInflict; } // If the avatar is null, the person is not inworld, and not on a team if (m_combatModule.AllowTeams && OtherAvatarCP != null && otherAvatar.UUID != m_SP.UUID && OtherAvatarCP.Team == Team) { float Hits = 0; if (!TeamHits.TryGetValue(otherAvatar.UUID, out Hits)) { Hits = 0; } Hits++; if (m_combatModule.SendTeamKillerInfo && Hits == m_combatModule.TeamHitsBeforeSend) { otherAvatar.ControllingClient.SendAlertMessage("You have shot too many teammates and " + m_combatModule.DamageToTeamKillers + " health has been taken from you!"); OtherAvatarCP.IncurDamage(null, m_combatModule.DamageToTeamKillers); Hits = 0; } TeamHits [otherAvatar.UUID] = Hits; if (m_combatModule.AllowTeamKilling) //Green light on team killing { Health -= part.ParentEntity.Damage; } } else //Object, hit em { Health -= part.ParentEntity.Damage; } } else { float Z = m_SP.Velocity.Length(); if (coldata [localid].PenetrationDepth >= 0.05f && m_SP.Velocity.Z < -3 && !m_SP.PhysicsActor.Flying && !m_SP.PhysicsActor.IsJumping) { Z = Math.Max(Z, 1.5f) * 10; float damage = Math.Min(coldata [localid].PenetrationDepth, 15f); Health -= damage * Z; } } if (Health > m_combatModule.MaximumHealth) { Health = m_combatModule.MaximumHealth; } if (Health <= 0 && killingAvatar == null) { killingAvatar = otherAvatar; } //MainConsole.Instance.Debug("[AVATAR]: Collision with localid: " + localid.ToString() + " at depth: " + coldata[localid].ToString()); } if (starthealth != Health) { m_SP.ControllingClient.SendHealth(Health); } if (Health <= 0) { KillAvatar(killingAvatar, "You killed " + m_SP.Name, "You died!", true, true); } }