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
@@ -321,16 +321,6 @@ namespace Barotrauma
l.body.SetTransform(l.SimPosition, l.body.SetTransform(l.SimPosition,
-l.body.Rotation); -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() private void Mirror()
@@ -1083,17 +1083,6 @@ namespace Barotrauma
hand.body.SmoothRotate((ang2 + handAngle * Dir), 100.0f * force); 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() public override void Flip()
{ {
base.Flip(); base.Flip();
@@ -941,18 +941,6 @@ namespace Barotrauma
{ {
case Physics.CollisionStairs: case Physics.CollisionStairs:
if (inWater && TargetMovement.Y < 0.5f) return -1; 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; break;
case Physics.CollisionPlatform: case Physics.CollisionPlatform:
Structure platform = fixture.Body.UserData as Structure; Structure platform = fixture.Body.UserData as Structure;
@@ -1040,7 +1028,7 @@ namespace Barotrauma
protected void CheckDistFromCollider() 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 //if the ragdoll is too far from the collider, disable collisions until it's close enough
//(in case the ragdoll has gotten stuck somewhere) //(in case the ragdoll has gotten stuck somewhere)
@@ -1055,19 +1043,20 @@ namespace Barotrauma
} }
else if (collisionsDisabled) 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(); UpdateCollisionCategories();
collisionsDisabled = false; collisionsDisabled = false;
} }
} }
float t = 0.0f;
private void UpdateNetPlayerPosition(float deltaTime) private void UpdateNetPlayerPosition(float deltaTime)
{ {
if (character.MemPos.Count < 2) return;
if (character == GameMain.NetworkMember.Character) if (character == GameMain.NetworkMember.Character)
{ {
if (character.MemPos.Count < 2) return;
PosInfo serverPos = character.MemPos.Last(); PosInfo serverPos = character.MemPos.Last();
int localPosIndex = character.MemLocalPos.FindIndex(m => m.ID == serverPos.ID); int localPosIndex = character.MemLocalPos.FindIndex(m => m.ID == serverPos.ID);
@@ -1086,46 +1075,10 @@ namespace Barotrauma
} }
else else
{ {
PosInfo prev = character.MemPos[0]; collider.CorrectPosition(character.MemPos, deltaTime, out overrideTargetMovement);
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);
}
} }
} }
public virtual Vector2 EstimateCurrPosition(Vector2 prevPosition, float timePassed)
{
return prevPosition;
}
private Vector2 GetFlowForce() private Vector2 GetFlowForce()
{ {
Vector2 limbPos = ConvertUnits.ToDisplayUnits(Limbs[0].SimPosition); Vector2 limbPos = ConvertUnits.ToDisplayUnits(Limbs[0].SimPosition);
+33 -26
View File
@@ -798,14 +798,23 @@ namespace Barotrauma
if (length > 0.0f) targetMovement = targetMovement / length; if (length > 0.0f) targetMovement = targetMovement / length;
} }
if (AnimController is HumanoidAnimController && if (IsKeyDown(InputType.Run))
!((HumanoidAnimController)AnimController).Crouching &&
Math.Sign(targetMovement.X) != -Math.Sign(AnimController.Dir) &&
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; targetMovement *= SpeedMultiplier;
SpeedMultiplier = 1.0f; SpeedMultiplier = 1.0f;
@@ -1845,41 +1854,39 @@ namespace Barotrauma
{ {
msg.Write(ID); msg.Write(ID);
//todo: only write this if sending for the client who's controlling the character? if (this == c.Character)
msg.Write((UInt32)(LastNetworkUpdateID - memInput.Count)); {
//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(AnimController.Dir > 0.0f);
msg.Write(SimPosition.X); msg.Write(SimPosition.X);
msg.Write(SimPosition.Y); msg.Write(SimPosition.Y);
}
public static void ClientReadStatic(NetIncomingMessage msg, float sendingTime) msg.WritePadBits();
{
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);
}
} }
public virtual void ClientRead(NetIncomingMessage msg, float sendingTime) 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(); bool facingRight = msg.ReadBoolean();
Vector2 pos = new Vector2(msg.ReadFloat(), msg.ReadFloat()); Vector2 pos = new Vector2(msg.ReadFloat(), msg.ReadFloat());
var posInfo = var posInfo =
GameMain.NetworkMember.Character == this ? GameMain.NetworkMember.Character == this ?
new PosInfo(pos, facingRight ? Direction.Right : Direction.Left, networkUpdateID) : new PosInfo(pos, facingRight ? Direction.Right : Direction.Left, networkUpdateID) :
+14 -1
View File
@@ -707,7 +707,20 @@ namespace Barotrauma.Networking
lastSentChatMsgID = inc.ReadUInt32(); lastSentChatMsgID = inc.ReadUInt32();
break; break;
case ServerNetObject.CHARACTER_POSITION: 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(); inc.ReadPadBits();
break; break;
case ServerNetObject.CHAT_MESSAGE: case ServerNetObject.CHAT_MESSAGE:
+41
View File
@@ -53,6 +53,8 @@ namespace Barotrauma
Vector2 offsetFromTargetPos; Vector2 offsetFromTargetPos;
private float netInterpolationState;
public Shape BodyShape public Shape BodyShape
{ {
get { return bodyShape; } get { return bodyShape; }
@@ -462,6 +464,45 @@ namespace Barotrauma
1.0f, SpriteEffects.None, 0.0f); 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> /// <summary>
/// rotate the body towards the target rotation in the "shortest direction" /// rotate the body towards the target rotation in the "shortest direction"