public void UpdatePrimFlags(bool UsePhysics, bool IsTemporary, bool IsPhantom, bool IsVD) { bool wasUsingPhysics = ((ObjectFlags & (uint) PrimFlags.Physics) != 0); bool wasTemporary = ((ObjectFlags & (uint)PrimFlags.TemporaryOnRez) != 0); bool wasPhantom = ((ObjectFlags & (uint)PrimFlags.Phantom) != 0); bool wasVD = VolumeDetectActive; if ((UsePhysics == wasUsingPhysics) && (wasTemporary == IsTemporary) && (wasPhantom == IsPhantom) && (IsVD==wasVD)) { return; } // Special cases for VD. VD can only be called from a script // and can't be combined with changes to other states. So we can rely // that... // ... if VD is changed, all others are not. // ... if one of the others is changed, VD is not. if (IsVD) // VD is active, special logic applies { // State machine logic for VolumeDetect // More logic below bool phanReset = (IsPhantom != wasPhantom) && !IsPhantom; if (phanReset) // Phantom changes from on to off switch VD off too { IsVD = false; // Switch it of for the course of this routine VolumeDetectActive = false; // and also permanently if (PhysActor != null) PhysActor.SetVolumeDetect(0); // Let physics know about it too } else { IsPhantom = false; // If volumedetect is active we don't want phantom to be applied. // If this is a new call to VD out of the state "phantom" // this will also cause the prim to be visible to physics } } if (UsePhysics && IsJoint()) { IsPhantom = true; } if (UsePhysics) { AddFlag(PrimFlags.Physics); if (!wasUsingPhysics) { DoPhysicsPropertyUpdate(UsePhysics, false); if (m_parentGroup != null) { if (!m_parentGroup.IsDeleted) { if (LocalId == m_parentGroup.RootPart.LocalId) { m_parentGroup.CheckSculptAndLoad(); } } } } } else { RemFlag(PrimFlags.Physics); if (wasUsingPhysics) { DoPhysicsPropertyUpdate(UsePhysics, false); } } if (IsPhantom || IsAttachment || (Shape.PathCurve == (byte)Extrusion.Flexible)) // note: this may have been changed above in the case of joints { AddFlag(PrimFlags.Phantom); if (PhysActor != null) { m_parentGroup.Scene.PhysicsScene.RemovePrim(PhysActor); /// that's not wholesome. Had to make Scene public PhysActor = null; } } else // Not phantom { RemFlag(PrimFlags.Phantom); PhysicsActor pa = PhysActor; if (pa == null) { // It's not phantom anymore. So make sure the physics engine get's knowledge of it PhysActor = m_parentGroup.Scene.PhysicsScene.AddPrimShape( Name, Shape, AbsolutePosition, Scale, RotationOffset, UsePhysics); pa = PhysActor; if (pa != null) { pa.LocalID = LocalId; DoPhysicsPropertyUpdate(UsePhysics, true); if (m_parentGroup != null) { if (!m_parentGroup.IsDeleted) { if (LocalId == m_parentGroup.RootPart.LocalId) { m_parentGroup.CheckSculptAndLoad(); } } } if ( ((AggregateScriptEvents & scriptEvents.collision) != 0) || ((AggregateScriptEvents & scriptEvents.collision_end) != 0) || ((AggregateScriptEvents & scriptEvents.collision_start) != 0) || (CollisionSound != UUID.Zero) ) { PhysActor.OnCollisionUpdate += PhysicsCollision; PhysActor.SubscribeEvents(1000); } } } else // it already has a physical representation { pa.IsPhysical = UsePhysics; DoPhysicsPropertyUpdate(UsePhysics, false); // Update physical status. If it's phantom this will remove the prim if (m_parentGroup != null) { if (!m_parentGroup.IsDeleted) { if (LocalId == m_parentGroup.RootPart.LocalId) { m_parentGroup.CheckSculptAndLoad(); } } } } } if (IsVD) { // If the above logic worked (this is urgent candidate to unit tests!) // we now have a physicsactor. // Defensive programming calls for a check here. // Better would be throwing an exception that could be catched by a unit test as the internal // logic should make sure, this Physactor is always here. if (this.PhysActor != null) { PhysActor.SetVolumeDetect(1); AddFlag(PrimFlags.Phantom); // We set this flag also if VD is active this.VolumeDetectActive = true; } } else { // Remove VolumeDetect in any case. Note, it's safe to call SetVolumeDetect as often as you like // (mumbles, well, at least if you have infinte CPU powers :-)) PhysicsActor pa = this.PhysActor; if (pa != null) { PhysActor.SetVolumeDetect(0); } this.VolumeDetectActive = false; } if (IsTemporary) { AddFlag(PrimFlags.TemporaryOnRez); } else { RemFlag(PrimFlags.TemporaryOnRez); } // m_log.Debug("Update: PHY:" + UsePhysics.ToString() + ", T:" + IsTemporary.ToString() + ", PHA:" + IsPhantom.ToString() + " S:" + CastsShadows.ToString()); ParentGroup.HasGroupChanged = true; ScheduleFullUpdate(); }
/// <summary> /// Adds a physical representation of the avatar to the Physics plugin /// </summary> public void AddToPhysicalScene(bool isFlying, bool AddAvHeightToPosition) { //Make sure we arn't already doing this if (m_creatingPhysicalRepresentation) return; //Set this so we don't do it multiple times m_creatingPhysicalRepresentation = true; IAvatarAppearanceModule appearance = RequestModuleInterface<IAvatarAppearanceModule> (); if (appearance != null) { if (appearance.Appearance.AvatarHeight == 0) appearance.Appearance.SetHeight (); if (appearance.Appearance.AvatarHeight != 0) m_avHeight = appearance.Appearance.AvatarHeight; } PhysicsScene scene = m_scene.PhysicsScene; Vector3 pVec = AbsolutePosition; if(AddAvHeightToPosition) //This is here so that after teleports, you arrive just slightly higher so that you don't fall through the ground/objects pVec.Z += m_avHeight; m_physicsActor = scene.AddAvatar(Name, pVec, Rotation, new Vector3 (0f, 0f, m_avHeight), isFlying, LocalId); scene.AddPhysicsActorTaint(m_physicsActor); m_physicsActor.OnRequestTerseUpdate += SendTerseUpdateToAllClients; m_physicsActor.OnSignificantMovement += CheckForSignificantMovement; m_physicsActor.OnCollisionUpdate += PhysicsCollisionUpdate; m_physicsActor.OnPositionAndVelocityUpdate += PhysicsUpdatePosAndVelocity; m_physicsActor.OnOutOfBounds += OutOfBoundsCall; // Called for PhysicsActors when there's something wrong m_physicsActor.SubscribeEvents(500); m_physicsActor.Orientation = Rotation; //Tell any events about it if (OnAddPhysics != null) OnAddPhysics(); //All done, reset this m_creatingPhysicalRepresentation = false; }
/// <summary> /// Adds a physical representation of the avatar to the Physics plugin /// </summary> public void AddToPhysicalScene(bool isFlying) { if (m_appearance.AvatarHeight == 0) m_appearance.SetHeight(); PhysicsScene scene = m_scene.PhysicsScene; Vector3 pVec = AbsolutePosition; // Old bug where the height was in centimeters instead of meters m_physicsActor = scene.AddAvatar(Firstname + "." + Lastname, pVec, new Vector3(0f, 0f, m_appearance.AvatarHeight), isFlying); scene.AddPhysicsActorTaint(m_physicsActor); //m_physicsActor.OnRequestTerseUpdate += SendTerseUpdateToAllClients; m_physicsActor.OnCollisionUpdate += PhysicsCollisionUpdate; m_physicsActor.OnOutOfBounds += OutOfBoundsCall; // Called for PhysicsActors when there's something wrong m_physicsActor.SubscribeEvents(500); m_physicsActor.LocalID = LocalId; }
/// <summary> /// Adds a physical representation of the avatar to the Physics plugin /// </summary> public void AddToPhysicalScene(bool isFlying) { // m_log.DebugFormat( // "[SCENE PRESENCE]: Adding physics actor for {0}, ifFlying = {1} in {2}", // Name, isFlying, Scene.RegionInfo.RegionName); if (m_appearance.AvatarHeight == 0) m_appearance.SetHeight(); PhysicsScene scene = m_scene.PhysicsScene; Vector3 pVec = AbsolutePosition; // Old bug where the height was in centimeters instead of meters m_physicsActor = scene.AddAvatar(LocalId, Firstname + "." + Lastname, pVec, new Vector3(0f, 0f, m_appearance.AvatarHeight), isFlying); scene.AddPhysicsActorTaint(m_physicsActor); //m_physicsActor.OnRequestTerseUpdate += SendTerseUpdateToAllClients; m_physicsActor.OnCollisionUpdate += PhysicsCollisionUpdate; m_physicsActor.OnOutOfBounds += OutOfBoundsCall; // Called for PhysicsActors when there's something wrong m_physicsActor.SubscribeEvents(500); m_physicsActor.LocalID = LocalId; SetHeight(m_appearance.AvatarHeight); }