diff --git a/OpenSim/Framework/AnimationSet.cs b/OpenSim/Framework/AnimationSet.cs index fa71405abb..6c5b15c11f 100644 --- a/OpenSim/Framework/AnimationSet.cs +++ b/OpenSim/Framework/AnimationSet.cs @@ -37,6 +37,54 @@ namespace OpenSim.Framework { private bool m_parseError = false; + public const uint createBasePermitions = (uint)(PermissionMask.All); // no export ? + public const uint createNextPermitions = (uint)(PermissionMask.Copy | PermissionMask.Modify); + + public const uint allowedBasePermitions = (uint)(PermissionMask.Copy | PermissionMask.Modify); + public const uint allowedNextPermitions = 0; + + public static void setCreateItemPermitions(InventoryItemBase it) + { + if (it == null) + return; + + it.BasePermissions = createBasePermitions; + it.CurrentPermissions = createBasePermitions; + // it.GroupPermissions &= allowedPermitions; + it.NextPermissions = createNextPermitions; + // it.EveryOnePermissions &= allowedPermitions; + it.GroupPermissions = 0; + it.EveryOnePermissions = 0; + } + + public static void enforceItemPermitions(InventoryItemBase it, bool IsCreator) + { + if (it == null) + return; + + uint bp; + uint np; + + if (IsCreator) + { + bp = createBasePermitions; + np = createNextPermitions; + } + else + { + bp = allowedBasePermitions; + np = allowedNextPermitions; + } + + it.BasePermissions &= bp; + it.CurrentPermissions &= bp; + // it.GroupPermissions &= allowedPermitions; + it.NextPermissions &= np; + // it.EveryOnePermissions &= allowedPermitions; + it.GroupPermissions = 0; + it.EveryOnePermissions = 0; + } + public int AnimationCount { get; private set; } private Dictionary> m_animations = new Dictionary>(); diff --git a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs index 0e38d05af7..75634e01aa 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs @@ -1125,10 +1125,7 @@ namespace OpenSim.Region.ClientStack.Linden if (inType == (sbyte)CustomInventoryType.AnimationSet) { - item.BasePermissions = (uint)(PermissionMask.Copy | PermissionMask.Modify); - item.CurrentPermissions = (uint)(PermissionMask.Copy| PermissionMask.Modify); - item.EveryOnePermissions = 0; - item.NextPermissions = 0; + AnimationSet.setCreateItemPermitions(item); } else if (restrictPerms) diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index 12ee3b2e4a..6385aedd0f 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -607,7 +607,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP // Disable UDP handling for this client m_udpClient.Shutdown(); - + //m_log.InfoFormat("[CLIENTVIEW] Memory pre GC {0}", System.GC.GetTotalMemory(false)); //GC.Collect(); @@ -4912,6 +4912,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP IEventQueue eq = Scene.RequestModuleInterface(); if (eq != null) { + OSD message_body = updateMessage.Serialize(); // Add new fields here until OMV has them OSDMap bodyMap = (OSDMap)message_body; @@ -4923,8 +4924,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP OSDMap message = new OSDMap(); message.Add("message", OSD.FromString("ParcelProperties")); message.Add("body", message_body); + eq.Enqueue (message, this.AgentId); - //eq.ParcelProperties(updateMessage, this.AgentId); + +// eq.ParcelProperties(updateMessage, this.AgentId); } else { @@ -12420,8 +12423,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP uint regionY = 0; Utils.LongToUInts(m_scene.RegionInfo.RegionHandle, out regionX, out regionY); - locx = Convert.ToSingle(args[0]) - (float)regionX; - locy = Convert.ToSingle(args[1]) - (float)regionY; + locx = (float)(Convert.ToDouble(args[0]) - (double)regionX); + locy = (float)(Convert.ToDouble(args[1]) - (double)regionY); locz = Convert.ToSingle(args[2]); Action handlerAutoPilotGo = OnAutoPilotGo; diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs index 94782f912e..64a9610e1c 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs @@ -178,7 +178,8 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess sbyte assetType, byte wearableType, uint nextOwnerMask, int creationDate) { - m_log.DebugFormat("[INVENTORY ACCESS MODULE]: Received request to create inventory item {0} in folder {1}", name, folderID); + m_log.DebugFormat("[INVENTORY ACCESS MODULE]: Received request to create inventory item {0} in folder {1}, transactionID {2}", name, + folderID, transactionID); if (!m_Scene.Permissions.CanCreateUserInventory(invType, remoteClient.AgentId)) return; @@ -219,7 +220,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess m_Scene.AssetService.Store(asset); m_Scene.CreateNewInventoryItem( remoteClient, remoteClient.AgentId.ToString(), string.Empty, folderID, - name, description, 0, callbackID, asset, invType, nextOwnerMask, creationDate,transactionID); + name, description, 0, callbackID, asset, invType, nextOwnerMask, creationDate,transactionID); } else { diff --git a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs index c8555abcc3..bbb280bbdb 100644 --- a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs +++ b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs @@ -1200,32 +1200,30 @@ namespace OpenSim.Region.CoreModules.World.Land { //the proprieties to who changed them - land.SendLandProperties(0, true, LandChannel.LAND_RESULT_SINGLE, remote_client); + land.SendLandProperties(0, false, LandChannel.LAND_RESULT_SINGLE, remote_client); - if (needOverlay) - { - UUID parcelID = land.LandData.GlobalID; - m_scene.ForEachScenePresence(delegate(ScenePresence avatar) - { - if (avatar.IsDeleted || avatar.isNPC) - return; + UUID parcelID = land.LandData.GlobalID; + m_scene.ForEachScenePresence(delegate(ScenePresence avatar) + { + if (avatar.IsDeleted || avatar.isNPC) + return; - IClientAPI client = avatar.ControllingClient; + IClientAPI client = avatar.ControllingClient; + if (needOverlay) SendParcelOverlay(client); - if (avatar.IsChildAgent) - return; - - ILandObject aland = GetLandObject(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y); - if (aland != null) - { - if (client != remote_client || land != aland) - aland.SendLandProperties(0, false, LandChannel.LAND_RESULT_SINGLE, client); - } - if (avatar.currentParcelUUID == parcelID) - avatar.currentParcelUUID = parcelID; // force parcel flags review - }); - } + if (avatar.IsChildAgent) + return; + + ILandObject aland = GetLandObject(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y); + if (aland != null) + { + if (client != remote_client || land != aland) + aland.SendLandProperties(0, false, LandChannel.LAND_RESULT_SINGLE, client); + } + if (avatar.currentParcelUUID == parcelID) + avatar.currentParcelUUID = parcelID; // force parcel flags review + }); } } diff --git a/OpenSim/Region/CoreModules/World/Land/LandObject.cs b/OpenSim/Region/CoreModules/World/Land/LandObject.cs index e002febd31..a3cd4a5673 100644 --- a/OpenSim/Region/CoreModules/World/Land/LandObject.cs +++ b/OpenSim/Region/CoreModules/World/Land/LandObject.cs @@ -1244,6 +1244,7 @@ namespace OpenSim.Region.CoreModules.World.Land public void SetMediaUrl(string url) { LandData.MediaURL = url; + m_scene.LandChannel.UpdateLandObject(LandData.LocalID, LandData); SendLandUpdateToAvatarsOverMe(); } @@ -1254,6 +1255,7 @@ namespace OpenSim.Region.CoreModules.World.Land public void SetMusicUrl(string url) { LandData.MusicURL = url; + m_scene.LandChannel.UpdateLandObject(LandData.LocalID, LandData); SendLandUpdateToAvatarsOverMe(); } diff --git a/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs b/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs index db3b834735..2d1b0df906 100644 --- a/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs +++ b/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs @@ -48,7 +48,7 @@ namespace OpenSim.Region.Framework.Scenes.Animation public AnimationSet Animations { - get { return m_animations; } + get { return m_animations; } } protected AnimationSet m_animations = new AnimationSet(); @@ -56,25 +56,27 @@ namespace OpenSim.Region.Framework.Scenes.Animation /// The current movement animation /// public string CurrentMovementAnimation { get; private set; } - + private int m_animTickFall; - public int m_animTickJump; // ScenePresence has to see this to control +Z force - public bool m_jumping = false; - public float m_jumpVelocity = 0f; -// private int m_landing = 0; + private int m_animTickLand; + private int m_animTickJump; + + public bool m_jumping = false; + + // private int m_landing = 0; /// /// Is the avatar falling? /// public bool Falling { get; private set; } - private float m_fallHeight; + private float m_lastFallVelocity; /// /// The scene presence that this animator applies to /// protected ScenePresence m_scenePresence; - + public ScenePresenceAnimator(ScenePresence sp) { m_scenePresence = sp; @@ -89,7 +91,7 @@ namespace OpenSim.Region.Framework.Scenes.Animation // m_log.DebugFormat("[SCENE PRESENCE ANIMATOR]: Adding animation {0} for {1}", animID, m_scenePresence.Name); if (m_scenePresence.Scene.DebugAnimations) m_log.DebugFormat( - "[SCENE PRESENCE ANIMATOR]: Adding animation {0} {1} for {2}", + "[SCENE PRESENCE ANIMATOR]: Adding animation {0} {1} for {2}", GetAnimName(animID), animID, m_scenePresence.Name); if (m_animations.Add(animID, m_scenePresence.ControllingClient.NextAnimationSequenceNumber, objectID)) @@ -111,7 +113,7 @@ namespace OpenSim.Region.Framework.Scenes.Animation if (animID == UUID.Zero) return; -// m_log.DebugFormat("[SCENE PRESENCE ANIMATOR]: Adding animation {0} {1} for {2}", animID, name, m_scenePresence.Name); + // m_log.DebugFormat("[SCENE PRESENCE ANIMATOR]: Adding animation {0} {1} for {2}", animID, name, m_scenePresence.Name); AddAnimation(animID, objectID); } @@ -131,7 +133,7 @@ namespace OpenSim.Region.Framework.Scenes.Animation if (m_scenePresence.Scene.DebugAnimations) m_log.DebugFormat( - "[SCENE PRESENCE ANIMATOR]: Removing animation {0} {1} for {2}", + "[SCENE PRESENCE ANIMATOR]: Removing animation {0} {1} for {2}", GetAnimName(animID), animID, m_scenePresence.Name); if (m_animations.Remove(animID, allowNoDefault)) @@ -153,7 +155,7 @@ namespace OpenSim.Region.Framework.Scenes.Animation else m_animations.Remove(animID, false); } - if(sendPack) + if (sendPack) SendAnimPack(); } @@ -205,7 +207,7 @@ namespace OpenSim.Region.Framework.Scenes.Animation if (aoSitGndAnim != UUID.Zero) { - avnChangeAnim(aoSitGndAnim, false, false); + avnChangeAnim(aoSitGndAnim, false, true); aoSitGndAnim = UUID.Zero; } @@ -238,9 +240,9 @@ namespace OpenSim.Region.Framework.Scenes.Animation if (m_animations.TrySetDefaultAnimation( anim, m_scenePresence.ControllingClient.NextAnimationSequenceNumber, m_scenePresence.UUID)) { - // m_log.DebugFormat( - // "[SCENE PRESENCE ANIMATOR]: Updating movement animation to {0} for {1}", - // anim, m_scenePresence.Name); +// m_log.DebugFormat( +// "[SCENE PRESENCE ANIMATOR]: Updating movement animation to {0} for {1}", +// anim, m_scenePresence.Name); // 16384 is CHANGED_ANIMATION m_scenePresence.SendScriptEventToAttachments("changed", new Object[] { (int)Changed.ANIMATION }); @@ -258,83 +260,119 @@ namespace OpenSim.Region.Framework.Scenes.Animation return ret; } + public enum motionControlStates : byte + { + sitted = 0, + flying, + falling, + jumping, + landing, + onsurface + } + + public motionControlStates currentControlState = motionControlStates.onsurface; + /// /// This method determines the proper movement related animation /// private string DetermineMovementAnimation() { - const float FALL_DELAY = 800f; - const float PREJUMP_DELAY = 200f; - const float JUMP_PERIOD = 800f; + const int FALL_DELAY = 800; + const int PREJUMP_DELAY = 200; + const int JUMP_PERIOD = 800; #region Inputs + if (m_scenePresence.IsInTransit) + return CurrentMovementAnimation; + if (m_scenePresence.SitGround) + { + currentControlState = motionControlStates.sitted; return "SITGROUND"; + } if (m_scenePresence.ParentID != 0 || m_scenePresence.ParentUUID != UUID.Zero) + { + currentControlState = motionControlStates.sitted; return "SIT"; + } AgentManager.ControlFlags controlFlags = (AgentManager.ControlFlags)m_scenePresence.AgentControlFlags; PhysicsActor actor = m_scenePresence.PhysicsActor; - // Create forward and left vectors from the current avatar rotation - Matrix4 rotMatrix = Matrix4.CreateFromQuaternion(m_scenePresence.Rotation); - Vector3 fwd = Vector3.Transform(Vector3.UnitX, rotMatrix); - Vector3 left = Vector3.Transform(Vector3.UnitY, rotMatrix); + const AgentManager.ControlFlags ANYXYMASK = ( + AgentManager.ControlFlags.AGENT_CONTROL_AT_POS | AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS | + AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG | AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG | + AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS | AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS | + AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG | AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_NEG + ); // Check control flags - bool heldForward = ((controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_AT_POS) == AgentManager.ControlFlags.AGENT_CONTROL_AT_POS || (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS) == AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS); - bool heldBack = ((controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG || (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG); - bool heldLeft = ((controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS) == AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS || (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS) == AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS); - bool heldRight = ((controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG || (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_NEG); +/* not in use + bool heldForward = ((controlFlags & (AgentManager.ControlFlags.AGENT_CONTROL_AT_POS | AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS)) != 0); + bool heldBack = ((controlFlags & (AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG | AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG)) != 0); + bool heldLeft = ((controlFlags & (AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS | AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS)) != 0); + bool heldRight = ((controlFlags & (AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG | AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_NEG)) != 0); +*/ bool heldTurnLeft = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_TURN_LEFT) == AgentManager.ControlFlags.AGENT_CONTROL_TURN_LEFT; bool heldTurnRight = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_TURN_RIGHT) == AgentManager.ControlFlags.AGENT_CONTROL_TURN_RIGHT; - bool heldUp = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_UP_POS) == AgentManager.ControlFlags.AGENT_CONTROL_UP_POS; - bool heldDown = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG; +// bool heldUp = ((controlFlags & (AgentManager.ControlFlags.AGENT_CONTROL_UP_POS | AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_POS)) != 0); + // excluded nudge up so it doesn't trigger jump state + bool heldUp = ((controlFlags & (AgentManager.ControlFlags.AGENT_CONTROL_UP_POS)) != 0); + bool heldDown = ((controlFlags & (AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG | AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG)) != 0); //bool flying = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) == AgentManager.ControlFlags.AGENT_CONTROL_FLY; //bool mouselook = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) == AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK; - if (heldForward || heldBack || heldLeft || heldRight || heldUp || heldDown) + + bool heldOnXY = ((controlFlags & ANYXYMASK) != 0); + if (heldOnXY || heldUp || heldDown) { heldTurnLeft = false; heldTurnRight = false; } - - // Direction in which the avatar is trying to move - Vector3 move = Vector3.Zero; - if (heldForward) { move.X += fwd.X; move.Y += fwd.Y; } - if (heldBack) { move.X -= fwd.X; move.Y -= fwd.Y; } - if (heldLeft) { move.X += left.X; move.Y += left.Y; } - if (heldRight) { move.X -= left.X; move.Y -= left.Y; } - if (heldUp) { move.Z += 1; } - if (heldDown) { move.Z -= 1; } - - // Is the avatar trying to move? -// bool moving = (move != Vector3.Zero); + #endregion Inputs + // no physics actor case + if (actor == null) + { + // well what to do? + + currentControlState = motionControlStates.onsurface; + if (heldOnXY) + return "WALK"; + + return "STAND"; + } + #region Flying - if (actor != null && actor.Flying) + bool isColliding = actor.IsColliding; + + if (actor.Flying) { m_animTickFall = 0; m_animTickJump = 0; m_jumping = false; Falling = false; - m_jumpVelocity = 0f; - actor.Selected = false; - m_fallHeight = actor.Position.Z; // save latest flying height - if (move.X != 0f || move.Y != 0f) + currentControlState = motionControlStates.flying; + + if (heldOnXY) { return (m_scenePresence.Scene.m_useFlySlow ? "FLYSLOW" : "FLY"); } - else if (move.Z > 0f) + else if (heldUp) { return "HOVER_UP"; } - else if (move.Z < 0f) + else if (heldDown) { - if (actor != null && actor.IsColliding) + if (isColliding) + { + actor.Flying = false; + currentControlState = motionControlStates.landing; + m_animTickLand = Environment.TickCount; return "LAND"; + } else return "HOVER_DOWN"; } @@ -343,81 +381,88 @@ namespace OpenSim.Region.Framework.Scenes.Animation return "HOVER"; } } + else + { + if (isColliding && currentControlState == motionControlStates.flying) + { + currentControlState = motionControlStates.landing; + m_animTickLand = Environment.TickCount; + return "LAND"; + } + } #endregion Flying #region Falling/Floating/Landing - if ((actor == null || !actor.IsColliding) && !m_jumping) + if (!isColliding && currentControlState != motionControlStates.jumping) { - float fallElapsed = (float)(Environment.TickCount - m_animTickFall); - float fallVelocity = (actor != null) ? actor.Velocity.Z : 0.0f; + float fallVelocity = actor.Velocity.Z; - if (!m_jumping && (fallVelocity < -3.0f)) + if (fallVelocity < -2.5f) Falling = true; - if (m_animTickFall == 0 || (fallVelocity >= 0.0f)) + if (m_animTickFall == 0 || (fallVelocity >= -0.5f)) { - // not falling yet, or going up - // reset start of fall time m_animTickFall = Environment.TickCount; } - else if (!m_jumping && (fallElapsed > FALL_DELAY) && (fallVelocity < -3.0f) && (m_scenePresence.WasFlying)) + else { - // Falling long enough to trigger the animation - return "FALLDOWN"; + int fallElapsed = (Environment.TickCount - m_animTickFall); + if ((fallElapsed > FALL_DELAY) && (fallVelocity < -3.0f)) + { + currentControlState = motionControlStates.falling; + m_lastFallVelocity = fallVelocity; + // Falling long enough to trigger the animation + return "FALLDOWN"; + } } // Check if the user has stopped walking just now - if (CurrentMovementAnimation == "WALK" && (move == Vector3.Zero)) + if (CurrentMovementAnimation == "WALK" && !heldOnXY && !heldDown && !heldUp) return "STAND"; return CurrentMovementAnimation; } - #endregion Falling/Floating/Landing + m_animTickFall = 0; + #endregion Falling/Floating/Landing #region Jumping // section added for jumping... - int jumptime; - jumptime = Environment.TickCount - m_animTickJump; - - if ((move.Z > 0f) && (!m_jumping)) - { + if (isColliding && heldUp && currentControlState != motionControlStates.jumping) + { // Start jumping, prejump - m_animTickFall = 0; + currentControlState = motionControlStates.jumping; m_jumping = true; Falling = false; - actor.Selected = true; // borrowed for jumping flag m_animTickJump = Environment.TickCount; - m_jumpVelocity = 0.35f; return "PREJUMP"; } - if (m_jumping) + if (currentControlState == motionControlStates.jumping) { + int jumptime = Environment.TickCount - m_animTickJump; if ((jumptime > (JUMP_PERIOD * 1.5f)) && actor.IsColliding) { // end jumping m_jumping = false; Falling = false; actor.Selected = false; // borrowed for jumping flag - m_jumpVelocity = 0f; - m_animTickFall = Environment.TickCount; + m_animTickLand = Environment.TickCount; + currentControlState = motionControlStates.landing; return "LAND"; } else if (jumptime > JUMP_PERIOD) { // jump down - m_jumpVelocity = 0f; return "JUMP"; } else if (jumptime > PREJUMP_DELAY) { // jump up m_jumping = true; - m_jumpVelocity = 10f; return "JUMP"; } } @@ -426,45 +471,52 @@ namespace OpenSim.Region.Framework.Scenes.Animation #region Ground Movement - if (CurrentMovementAnimation == "FALLDOWN") + if (currentControlState == motionControlStates.falling) { Falling = false; - m_animTickFall = Environment.TickCount; + currentControlState = motionControlStates.landing; + m_animTickLand = Environment.TickCount; // TODO: SOFT_LAND support - float fallHeight = m_fallHeight - actor.Position.Z; - if (fallHeight > 15.0f) + float fallVsq = m_lastFallVelocity * m_lastFallVelocity; + if (fallVsq > 300f) // aprox 20*h return "STANDUP"; - else if (fallHeight > 8.0f) + else if (fallVsq > 160f) return "SOFT_LAND"; else return "LAND"; } - else if ((CurrentMovementAnimation == "LAND") || (CurrentMovementAnimation == "SOFT_LAND") || (CurrentMovementAnimation == "STANDUP")) + + + if (currentControlState == motionControlStates.landing) { - int landElapsed = Environment.TickCount - m_animTickFall; + Falling = false; + int landElapsed = Environment.TickCount - m_animTickLand; int limit = 1000; if (CurrentMovementAnimation == "LAND") limit = 350; // NB if the above is set too long a weird anim reset from some place prevents STAND from being sent to client - if ((m_animTickFall != 0) && (landElapsed <= limit)) + if ((m_animTickLand != 0) && (landElapsed <= limit)) { return CurrentMovementAnimation; } else { - m_fallHeight = actor.Position.Z; // save latest flying height + currentControlState = motionControlStates.onsurface; + m_animTickLand = 0; return "STAND"; } } + // next section moved outside paren. and realigned for jumping - if (move.X != 0f || move.Y != 0f) + + if (heldOnXY) { - m_fallHeight = actor.Position.Z; // save latest flying height + currentControlState = motionControlStates.onsurface; Falling = false; // Walking / crouchwalking / running - if (move.Z < 0f) + if (heldDown) { return "CROUCHWALK"; } @@ -480,9 +532,10 @@ namespace OpenSim.Region.Framework.Scenes.Animation } else if (!m_jumping) { + currentControlState = motionControlStates.onsurface; Falling = false; // Not walking - if (move.Z < 0) + if(heldDown) return "CROUCH"; else if (heldTurnLeft) return "TURNLEFT"; @@ -493,8 +546,6 @@ namespace OpenSim.Region.Framework.Scenes.Animation } #endregion Ground Movement - Falling = false; - return CurrentMovementAnimation; } @@ -504,7 +555,7 @@ namespace OpenSim.Region.Framework.Scenes.Animation /// 'true' if the animation was changed public bool UpdateMovementAnimations() { -// m_log.DebugFormat("[SCENE PRESENCE ANIMATOR]: Updating movement animations for {0}", m_scenePresence.Name); + // m_log.DebugFormat("[SCENE PRESENCE ANIMATOR]: Updating movement animations for {0}", m_scenePresence.Name); bool ret = false; lock (m_animations) @@ -552,19 +603,19 @@ namespace OpenSim.Region.Framework.Scenes.Animation m_animations.GetArrays(out animIDs, out sequenceNums, out objectIDs); return animIDs; } - + public BinBVHAnimation GenerateRandomAnimation() { int rnditerations = 3; BinBVHAnimation anim = new BinBVHAnimation(); List parts = new List(); - parts.Add("mPelvis");parts.Add("mHead");parts.Add("mTorso"); - parts.Add("mHipLeft");parts.Add("mHipRight");parts.Add("mHipLeft");parts.Add("mKneeLeft"); - parts.Add("mKneeRight");parts.Add("mCollarLeft");parts.Add("mCollarRight");parts.Add("mNeck"); - parts.Add("mElbowLeft");parts.Add("mElbowRight");parts.Add("mWristLeft");parts.Add("mWristRight"); - parts.Add("mShoulderLeft");parts.Add("mShoulderRight");parts.Add("mAnkleLeft");parts.Add("mAnkleRight"); - parts.Add("mEyeRight");parts.Add("mChest");parts.Add("mToeLeft");parts.Add("mToeRight"); - parts.Add("mFootLeft");parts.Add("mFootRight");parts.Add("mEyeLeft"); + parts.Add("mPelvis"); parts.Add("mHead"); parts.Add("mTorso"); + parts.Add("mHipLeft"); parts.Add("mHipRight"); parts.Add("mHipLeft"); parts.Add("mKneeLeft"); + parts.Add("mKneeRight"); parts.Add("mCollarLeft"); parts.Add("mCollarRight"); parts.Add("mNeck"); + parts.Add("mElbowLeft"); parts.Add("mElbowRight"); parts.Add("mWristLeft"); parts.Add("mWristRight"); + parts.Add("mShoulderLeft"); parts.Add("mShoulderRight"); parts.Add("mAnkleLeft"); parts.Add("mAnkleRight"); + parts.Add("mEyeRight"); parts.Add("mChest"); parts.Add("mToeLeft"); parts.Add("mToeRight"); + parts.Add("mFootLeft"); parts.Add("mFootRight"); parts.Add("mEyeLeft"); anim.HandPose = 1; anim.InPoint = 0; anim.OutPoint = (rnditerations * .10f); @@ -588,12 +639,12 @@ namespace OpenSim.Region.Framework.Scenes.Animation for (int i = 0; i < rnditerations; i++) { anim.Joints[j].rotationkeys[i] = new binBVHJointKey(); - anim.Joints[j].rotationkeys[i].time = (i*.10f); - anim.Joints[j].rotationkeys[i].key_element.X = ((float) rnd.NextDouble()*2 - 1); - anim.Joints[j].rotationkeys[i].key_element.Y = ((float) rnd.NextDouble()*2 - 1); - anim.Joints[j].rotationkeys[i].key_element.Z = ((float) rnd.NextDouble()*2 - 1); + anim.Joints[j].rotationkeys[i].time = (i * .10f); + anim.Joints[j].rotationkeys[i].key_element.X = ((float)rnd.NextDouble() * 2 - 1); + anim.Joints[j].rotationkeys[i].key_element.Y = ((float)rnd.NextDouble() * 2 - 1); + anim.Joints[j].rotationkeys[i].key_element.Z = ((float)rnd.NextDouble() * 2 - 1); anim.Joints[j].positionkeys[i] = new binBVHJointKey(); - anim.Joints[j].positionkeys[i].time = (i*.10f); + anim.Joints[j].positionkeys[i].time = (i * .10f); anim.Joints[j].positionkeys[i].key_element.X = 0; anim.Joints[j].positionkeys[i].key_element.Y = 0; anim.Joints[j].positionkeys[i].key_element.Z = 0; @@ -620,22 +671,6 @@ namespace OpenSim.Region.Framework.Scenes.Animation /// public void SendAnimPack(UUID[] animations, int[] seqs, UUID[] objectIDs) { -/* - if (m_scenePresence.IsChildAgent) - return; - -// m_log.DebugFormat( -// "[SCENE PRESENCE ANIMATOR]: Sending anim pack with animations '{0}', sequence '{1}', uuids '{2}'", -// string.Join(",", Array.ConvertAll(animations, a => a.ToString())), -// string.Join(",", Array.ConvertAll(seqs, s => s.ToString())), -// string.Join(",", Array.ConvertAll(objectIDs, o => o.ToString()))); - - m_scenePresence.Scene.ForEachClient( - delegate(IClientAPI client) - { - client.SendAnimations(animations, seqs, m_scenePresence.ControllingClient.AgentId, objectIDs); - }); - */ m_scenePresence.SendAnimPack(animations, seqs, objectIDs); } @@ -645,7 +680,7 @@ namespace OpenSim.Region.Framework.Scenes.Animation sequenceNums = null; objectIDs = null; - if(m_animations != null) + if (m_animations != null) m_animations.GetArrays(out animIDs, out sequenceNums, out objectIDs); } @@ -668,7 +703,7 @@ namespace OpenSim.Region.Framework.Scenes.Animation public void SendAnimPack() { //m_log.Debug("Sending animation pack to all"); - + if (m_scenePresence.IsChildAgent) return; @@ -678,7 +713,7 @@ namespace OpenSim.Region.Framework.Scenes.Animation m_animations.GetArrays(out animIDs, out sequenceNums, out objectIDs); -// SendAnimPack(animIDs, sequenceNums, objectIDs); + // SendAnimPack(animIDs, sequenceNums, objectIDs); m_scenePresence.SendAnimPack(animIDs, sequenceNums, objectIDs); } diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index e003a59f6a..5197f5802d 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -1063,6 +1063,10 @@ namespace OpenSim.Region.Framework.Scenes if (!Permissions.CanCreateUserInventory(invType, remoteClient.AgentId)) return; + if (type != (sbyte)AssetType.Link || type != (sbyte)AssetType.LinkFolder) + return; + + ScenePresence presence; if (TryGetScenePresence(remoteClient.AgentId, out presence)) { diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 594697964b..42d36843e9 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -287,14 +287,7 @@ namespace OpenSim.Region.Framework.Scenes set { PhysicsActor.Flying = value; } } - // add for fly velocity control - private bool FlyingOld {get; set;} - public bool WasFlying - { - get; private set; - } - - public bool IsColliding + public bool IsColliding { get { return PhysicsActor != null && PhysicsActor.IsColliding; } // We would expect setting IsColliding to be private but it's used by a hack in Scene @@ -936,7 +929,7 @@ namespace OpenSim.Region.Framework.Scenes /// /// AGENT_CONTRL_STOP comes about if user holds down space key on viewers. /// - private float AgentControlStopSlowWhilstMoving = 0.5f; + private float AgentControlStopSlowWhilstMoving = 0.2f; private bool m_forceFly; @@ -2174,7 +2167,7 @@ namespace OpenSim.Region.Framework.Scenes bool DCFlagKeyPressed = false; Vector3 agent_control_v3 = Vector3.Zero; - bool newFlying = actor.Flying; + bool newFlying = false; if (ForceFly) newFlying = true; @@ -2286,11 +2279,11 @@ namespace OpenSim.Region.Framework.Scenes if (Flying && !ForceFly) { // Need to stop in mid air if user holds down AGENT_CONTROL_STOP - if (AgentControlStopActive) - { - agent_control_v3 = Vector3.Zero; - } - else + // if (AgentControlStopActive) + // { + // agent_control_v3 = Vector3.Zero; + // } + // else { // Landing detection code @@ -2298,38 +2291,44 @@ namespace OpenSim.Region.Framework.Scenes bool controlland = (((flags & AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0) || ((flags & AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG) != 0)); - //m_log.Debug("[CONTROL]: " +flags); + //m_log.Debug("[CONTROL]: " +flags); // Applies a satisfying roll effect to the avatar when flying. if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_TURN_LEFT) != 0 && (flags & AgentManager.ControlFlags.AGENT_CONTROL_YAW_POS) != 0) { ApplyFlyingRoll( - FLY_ROLL_RADIANS_PER_UPDATE, - (flags & AgentManager.ControlFlags.AGENT_CONTROL_UP_POS) != 0, + FLY_ROLL_RADIANS_PER_UPDATE, + (flags & AgentManager.ControlFlags.AGENT_CONTROL_UP_POS) != 0, (flags & AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0); - } + } else if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_TURN_RIGHT) != 0 && (flags & AgentManager.ControlFlags.AGENT_CONTROL_YAW_NEG) != 0) { ApplyFlyingRoll( - -FLY_ROLL_RADIANS_PER_UPDATE, - (flags & AgentManager.ControlFlags.AGENT_CONTROL_UP_POS) != 0, - (flags & AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0); + -FLY_ROLL_RADIANS_PER_UPDATE, + (flags & AgentManager.ControlFlags.AGENT_CONTROL_UP_POS) != 0, + (flags & AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0); } else { if (m_AngularVelocity.Z != 0) - m_AngularVelocity.Z += CalculateFlyingRollResetToZero(FLY_ROLL_RESET_RADIANS_PER_UPDATE); - } - - if (Flying && IsColliding && controlland) - { - // nesting this check because LengthSquared() is expensive and we don't - // want to do it every step when flying. - if ((Velocity.LengthSquared() <= LAND_VELOCITYMAG_MAX)) - StopFlying(); + m_AngularVelocity.Z += CalculateFlyingRollResetToZero(FLY_ROLL_RESET_RADIANS_PER_UPDATE); } + + /* + if (Flying && IsColliding && controlland) + { + // nesting this check because LengthSquared() is expensive and we don't + // want to do it every step when flying. + if ((Velocity.LengthSquared() <= LAND_VELOCITYMAG_MAX)) + StopFlying(); + } + */ } } + else if (IsColliding && agent_control_v3.Z < 0f) + agent_control_v3.Z = 0; +// else if(AgentControlStopActive %% Velocity.Z <0.01f) + // m_log.DebugFormat("[SCENE PRESENCE]: MovementFlag {0} for {1}", MovementFlag, Name); @@ -2342,32 +2341,22 @@ namespace OpenSim.Region.Framework.Scenes if (update_movementflag || (update_rotation && DCFlagKeyPressed && (!AgentControlStopActive || MovementFlag != 0))) { -// if (update_movementflag || !AgentControlStopActive || MovementFlag != 0) -// { -// m_log.DebugFormat( -// "[SCENE PRESENCE]: In {0} adding velocity of {1} to {2}, umf = {3}, mf = {4}, ur = {5}", -// m_scene.RegionInfo.RegionName, agent_control_v3, Name, -// update_movementflag, MovementFlag, update_rotation); - float speedModifier; - - if (AgentControlStopActive) - speedModifier = AgentControlStopSlowWhilstMoving; + if (AgentControlStopActive) + { +// if (MovementFlag == 0 && Animator.Falling) + if (MovementFlag == 0 && Animator.currentControlState == ScenePresenceAnimator.motionControlStates.falling) + { + AddNewMovement(agent_control_v3, AgentControlStopSlowWhilstMoving, true); + } else - speedModifier = 1; + AddNewMovement(agent_control_v3, AgentControlStopSlowWhilstMoving); + } + + else + AddNewMovement(agent_control_v3); - AddNewMovement(agent_control_v3, speedModifier); -// } } -// else -// { -// if (!update_movementflag) -// { -// m_log.DebugFormat( -// "[SCENE PRESENCE]: In {0} ignoring requested update of {1} for {2} as update_movementflag = false", -// m_scene.RegionInfo.RegionName, agent_control_v3, Name); -// } -// } if (update_movementflag && ParentID == 0) { @@ -3246,68 +3235,55 @@ namespace OpenSim.Region.Framework.Scenes /// The vector in which to move. This is relative to the rotation argument /// /// Optional additional speed modifier for this particular add. Default is 1 - public void AddNewMovement(Vector3 vec, float thisAddSpeedModifier = 1) + public void AddNewMovement(Vector3 vec, float thisAddSpeedModifier = 1, bool breaking = false) { -// m_log.DebugFormat( -// "[SCENE PRESENCE]: Adding new movement {0} with rotation {1}, thisAddSpeedModifier {2} for {3}", -// vec, Rotation, thisAddSpeedModifier, Name); + // m_log.DebugFormat( + // "[SCENE PRESENCE]: Adding new movement {0} with rotation {1}, thisAddSpeedModifier {2} for {3}", + // vec, Rotation, thisAddSpeedModifier, Name); + // rotate from avatar coord space to world + // for now all controls assume this is only a rotation around Z + // if not all checks below need to be done before this rotation Vector3 direc = vec * Rotation; direc.Normalize(); - if (Flying != FlyingOld) // add for fly velocity control - { - FlyingOld = Flying; // add for fly velocity control - if (!Flying) - WasFlying = true; // add for fly velocity control - } - - if (IsColliding) - WasFlying = false; // add for fly velocity control - + // mouse look situation ? if ((vec.Z == 0f) && !Flying) direc.Z = 0f; // Prevent camera WASD up. + // odd rescalings direc *= 0.03f * 128f * SpeedModifier * thisAddSpeedModifier; -// m_log.DebugFormat("[SCENE PRESENCE]: Force to apply before modification was {0} for {1}", direc, Name); + // m_log.DebugFormat("[SCENE PRESENCE]: Force to apply before modification was {0} for {1}", direc, Name); - if (PhysicsActor != null) + if (Animator.currentControlState == ScenePresenceAnimator.motionControlStates.falling) { - if (Flying) - { + if (breaking) + direc.Z = -9999f; //hack to tell physics to stop on Z + else + direc = Vector3.Zero; + } + else if (Flying) + { + if (IsColliding && direc.Z < 0) + // landing situation, prevent avatar moving or it may fail to land + // animator will handle this condition and do the land + direc = Vector3.Zero; + else direc *= 4.0f; - //bool controlland = (((m_AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0) || ((m_AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG) != 0)); - //if (controlland) - // m_log.Info("[AGENT]: landCommand"); - //if (IsColliding) - // m_log.Info("[AGENT]: colliding"); - //if (Flying && IsColliding && controlland) - //{ - // StopFlying(); - // m_log.Info("[AGENT]: Stop Flying"); - //} - } - if (Animator.Falling && WasFlying) // if falling from flying, disable motion add + } + else if (IsColliding) + { + if (direc.Z > 2.0f) // reinforce jumps { - direc *= 0.0f; - } - else if (!Flying && IsColliding) - { - if (direc.Z > 2.0f) - { - direc.Z *= 2.6f; - - // TODO: PreJump and jump happen too quickly. Many times prejump gets ignored. -// Animator.TrySetMovementAnimation("PREJUMP"); -// Animator.TrySetMovementAnimation("JUMP"); - } + direc.Z *= 2.6f; } + else if (direc.Z < 0) // on a surface moving down (pg down) only changes animation + direc.Z = 0; } -// m_log.DebugFormat("[SCENE PRESENCE]: Setting force to apply to {0} for {1}", direc, Name); + // m_log.DebugFormat("[SCENE PRESENCE]: Setting force to apply to {0} for {1}", direc, Name); - // TODO: Add the force instead of only setting it to support multiple forces per frame? m_forceToApply = direc; Animator.UpdateMovementAnimations(); } diff --git a/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs b/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs index daf6c7c8e0..992fae74bd 100644 --- a/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs +++ b/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs @@ -79,6 +79,7 @@ namespace OpenSim.Region.Physics.OdePlugin private Vector3 _acceleration; private Vector3 m_rotationalVelocity; private Vector3 m_size; + private Vector3 m_collideNormal; private Quaternion m_orientation; private Quaternion m_orientation2D; private float m_mass = 80f; @@ -109,6 +110,7 @@ namespace OpenSim.Region.Physics.OdePlugin private bool _zeroFlag = false; + private uint m_localID = 0; public bool m_returnCollisions = false; // taints and their non-tainted counterparts @@ -153,9 +155,7 @@ namespace OpenSim.Region.Physics.OdePlugin public UUID m_uuid; public bool bad = false; - float mu; - - + float mu; public OdeCharacter(uint localID, String avName, OdeScene parent_scene, Vector3 pos, Vector3 pSize, float pfeetOffset, float density, float walk_divisor, float rundivisor) { @@ -864,11 +864,12 @@ namespace OpenSim.Region.Physics.OdePlugin x = tx * cos - y * sin; y = tx * sin + y * cos; } - - - public bool Collide(IntPtr me,IntPtr other, bool reverse, ref d.ContactGeom contact, ref bool feetcollision) + + public bool Collide(IntPtr me, IntPtr other, bool reverse, ref d.ContactGeom contact, + ref d.ContactGeom altContact , ref bool useAltcontact, ref bool feetcollision) { feetcollision = false; + useAltcontact = false; if (me == capsule) { @@ -899,31 +900,78 @@ namespace OpenSim.Region.Physics.OdePlugin { feetcollision = true; if (h < boneOff) + { + m_collideNormal.X = contact.normal.X; + m_collideNormal.Y = contact.normal.Y; + m_collideNormal.Z = contact.normal.Z; IsColliding = true; + } + } + return true; + } +/* + d.AABB aabb; + d.GeomGetAABB(other,out aabb); + float othertop = aabb.MaxZ - _position.Z; +*/ +// if (offset.Z > 0 || othertop > -feetOff || contact.normal.Z > 0.35f) + if (offset.Z > 0 || contact.normal.Z > 0.35f) + { + if (offset.Z <= 0) + { + feetcollision = true; + if (h < boneOff) + { + m_collideNormal.X = contact.normal.X; + m_collideNormal.Y = contact.normal.Y; + m_collideNormal.Z = contact.normal.Z; + IsColliding = true; + } + } + + if (contact.normal.Z < 0.2f) + { + contact.normal.Z = 0; + float t = contact.normal.X * contact.normal.X + contact.normal.Y * contact.normal.Y; + if (t > 0) + { + t = 1.0f / t; + contact.normal.X *= t; + contact.normal.Y *= t; + } } return true; } - if (offset.Z > 0) - return true; + altContact = contact; + useAltcontact = true; offset.Normalize(); + if (contact.depth > 0.1f) + contact.depth = 0.1f; + if (reverse) { - contact.normal.X = offset.X; - contact.normal.Y = offset.Y; - contact.normal.Z = offset.Z; + altContact.normal.X = offset.X; + altContact.normal.Y = offset.Y; + altContact.normal.Z = offset.Z; } else { - contact.normal.X = -offset.X; - contact.normal.Y = -offset.Y; - contact.normal.Z = -offset.Z; + altContact.normal.X = -offset.X; + altContact.normal.Y = -offset.Y; + altContact.normal.Z = -offset.Z; } + feetcollision = true; if (h < boneOff) + { + m_collideNormal.X = contact.normal.X; + m_collideNormal.Y = contact.normal.Y; + m_collideNormal.Z = contact.normal.Z; IsColliding = true; + } return true; } return false; @@ -1003,6 +1051,9 @@ namespace OpenSim.Region.Physics.OdePlugin Vector3 vel = new Vector3(dtmp.X, dtmp.Y, dtmp.Z); float velLengthSquared = vel.LengthSquared(); + + Vector3 ctz = _target_velocity; + float movementdivisor = 1f; //Ubit change divisions into multiplications below if (!m_alwaysRun) @@ -1010,13 +1061,16 @@ namespace OpenSim.Region.Physics.OdePlugin else movementdivisor = 1 / runDivisor; + ctz.X *= movementdivisor; + ctz.Y *= movementdivisor; + //****************************************** // colide with land d.AABB aabb; // d.GeomGetAABB(feetbox, out aabb); d.GeomGetAABB(capsule, out aabb); - float chrminZ = aabb.MinZ; ; // move up a bit + float chrminZ = aabb.MinZ; // move up a bit Vector3 posch = localpos; float ftmp; @@ -1031,15 +1085,18 @@ namespace OpenSim.Region.Physics.OdePlugin float terrainheight = _parent_scene.GetTerrainHeightAtXY(posch.X, posch.Y); if (chrminZ < terrainheight) { - float depth = terrainheight - chrminZ; - if (!flying) - { - vec.Z = -vel.Z * PID_D * 1.5f + depth * PID_P * 50; - } - else - vec.Z = depth * PID_P * 50; + if (ctz.Z < 0) + ctz.Z = 0; - if (depth < 0.1f) + Vector3 n = _parent_scene.GetTerrainNormalAtXY(posch.X, posch.Y); + float depth = terrainheight - chrminZ; + + vec.Z = depth * PID_P * 50; + + if (!flying) + vec.Z += -vel.Z * PID_D; + + if (depth < 0.2f) { m_colliderGroundfilter++; if (m_colliderGroundfilter > 2) @@ -1053,50 +1110,83 @@ namespace OpenSim.Region.Physics.OdePlugin m_freemove = false; } + m_collideNormal.X = n.X; + m_collideNormal.Y = n.Y; + m_collideNormal.Z = n.Z; + m_iscollidingGround = true; + ContactPoint contact = new ContactPoint(); contact.PenetrationDepth = depth; contact.Position.X = localpos.X; contact.Position.Y = localpos.Y; contact.Position.Z = terrainheight; - contact.SurfaceNormal.X = 0.0f; - contact.SurfaceNormal.Y = 0.0f; - contact.SurfaceNormal.Z = -1f; + contact.SurfaceNormal.X = -n.X; + contact.SurfaceNormal.Y = -n.Y; + contact.SurfaceNormal.Z = -n.Z; contact.RelativeSpeed = -vel.Z; contact.CharacterFeet = true; AddCollisionEvent(0, contact); - vec.Z *= 0.5f; +// vec.Z *= 0.5f; } } else { - m_colliderGroundfilter = 0; - m_iscollidingGround = false; + m_colliderGroundfilter -= 5; + if (m_colliderGroundfilter <= 0) + { + m_colliderGroundfilter = 0; + m_iscollidingGround = false; + } } } else { - m_colliderGroundfilter = 0; - m_iscollidingGround = false; + m_colliderGroundfilter -= 5; + if (m_colliderGroundfilter <= 0) + { + m_colliderGroundfilter = 0; + m_iscollidingGround = false; + } } //****************************************** + if (!m_iscolliding) + m_collideNormal.Z = 0; + + bool tviszero = (ctz.X == 0.0f && ctz.Y == 0.0f && ctz.Z == 0.0f); + - bool tviszero = (_target_velocity.X == 0.0f && _target_velocity.Y == 0.0f && _target_velocity.Z == 0.0f); - // if (!tviszero || m_iscolliding || velLengthSquared <0.01) if (!tviszero) + { m_freemove = false; + // movement relative to surface if moving on it + // dont disturbe vertical movement, ie jumps + if (m_iscolliding && !flying && ctz.Z == 0 && m_collideNormal.Z > 0.2f && m_collideNormal.Z < 0.94f) + { + float p = ctz.X * m_collideNormal.X + ctz.Y * m_collideNormal.Y; + ctz.X *= (float)Math.Sqrt(1 - m_collideNormal.X * m_collideNormal.X); + ctz.Y *= (float)Math.Sqrt(1 - m_collideNormal.Y * m_collideNormal.Y); + ctz.Z -= p; + if (ctz.Z < 0) + ctz.Z *= 2; + + } + + } + + if (!m_freemove) { // if velocity is zero, use position control; otherwise, velocity control - if (tviszero && m_iscolliding) + if (tviszero && m_iscolliding && !flying) { // keep track of where we stopped. No more slippin' & slidin' if (!_zeroFlag) @@ -1129,22 +1219,48 @@ namespace OpenSim.Region.Physics.OdePlugin { if (!flying) { - if (_target_velocity.Z > 0.0f) + // we are on a surface + if (ctz.Z > 0f) { - // We're colliding with something and we're not flying but we're moving - // This means we're walking or running. JUMPING - vec.Z += (_target_velocity.Z - vel.Z) * PID_D * 1.2f;// +(_zeroPosition.Z - localpos.Z) * PID_P; + // moving up or JUMPING + vec.Z += (ctz.Z - vel.Z) * PID_D * 1.2f;// +(_zeroPosition.Z - localpos.Z) * PID_P; + vec.X += (ctz.X - vel.X) * (PID_D); + vec.Y += (ctz.Y - vel.Y) * (PID_D); } + else + { + // we are moving down on a surface + if (ctz.Z == 0) + { + if (vel.Z > 0) + vec.Z -= vel.Z * PID_D * 2.0f; + vec.X += (ctz.X - vel.X) * (PID_D); + vec.Y += (ctz.Y - vel.Y) * (PID_D); + } + // intencionally going down + else + { + if (ctz.Z < vel.Z) + vec.Z += (ctz.Z - vel.Z) * PID_D * 2.0f; + else + { + } + + if (Math.Abs(ctz.X) > Math.Abs(vel.X)) + vec.X += (ctz.X - vel.X) * (PID_D); + if (Math.Abs(ctz.Y) > Math.Abs(vel.Y)) + vec.Y += (ctz.Y - vel.Y) * (PID_D); + } + } + // We're standing on something - vec.X = ((_target_velocity.X * movementdivisor) - vel.X) * (PID_D); - vec.Y = ((_target_velocity.Y * movementdivisor) - vel.Y) * (PID_D); } else { // We're flying and colliding with something - vec.X = ((_target_velocity.X * movementdivisor) - vel.X) * (PID_D * 0.0625f); - vec.Y = ((_target_velocity.Y * movementdivisor) - vel.Y) * (PID_D * 0.0625f); - vec.Z += (_target_velocity.Z - vel.Z) * (PID_D); + vec.X += (ctz.X - vel.X) * (PID_D * 0.0625f); + vec.Y += (ctz.Y - vel.Y) * (PID_D * 0.0625f); + vec.Z += (ctz.Z - vel.Z) * (PID_D); } } else // ie not colliding @@ -1152,9 +1268,9 @@ namespace OpenSim.Region.Physics.OdePlugin if (flying) //(!m_iscolliding && flying) { // we're in mid air suspended - vec.X = ((_target_velocity.X * movementdivisor) - vel.X) * (PID_D * 1.667f); - vec.Y = ((_target_velocity.Y * movementdivisor) - vel.Y) * (PID_D * 1.667f); - vec.Z += (_target_velocity.Z - vel.Z) * (PID_D); + vec.X += (ctz.X - vel.X) * (PID_D * 1.667f); + vec.Y += (ctz.Y - vel.Y) * (PID_D * 1.667f); + vec.Z += (ctz.Z - vel.Z) * (PID_D); } else @@ -1163,8 +1279,11 @@ namespace OpenSim.Region.Physics.OdePlugin // m_iscolliding includes collisions with the ground. // d.Vector3 pos = d.BodyGetPosition(Body); - vec.X = (_target_velocity.X - vel.X) * PID_D * 0.833f; - vec.Y = (_target_velocity.Y - vel.Y) * PID_D * 0.833f; + vec.X += (ctz.X - vel.X) * PID_D * 0.833f; + vec.Y += (ctz.Y - vel.Y) * PID_D * 0.833f; + // hack for breaking on fall + if (ctz.Z == -9999f) + vec.Z += -vel.Z * PID_D - _parent_scene.gravityz * m_mass; } } } diff --git a/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs b/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs index 9bf2abe0e3..2adbe014b1 100644 --- a/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs +++ b/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs @@ -935,18 +935,22 @@ namespace OpenSim.Region.Physics.OdePlugin SharedTmpcontact.surface.mu = mu; SharedTmpcontact.surface.bounce = bounce; + d.ContactGeom altContact = new d.ContactGeom(); + bool useAltcontact = false; + bool noskip = true; + while (true) { // if (!(IgnoreNegSides && curContact.side1 < 0)) { - bool noskip = true; + noskip = true; + useAltcontact = false; + if (dop1ava) { - if (!(((OdeCharacter)p1).Collide(g1, g2, false, ref curContact, ref FeetCollision))) - noskip = false; - else + if ((((OdeCharacter)p1).Collide(g1, g2, false, ref curContact, ref altContact , ref useAltcontact, ref FeetCollision))) { - if(p2.PhysicsActorType == (int)ActorTypes.Agent) + if (p2.PhysicsActorType == (int)ActorTypes.Agent) { p1.CollidingObj = true; p2.CollidingObj = true; @@ -954,18 +958,32 @@ namespace OpenSim.Region.Physics.OdePlugin else if (p2.Velocity.LengthSquared() > 0.0f) p2.CollidingObj = true; } + else + noskip = false; } else if (dop2ava) { - if (!(((OdeCharacter)p2).Collide(g2,g1, true, ref curContact, ref FeetCollision))) + if ((((OdeCharacter)p2).Collide(g2, g1, true, ref curContact, ref altContact , ref useAltcontact, ref FeetCollision))) + { + if (p1.PhysicsActorType == (int)ActorTypes.Agent) + { + p1.CollidingObj = true; + p2.CollidingObj = true; + } + else if (p2.Velocity.LengthSquared() > 0.0f) + p1.CollidingObj = true; + } + else noskip = false; - else if (p1.Velocity.LengthSquared() > 0.0f) - p1.CollidingObj = true; } if (noskip) { - Joint = CreateContacJoint(ref curContact); + if(useAltcontact) + Joint = CreateContacJoint(ref altContact); + else + Joint = CreateContacJoint(ref curContact); + if (Joint == IntPtr.Zero) break; @@ -1924,12 +1942,12 @@ namespace OpenSim.Region.Physics.OdePlugin dy = 0; } } - else { // we still have square fixed size regions // also flip x and y because of how map is done for ODE fliped axis // so ix,iy,dx and dy are inter exchanged + if (x < regsize - 1) { iy = (int)x; @@ -1976,7 +1994,7 @@ namespace OpenSim.Region.Physics.OdePlugin */ h0 = ((float)heights[iy]); // 0,0 vertice - if ((dy > dx)) + if (dy>dx) { iy += regsize; h2 = (float)heights[iy]; // 0,1 vertice @@ -1994,6 +2012,133 @@ namespace OpenSim.Region.Physics.OdePlugin return h0 + h1 + h2; } + public Vector3 GetTerrainNormalAtXY(float x, float y) + { + int offsetX = ((int)(x / (int)Constants.RegionSize)) * (int)Constants.RegionSize; + int offsetY = ((int)(y / (int)Constants.RegionSize)) * (int)Constants.RegionSize; + + IntPtr heightFieldGeom = IntPtr.Zero; + Vector3 norm = new Vector3(0, 0, 1); + + // get region map + if (!RegionTerrain.TryGetValue(new Vector3(offsetX, offsetY, 0), out heightFieldGeom)) + return norm; + + if (heightFieldGeom == IntPtr.Zero) + return norm; + + if (!TerrainHeightFieldHeights.ContainsKey(heightFieldGeom)) + return norm; + + // TerrainHeightField for ODE as offset 1m + x += 1f - offsetX; + y += 1f - offsetY; + + // make position fit into array + if (x < 0) + x = 0; + if (y < 0) + y = 0; + + // integer indexs + int ix; + int iy; + // interpolators offset + float dx; + float dy; + + + int regsize = (int)Constants.RegionSize + 3; // map size see setterrain number of samples + int xstep = 1; + int ystep = regsize; + bool firstTri = false; + + if (OdeUbitLib) + { + if (x < regsize - 1) + { + ix = (int)x; + dx = x - (float)ix; + } + else // out world use external height + { + ix = regsize - 2; + dx = 0; + } + if (y < regsize - 1) + { + iy = (int)y; + dy = y - (float)iy; + } + else + { + iy = regsize - 2; + dy = 0; + } + firstTri = dy > dx; + } + + else + { + xstep = regsize; + ystep = 1; + // we still have square fixed size regions + // also flip x and y because of how map is done for ODE fliped axis + // so ix,iy,dx and dy are inter exchanged + if (x < regsize - 1) + { + iy = (int)x; + dy = x - (float)iy; + } + else // out world use external height + { + iy = regsize - 2; + dy = 0; + } + if (y < regsize - 1) + { + ix = (int)y; + dx = y - (float)ix; + } + else + { + ix = regsize - 2; + dx = 0; + } + firstTri = dx > dy; + } + + float h0; + float h1; + float h2; + + iy *= regsize; + iy += ix; // all indexes have iy + ix + + float[] heights = TerrainHeightFieldHeights[heightFieldGeom]; + + if (firstTri) + { + h1 = ((float)heights[iy]); // 0,0 vertice + iy += ystep; + h0 = (float)heights[iy]; // 0,1 + h2 = (float)heights[iy+xstep]; // 1,1 vertice + norm.X = h0 - h2; + norm.Y = h1 - h0; + } + else + { + h2 = ((float)heights[iy]); // 0,0 vertice + iy += xstep; + h0 = ((float)heights[iy]); // 1,0 vertice + h1 = (float)heights[iy+ystep]; // vertice 1,1 + norm.X = h2 - h0; + norm.Y = h0 - h1; + } + norm.Z = 1; + norm.Normalize(); + return norm; + } public override void SetTerrain(float[] heightMap) {