Moved collider position correction logic to the physicsbody class (so that it can be used for sub & item syncing), character position msg length is written in bytes instead of bits, misc cleanup/refactoring

This commit is contained in:
Regalis
2016-10-19 19:10:15 +03:00
parent b4389277aa
commit e2d0e7fe24
6 changed files with 98 additions and 105 deletions

View File

@@ -321,16 +321,6 @@ namespace Barotrauma
l.body.SetTransform(l.SimPosition,
-l.body.Rotation);
}
}
public override Vector2 EstimateCurrPosition(Vector2 prevPosition, float timePassed)
{
timePassed = MathHelper.Clamp(timePassed, 0.0f, 1.0f);
Vector2 currPosition = prevPosition + targetMovement * timePassed;
return currPosition;
}
private void Mirror()

View File

@@ -1083,17 +1083,6 @@ namespace Barotrauma
hand.body.SmoothRotate((ang2 + handAngle * Dir), 100.0f * force);
}
public override Vector2 EstimateCurrPosition(Vector2 prevPosition, float timePassed)
{
timePassed = MathHelper.Clamp(timePassed, 0.0f, 1.0f);
Vector2 targetMovement = character.GetTargetMovement();
Vector2 currPosition = prevPosition + targetMovement * timePassed / 500.0f;
return currPosition;
}
public override void Flip()
{
base.Flip();

View File

@@ -941,18 +941,6 @@ namespace Barotrauma
{
case Physics.CollisionStairs:
if (inWater && TargetMovement.Y < 0.5f) return -1;
//Structure structure = fixture.Body.UserData as Structure;
//if (stairs == null && structure != null)
//{
// if (LowestLimb.SimPosition.Y < structure.SimPosition.Y)
// {
// return -1;
// }
// else
// {
// stairs = structure;
// }
//}
break;
case Physics.CollisionPlatform:
Structure platform = fixture.Body.UserData as Structure;
@@ -1040,7 +1028,7 @@ namespace Barotrauma
protected void CheckDistFromCollider()
{
float allowedDist = Math.Max(Math.Max(collider.radius, collider.width), collider.height);
float allowedDist = Math.Max(Math.Max(collider.radius, collider.width), collider.height) * 2.0f;
//if the ragdoll is too far from the collider, disable collisions until it's close enough
//(in case the ragdoll has gotten stuck somewhere)
@@ -1055,19 +1043,20 @@ namespace Barotrauma
}
else if (collisionsDisabled)
{
//set the position of the ragdoll to make sure limbs don't get stuck inside walls when re-enabling collisions
SetPosition(MainLimb.SimPosition, true);
UpdateCollisionCategories();
collisionsDisabled = false;
}
}
float t = 0.0f;
private void UpdateNetPlayerPosition(float deltaTime)
{
if (character.MemPos.Count < 2) return;
if (character == GameMain.NetworkMember.Character)
{
if (character.MemPos.Count < 2) return;
PosInfo serverPos = character.MemPos.Last();
int localPosIndex = character.MemLocalPos.FindIndex(m => m.ID == serverPos.ID);
@@ -1086,46 +1075,10 @@ namespace Barotrauma
}
else
{
PosInfo prev = character.MemPos[0];
PosInfo next = character.MemPos[1];
Vector2 currPos = collider.SimPosition;
//interpolate the position of the collider from the first position in the buffer towards the second
if (prev.Timestamp < next.Timestamp)
{
//if there are more than 2 positions in the buffer,
//increase the interpolation speed to catch up with the server
float speedMultiplier = 1.0f + (float)Math.Pow((character.MemPos.Count - 2) / 2.0f, 2.0f);
t += (deltaTime * speedMultiplier) / (next.Timestamp - prev.Timestamp);
currPos = Vector2.Lerp(prev.Position, next.Position, t);
//override the targetMovement to make the character play the walking/running animation
overrideTargetMovement = (next.Position - prev.Position) / (next.Timestamp - prev.Timestamp);
}
else
{
currPos = next.Position;
t = 1.0f;
}
collider.SetTransform(currPos, collider.Rotation);
if (t >= 1.0f)
{
t = 0.0f;
character.MemPos.RemoveAt(0);
}
collider.CorrectPosition(character.MemPos, deltaTime, out overrideTargetMovement);
}
}
public virtual Vector2 EstimateCurrPosition(Vector2 prevPosition, float timePassed)
{
return prevPosition;
}
private Vector2 GetFlowForce()
{
Vector2 limbPos = ConvertUnits.ToDisplayUnits(Limbs[0].SimPosition);

View File

@@ -798,14 +798,23 @@ namespace Barotrauma
if (length > 0.0f) targetMovement = targetMovement / length;
}
if (AnimController is HumanoidAnimController &&
!((HumanoidAnimController)AnimController).Crouching &&
Math.Sign(targetMovement.X) != -Math.Sign(AnimController.Dir) &&
IsKeyDown(InputType.Run))
if (IsKeyDown(InputType.Run))
{
targetMovement *= 3.0f;
//can't run if
// - not a humanoid
// - dragging someone
// - crouching
// - moving backwards
if (AnimController is HumanoidAnimController &&
selectedCharacter == null &&
!((HumanoidAnimController)AnimController).Crouching &&
Math.Sign(targetMovement.X) != -Math.Sign(AnimController.Dir))
{
targetMovement *= 3.0f;
}
}
targetMovement *= SpeedMultiplier;
SpeedMultiplier = 1.0f;
@@ -1845,41 +1854,39 @@ namespace Barotrauma
{
msg.Write(ID);
//todo: only write this if sending for the client who's controlling the character?
msg.Write((UInt32)(LastNetworkUpdateID - memInput.Count));
if (this == c.Character)
{
//length of the message
msg.Write((byte)(4+4+4+4));
msg.Write(true);
msg.Write((UInt32)(LastNetworkUpdateID - memInput.Count));
}
else
{
//length of the message
msg.Write((byte)(4+4+4));
msg.Write(false);
}
msg.Write(AnimController.Dir > 0.0f);
msg.Write(SimPosition.X);
msg.Write(SimPosition.Y);
}
public static void ClientReadStatic(NetIncomingMessage msg, float sendingTime)
{
UInt16 id = msg.ReadUInt16();
var character = Entity.FindEntityByID(id) as Character;
if (character == null)
{
//skip through the rest of the message
//todo: a better way to skip through the message?
msg.Position += 32 + 1 + 32 + 32;
}
else
{
character.ClientRead(msg, sendingTime);
}
msg.WritePadBits();
}
public virtual void ClientRead(NetIncomingMessage msg, float sendingTime)
{
UInt32 networkUpdateID = msg.ReadUInt32();
UInt32 networkUpdateID = 0;
if (msg.ReadBoolean())
{
networkUpdateID = msg.ReadUInt32();
}
//float sendingTime = msg.ReadSingle();
bool facingRight = msg.ReadBoolean();
Vector2 pos = new Vector2(msg.ReadFloat(), msg.ReadFloat());
var posInfo =
GameMain.NetworkMember.Character == this ?
new PosInfo(pos, facingRight ? Direction.Right : Direction.Left, networkUpdateID) :

View File

@@ -707,7 +707,20 @@ namespace Barotrauma.Networking
lastSentChatMsgID = inc.ReadUInt32();
break;
case ServerNetObject.CHARACTER_POSITION:
Character.ClientReadStatic(inc, sendingTime);
UInt16 id = inc.ReadUInt16();
byte msgLength = inc.ReadByte();
var character = Entity.FindEntityByID(id) as Character;
if (character == null)
{
//skip through the rest of the message
inc.Position += msgLength * 8;
}
else
{
character.ClientRead(inc, sendingTime);
}
inc.ReadPadBits();
break;
case ServerNetObject.CHAT_MESSAGE:

View File

@@ -53,6 +53,8 @@ namespace Barotrauma
Vector2 offsetFromTargetPos;
private float netInterpolationState;
public Shape BodyShape
{
get { return bodyShape; }
@@ -461,6 +463,45 @@ namespace Barotrauma
new Vector2(bodyShapeTexture.Width / 2, bodyShapeTexture.Height / 2),
1.0f, SpriteEffects.None, 0.0f);
}
public void CorrectPosition(List<PosInfo> positionBuffer, float deltaTime, out Vector2 newVelocity)
{
newVelocity = Vector2.Zero;
if (positionBuffer.Count < 2) return;
PosInfo prev = positionBuffer[0];
PosInfo next = positionBuffer[1];
Vector2 currPos = SimPosition;
//interpolate the position of the collider from the first position in the buffer towards the second
if (prev.Timestamp < next.Timestamp)
{
//if there are more than 2 positions in the buffer,
//increase the interpolation speed to catch up with the server
float speedMultiplier = 1.0f + (float)Math.Pow((positionBuffer.Count - 2) / 2.0f, 2.0f);
netInterpolationState += (deltaTime * speedMultiplier) / (next.Timestamp - prev.Timestamp);
currPos = Vector2.Lerp(prev.Position, next.Position, netInterpolationState);
//override the targetMovement to make the character play the walking/running animation
newVelocity = (next.Position - prev.Position) / (next.Timestamp - prev.Timestamp);
}
else
{
currPos = next.Position;
netInterpolationState = 1.0f;
}
SetTransform(currPos, Rotation);
if (netInterpolationState >= 1.0f)
{
netInterpolationState = 0.0f;
positionBuffer.RemoveAt(0);
}
}
/// <summary>