Lighting optimization (caching shadow vertices & only checking hulls in range if the position or range of the light changes), ragdoll optimization, itemcomponent optimization, dragging stunned/dead characters

This commit is contained in:
Regalis11
2015-10-11 21:04:42 +03:00
parent 0a96254696
commit 8df9133e84
25 changed files with 377 additions and 201 deletions
@@ -57,5 +57,6 @@ namespace Subsurface
public virtual void HoldItem(float deltaTime, Item item, Vector2[] handlePos, Vector2 holdPos, Vector2 aimPos, bool aim, float holdAngle) { }
public virtual void DragCharacter(Character target) { }
}
}
+30 -10
View File
@@ -578,14 +578,14 @@ namespace Subsurface
maxDist = ConvertUnits.ToSimUnits(maxDist);
foreach (Character c in Character.CharacterList)
foreach (Character c in CharacterList)
{
if (c == this) continue;
if (Vector2.Distance(SimPosition, c.SimPosition) > maxDist) continue;
float dist = Vector2.Distance(mouseSimPos, c.SimPosition);
if (dist < maxDist && closestCharacter==null || dist<closestDist)
if (dist < maxDist && (closestCharacter==null || dist<closestDist))
{
closestCharacter = c;
closestDist = dist;
@@ -596,6 +596,22 @@ namespace Subsurface
return closestCharacter;
}
private void ToggleSelectedCharacter(Character selected)
{
if (selectedCharacter != null)
{
foreach (Limb limb in selectedCharacter.AnimController.Limbs)
{
limb.pullJoint.Enabled = false;
}
selectedCharacter = null;
}
else
{
selectedCharacter = selected;
}
}
/// <summary>
/// Control the character according to player input
/// </summary>
@@ -659,7 +675,7 @@ namespace Subsurface
closestCharacter = FindClosestCharacter(mouseSimPos);
if (closestCharacter != null)
{
if (closestCharacter != selectedCharacter) selectedCharacter = null;
// if (closestCharacter != selectedCharacter) selectedCharacter = null;
if (!closestCharacter.IsHumanoid) closestCharacter = null;
}
@@ -697,21 +713,25 @@ namespace Subsurface
}
else
{
if (Vector2.Distance(selectedCharacter.SimPosition, SimPosition) > 2.0f) selectedCharacter = null;
if (Vector2.Distance(selectedCharacter.SimPosition, SimPosition) > 2.0f ||
(!selectedCharacter.isDead && selectedCharacter.Stun <= 0.0f))
{
ToggleSelectedCharacter(selectedCharacter);
}
}
if (GetInputState(InputType.Select))
{
if (selectedCharacter != null)
{
selectedCharacter = null;
ToggleSelectedCharacter(selectedCharacter);
}
else if (closestCharacter != null && closestCharacter.isDead && closestCharacter.IsHumanoid)
else if (closestCharacter != null && closestCharacter.IsHumanoid &&
(closestCharacter.isDead || closestCharacter.AnimController.StunTimer > 0.0f))
{
selectedCharacter = closestCharacter;
}
}
}
DisableControls = false;
}
@@ -741,7 +761,7 @@ namespace Subsurface
public virtual void Update(Camera cam, float deltaTime)
{
//AnimController.SimplePhysicsEnabled = (Character.controlled!=this && Vector2.Distance(cam.WorldViewCenter, Position)>5000.0f);
AnimController.SimplePhysicsEnabled = (Character.controlled!=this && Vector2.Distance(cam.WorldViewCenter, Position)>5000.0f);
if (isDead) return;
@@ -825,7 +845,7 @@ namespace Subsurface
Vector2 pos = ConvertUnits.ToDisplayUnits(AnimController.Limbs[0].SimPosition);
pos.Y = -pos.Y;
if (this == Character.controlled) return;
if (this == controlled) return;
if (IsNetworkPlayer)
{
+1 -1
View File
@@ -54,7 +54,7 @@ namespace Subsurface
//if (Vector2.Distance(selectedCharacter.SimPosition, SimPosition) > 2.0f) selectedCharacter = null;
}
if (character.ClosestCharacter != null && character.ClosestCharacter.IsDead)
if (character.ClosestCharacter != null && (character.ClosestCharacter.IsDead || character.ClosestCharacter.Stun > 0.0f))
{
Vector2 startPos = character.Position + (character.ClosestCharacter.Position - character.Position) * 0.7f;
startPos = cam.WorldToScreen(startPos);
@@ -225,11 +225,9 @@ namespace Subsurface
RefLimb.body.Rotation + MathUtils.GetShortestAngle(RefLimb.body.Rotation, movementAngle) :
HeadAngle*Dir);
RefLimb.pullJoint.Enabled = true;
RefLimb.pullJoint.WorldAnchorB =
RefLimb.SimPosition + movement * 0.1f;
RefLimb.body.LinearVelocity = movement;
RefLimb.body.SmoothRotate(0.0f);
//RefLimb.body.SmoothRotate(0.0f);
foreach (Limb l in Limbs)
{
@@ -36,66 +36,77 @@ namespace Subsurface
//if (inWater) stairs = null;
if (onFloorTimer <= 0.0f && !SimplePhysicsEnabled)
{
Vector2 rayStart = colliderPos; // at the bottom of the player sprite
Vector2 rayEnd = rayStart - new Vector2(0.0f, TorsoPosition);
if (stairs != null) rayEnd.Y -= 0.5f;
if (Anim != Animation.UsingConstruction) ResetPullJoints();
//do a raytrace straight down from the torso to figure
//out whether the ragdoll is standing on ground
float closestFraction = 1;
Structure closestStructure = null;
GameMain.World.RayCast((fixture, point, normal, fraction) =>
{
switch (fixture.CollisionCategories)
//do a raytrace straight down from the torso to figure
//out whether the ragdoll is standing on ground
float closestFraction = 1;
Structure closestStructure = null;
GameMain.World.RayCast((fixture, point, normal, fraction) =>
{
case Physics.CollisionStairs:
if (inWater && TargetMovement.Y < 0.5f) return -1;
switch (fixture.CollisionCategories)
{
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;
if (IgnorePlatforms || LowestLimb.Position.Y < platform.Rect.Y) return -1;
break;
case Physics.CollisionWall:
break;
default:
return -1;
}
onGround = true;
if (fraction < closestFraction)
{
closestFraction = fraction;
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;
if (IgnorePlatforms || LowestLimb.Position.Y < platform.Rect.Y) return -1;
break;
case Physics.CollisionWall:
break;
default:
return -1;
if (structure != null) closestStructure = structure;
}
onFloorTimer = 0.05f;
return closestFraction;
}
, rayStart, rayEnd);
onGround = true;
if (fraction < closestFraction)
if (closestStructure != null && closestStructure.StairDirection != Direction.None)
{
closestFraction = fraction;
Structure structure = fixture.Body.UserData as Structure;
if (structure != null) closestStructure = structure;
stairs = closestStructure;
}
else
{
stairs = null;
}
onFloorTimer = 0.05f;
return closestFraction;
}
, rayStart, rayEnd);
if (closestStructure != null && closestStructure.StairDirection != Direction.None)
{
stairs = closestStructure;
}
else
{
stairs = null;
if (closestFraction == 1) //raycast didn't hit anything
{
floorY = (currentHull == null) ? -1000.0f : ConvertUnits.ToSimUnits(currentHull.Rect.Y - currentHull.Rect.Height);
}
else
{
floorY = rayStart.Y + (rayEnd.Y - rayStart.Y) * closestFraction;
}
}
//the ragdoll "stays on ground" for 50 millisecs after separation
if (onFloorTimer <= 0.0f)
{
@@ -110,15 +121,6 @@ namespace Subsurface
onFloorTimer -= deltaTime;
}
if (closestFraction == 1) //raycast didn't hit anything
{
floorY = (currentHull == null) ? -1000.0f : ConvertUnits.ToSimUnits(currentHull.Rect.Y - currentHull.Rect.Height);
}
else
{
floorY = rayStart.Y + (rayEnd.Y - rayStart.Y) * closestFraction;
}
IgnorePlatforms = (TargetMovement.Y < 0.0f);
@@ -131,11 +133,12 @@ namespace Subsurface
if (stunTimer > 0)
{
//UpdateStruggling();
stunTimer -= deltaTime;
return;
}
if (Anim != Animation.UsingConstruction) ResetPullJoints();
if (TargetDir != dir) Flip();
if (SimplePhysicsEnabled)
@@ -191,6 +194,10 @@ namespace Subsurface
Limb leftLeg = GetLimb(LimbType.LeftLeg);
Limb rightLeg = GetLimb(LimbType.RightLeg);
if (character.SelectedCharacter != null) DragCharacter(character.SelectedCharacter);
float getUpSpeed = 0.3f;
float walkCycleSpeed = head.LinearVelocity.X * walkAnimSpeed;
if (stairs != null)
@@ -751,6 +758,27 @@ namespace Subsurface
// }
//}
public override void DragCharacter(Character target)
{
Limb leftHand = GetLimb(LimbType.LeftHand);
Limb rightHand = GetLimb(LimbType.RightHand);
leftHand.Disabled = true;
rightHand.Disabled = true;
Limb targetLimb = target.AnimController.GetLimb(LimbType.LeftHand);
leftHand.pullJoint.Enabled = true;
leftHand.pullJoint.WorldAnchorB = targetLimb.SimPosition;
rightHand.pullJoint.Enabled = true;
rightHand.pullJoint.WorldAnchorB = targetLimb.SimPosition;
targetLimb.pullJoint.Enabled = true;
targetLimb.pullJoint.WorldAnchorB = leftHand.SimPosition;
target.AnimController.IgnorePlatforms = IgnorePlatforms;
}
public override void HoldItem(float deltaTime, Item item, Vector2[] handlePos, Vector2 holdPos, Vector2 aimPos, bool aim, float holdAngle)
{
//calculate the handle positions