fix: PhysicsComponent created with GetOrCreate<T> is unusable (#2422)
* Run proper Rigidbody setup when adding ColliderShape
* Added test case for proper setup with GetOrCreate
* Followed similar Bepu format with creation of ReAttach method
* Reformatted files edited
* Revert "Reformatted files edited"
This reverts commit 1c9b03eb6e
.
This commit is contained in:
Родитель
c424213701
Коммит
32e341ca05
|
@ -37,7 +37,7 @@ namespace Stride.Physics.Tests
|
|||
if (hitResult.Succeeded)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
|
@ -243,6 +243,51 @@ namespace Stride.Physics.Tests
|
|||
Assert.Equal(0.0f, (new Vector3(-2.861034E-06f, 3.889218E-06f, -1f) - hit.Normal).Length(), 3f);
|
||||
Assert.Equal(0.0f, (new Vector3(-5.366335f, -0.08297831f, -17.9267f) - hit.Point).Length(), 3f);
|
||||
|
||||
game.Exit();
|
||||
});
|
||||
RunGameTest(game);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Verify PhysicsComponent creation through the use of GetOrCreate<T>
|
||||
/// If component is added this way, must ensure ColliderShape is properly setup if added later
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public void VerifyColliderShapeSetup()
|
||||
{
|
||||
var game = new ColliderShapesTest();
|
||||
game.Script.AddTask(async () =>
|
||||
{
|
||||
game.ScreenShotAutomationEnabled = false;
|
||||
await game.Script.NextFrame();
|
||||
await game.Script.NextFrame();
|
||||
|
||||
var simulation = game.SceneSystem.SceneInstance.RootScene.Entities.First(ent => ent.Name == "Simulation").Get<StaticColliderComponent>().Simulation;
|
||||
var cube = game.SceneSystem.SceneInstance.RootScene.Entities.First(ent => ent.Name == "CubePrefab1");
|
||||
|
||||
var body = cube.GetOrCreate<RigidbodyComponent>();
|
||||
|
||||
//verify values not properly set up
|
||||
Assert.Null(body.ColliderShape);
|
||||
Assert.Equal(RigidBodyTypes.Static, body.RigidBodyType);
|
||||
Assert.False(body.OverrideGravity);
|
||||
|
||||
//for further debug, can set breakpoint and check body.Simulation.discreteDynamicWorld.CollisionObjectArray before and after
|
||||
//the collider shape is attached to see it properly added
|
||||
|
||||
//add collider shape
|
||||
body.ColliderShape = new SphereColliderShape(false, 1.0f);
|
||||
//check if proper colliderShape setup took place
|
||||
Assert.True(body.ColliderShape != null);
|
||||
Assert.Equal(ColliderShapeTypes.Sphere, body.ColliderShape.Type);
|
||||
Assert.Equal(RigidBodyTypes.Dynamic, body.RigidBodyType);
|
||||
|
||||
body.OverrideGravity = true;
|
||||
//to verify InternalRigidBody was properly set up we can change properties such as Mass or OverrideGravity
|
||||
//that normally would return void if there are no InternalRigidBody values
|
||||
Assert.True(body.OverrideGravity);
|
||||
|
||||
|
||||
game.Exit();
|
||||
});
|
||||
RunGameTest(game);
|
||||
|
|
|
@ -85,7 +85,11 @@ namespace Stride.Physics
|
|||
|
||||
mass = value;
|
||||
|
||||
if (InternalRigidBody == null) return;
|
||||
if (InternalRigidBody == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
var inertia = ColliderShape.InternalShape.CalculateLocalInertia(value);
|
||||
InternalRigidBody.SetMassProps(value, inertia);
|
||||
|
@ -114,7 +118,11 @@ namespace Stride.Physics
|
|||
return;
|
||||
|
||||
if (InternalRigidBody == null)
|
||||
{
|
||||
//When setting ColliderShape, setup could have been previously skipped (eg when PhysicsComponent is created using GetOrCreate)
|
||||
ReAttach();
|
||||
return;
|
||||
}
|
||||
|
||||
if (NativeCollisionObject != null)
|
||||
NativeCollisionObject.CollisionShape = value.InternalShape;
|
||||
|
@ -193,7 +201,11 @@ namespace Stride.Physics
|
|||
{
|
||||
overrideGravity = value;
|
||||
|
||||
if (InternalRigidBody == null) return;
|
||||
if (InternalRigidBody == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (value)
|
||||
{
|
||||
|
@ -341,6 +353,7 @@ namespace Stride.Physics
|
|||
|
||||
protected override void OnDetach()
|
||||
{
|
||||
|
||||
MotionState.Dispose();
|
||||
MotionState.Clear();
|
||||
|
||||
|
|
|
@ -681,6 +681,32 @@ namespace Stride.Engine
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Ran when properties of Components may not be fully setup and need to be reintegrated (eg GetOrCreate<RigidbodyComponent> and adding collidershapes)
|
||||
/// </summary>
|
||||
internal void ReAttach()
|
||||
{
|
||||
//TODO: Could consider fully detaching and then rebuilding, but ideally this would cause null refs on Rigidbody OnDetach calls
|
||||
//Shouldnt call detach, because at this point the user has added new components and this runs as a check to rebuild as needed.
|
||||
//Entire wipes to rebuild causes loss in the data that the user has just added (and is slower)
|
||||
|
||||
Entity.Transform.UpdateWorldMatrix();
|
||||
|
||||
BoneIndex = -1;
|
||||
|
||||
OnAttach();
|
||||
|
||||
//ensure ignore collisions
|
||||
if (ignoreCollisionBuffer != null && NativeCollisionObject != null)
|
||||
{
|
||||
foreach (var kvp in ignoreCollisionBuffer)
|
||||
{
|
||||
IgnoreCollisionWith(kvp.Key, kvp.Value);
|
||||
}
|
||||
ignoreCollisionBuffer = null;
|
||||
}
|
||||
}
|
||||
|
||||
internal void Detach()
|
||||
{
|
||||
Data = null;
|
||||
|
|
Загрузка…
Ссылка в новой задаче