From 967da500c1651beee5f928c844a9898cbe6baf89 Mon Sep 17 00:00:00 2001 From: Date: Wed, 20 Aug 2008 03:46:11 +0000 Subject: [PATCH] Cleaned up Simian movement code and added running. git-svn-id: http://libopenmetaverse.googlecode.com/svn/trunk@2123 52acb1d6-8a22-11de-b505-999d5b087335 --- Programs/Simian/Agent.cs | 1 + Programs/Simian/Extensions/Movement.cs | 120 ++++++++++++------------- 2 files changed, 60 insertions(+), 61 deletions(-) diff --git a/Programs/Simian/Agent.cs b/Programs/Simian/Agent.cs index 95b91503..46d5a14d 100644 --- a/Programs/Simian/Agent.cs +++ b/Programs/Simian/Agent.cs @@ -17,6 +17,7 @@ namespace Simian public string LastName; public Avatar Avatar = new Avatar(); public int Balance; + public bool Running; public AgentManager.ControlFlags ControlFlags = AgentManager.ControlFlags.NONE; /// Sequence numbers of packets we've received (for duplicate checking) diff --git a/Programs/Simian/Extensions/Movement.cs b/Programs/Simian/Extensions/Movement.cs index 8d6817c1..f9ed3a41 100644 --- a/Programs/Simian/Extensions/Movement.cs +++ b/Programs/Simian/Extensions/Movement.cs @@ -13,6 +13,7 @@ namespace Simian.Extensions Timer UpdateTimer; const float SQRT_TWO = 1.41421356f; const float WALK_SPEED = 0.5f; + const float RUN_SPEED = 1.0f; const float FLY_SPEED = 1.5f; public Movement(Simian server) @@ -23,6 +24,7 @@ namespace Simian.Extensions public void Start() { Server.UDPServer.RegisterPacketCallback(PacketType.AgentUpdate, new UDPServer.PacketCallback(AgentUpdateHandler)); + Server.UDPServer.RegisterPacketCallback(PacketType.SetAlwaysRun, new UDPServer.PacketCallback(SetAlwaysRunHandler)); if (UpdateTimer != null) UpdateTimer = null; UpdateTimer = new Timer(new TimerCallback(UpdateTimer_Elapsed)); UpdateTimer.Change(100, 100); @@ -41,8 +43,9 @@ namespace Simian.Extensions { agent.Avatar.Velocity.X = 0f; - Vector3 fwd = Vector3.Transform(Vector3.UnitX, Matrix4.CreateFromQuaternion(agent.Avatar.Rotation)); - Vector3 left = Vector3.Transform(Vector3.UnitY, Matrix4.CreateFromQuaternion(agent.Avatar.Rotation)); + Matrix4 rotMatrix = Matrix4.CreateFromQuaternion(agent.Avatar.Rotation); + Vector3 fwd = Vector3.Transform(Vector3.UnitX, rotMatrix); + Vector3 left = Vector3.Transform(Vector3.UnitY, rotMatrix); bool heldForward = (agent.ControlFlags & AgentManager.ControlFlags.AGENT_CONTROL_AT_POS) == AgentManager.ControlFlags.AGENT_CONTROL_AT_POS; bool heldBack = (agent.ControlFlags & AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG; @@ -52,67 +55,21 @@ namespace Simian.Extensions bool heldDown = (agent.ControlFlags & AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG; bool flying = (agent.ControlFlags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) == AgentManager.ControlFlags.AGENT_CONTROL_FLY; - float speed = flying ? FLY_SPEED : WALK_SPEED; + 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; } + + float oldFloor = GetLandHeightAt(agent.Avatar.Position); + float newFloor = GetLandHeightAt(agent.Avatar.Position + move); + float lowerLimit = newFloor + agent.Avatar.Scale.Z / 2; + + float speed = flying ? FLY_SPEED : agent.Running ? RUN_SPEED : WALK_SPEED; if ((heldForward || heldBack) && (heldLeft || heldRight)) speed /= SQRT_TWO; - if (heldForward) - { - agent.Avatar.Position.X += fwd.X * speed; - agent.Avatar.Position.Y += fwd.Y * speed; - agent.Avatar.Velocity.X += fwd.X * speed; - agent.Avatar.Velocity.Y += fwd.Y * speed; - } - if (heldBack) - { - agent.Avatar.Position.X -= fwd.X * speed; - agent.Avatar.Position.Y -= fwd.Y * speed; - agent.Avatar.Velocity.X -= fwd.X * speed; - agent.Avatar.Velocity.Y -= fwd.Y * speed; - } - if (heldLeft) - { - agent.Avatar.Position.X += left.X * speed; - agent.Avatar.Position.Y += left.Y * speed; - agent.Avatar.Velocity.X += left.X * speed; - agent.Avatar.Velocity.Y += left.Y * speed; - } - if (heldRight) - { - agent.Avatar.Position.X -= left.X * speed; - agent.Avatar.Position.Y -= left.Y * speed; - agent.Avatar.Velocity.X -= left.X * speed; - agent.Avatar.Velocity.Y -= left.Y * speed; - } - - int x = (int)agent.Avatar.Position.X; - int y = (int)agent.Avatar.Position.Y; - - if (x > 255) x = 255; - else if (x < 0) x = 0; - if (y > 255) y = 255; - else if (y < 0) y = 0; - - float center = Server.Heightmap[y * 256 + x]; - float distX = agent.Avatar.Position.X - (int)agent.Avatar.Position.X; - float distY = agent.Avatar.Position.Y - (int)agent.Avatar.Position.Y; - - float nearestX; - float nearestY; - - if (distX > 0) nearestX = Server.Heightmap[y * 256 + x + (x < 255 ? 1 : 0)]; - else nearestX = Server.Heightmap[y * 256 + x - (x > 0 ? 1 : 0)]; - - if (distY > 0) nearestY = Server.Heightmap[(y + (y < 255 ? 1 : 0)) * 256 + x]; - else nearestY = Server.Heightmap[(y - (y > 0 ? 1 : 0)) * 256 + x]; - - float lerpX = Utils.Lerp(center, nearestX, Math.Abs(distX)); - float lerpY = Utils.Lerp(center, nearestY, Math.Abs(distY)); - - float floor = ((lerpX + lerpY) / 2) + agent.Avatar.Scale.Z / 2; - - if (flying) { if (heldUp) @@ -121,7 +78,12 @@ namespace Simian.Extensions if (heldDown) agent.Avatar.Position.Z -= speed; } - else agent.Avatar.Position.Z = floor; + else agent.Avatar.Position.Z = lowerLimit; + + agent.Avatar.Position.X += move.X * speed; + agent.Avatar.Position.Y += move.Y * speed; + agent.Avatar.Velocity.X += move.X * speed; + agent.Avatar.Velocity.Y += move.Y * speed; if (agent.Avatar.Position.X < 0) agent.Avatar.Position.X = 0f; else if (agent.Avatar.Position.X > 255) agent.Avatar.Position.X = 255f; @@ -129,7 +91,7 @@ namespace Simian.Extensions if (agent.Avatar.Position.Y < 0) agent.Avatar.Position.Y = 0f; else if (agent.Avatar.Position.Y > 255) agent.Avatar.Position.Y = 255f; - if (agent.Avatar.Position.Z < floor) agent.Avatar.Position.Z = floor; + if (agent.Avatar.Position.Z < lowerLimit) agent.Avatar.Position.Z = lowerLimit; } } @@ -151,6 +113,42 @@ namespace Simian.Extensions } } + void SetAlwaysRunHandler(Packet packet, Agent agent) + { + SetAlwaysRunPacket run = (SetAlwaysRunPacket)packet; + + agent.Running = run.AgentData.AlwaysRun; + } + + float GetLandHeightAt(Vector3 position) + { + int x = (int)position.X; + int y = (int)position.Y; + + if (x > 255) x = 255; + else if (x < 0) x = 0; + if (y > 255) y = 255; + else if (y < 0) y = 0; + + float center = Server.Heightmap[y * 256 + x]; + float distX = position.X - (int)position.X; + float distY = position.Y - (int)position.Y; + + float nearestX; + float nearestY; + + if (distX > 0) nearestX = Server.Heightmap[y * 256 + x + (x < 255 ? 1 : 0)]; + else nearestX = Server.Heightmap[y * 256 + x - (x > 0 ? 1 : 0)]; + + if (distY > 0) nearestY = Server.Heightmap[(y + (y < 255 ? 1 : 0)) * 256 + x]; + else nearestY = Server.Heightmap[(y - (y > 0 ? 1 : 0)) * 256 + x]; + + float lerpX = Utils.Lerp(center, nearestX, Math.Abs(distX)); + float lerpY = Utils.Lerp(center, nearestY, Math.Abs(distY)); + + return ((lerpX + lerpY) / 2); + } + ObjectUpdatePacket BuildFullUpdate(Agent agent, LLObject obj, byte state, uint flags) { byte[] objectData = new byte[60];