Closed ScottKane closed 11 months ago
Nothing jumps out at a glance; I'd verify that:
The timestep is definitely being called and the IntegrateVelocity callback is being called. The Transform.Position isn't being updated though. That's what I'm passing in as the RigidPose. Having a system manually moving the entity updated the graphics as expected.
Do I need to manually set my transforms position to the pose position from the body after each physics update? I think RigidPose would have to be a ref struct with Position as a ref field for it to update the position being passed in. How is this normally meant to work? You take a handle to the body and then use the pose position during rendering?
Yup, RigidPose
and Vector3
and such are regular ol' value types and pass by copy, so no updates will feed back through it. Simulation.Bodies.Add
returns a BodyHandle
, and you can get a BodyReference
to the body with Simulation.Bodies[bodyHandle]
. It's a convenience type that provides access to all the body properties, including pose. (You can also do the indirections and go look up data directly, or temporarily cache pointers for accesses, but that's a bit more annoying and usually unnecessary.)
Ok so now I have added a system to copy over the Position
Application
.Default()
.WithEntity(entity =>
{
entity.Set(new Transform
{
Position = new Vector3(0.0f, 0.0f, -5.0f)
});
entity.Set(Model.Load("Models/crate.glb"));
entity.Set(new Box(1, 1, 1));
})
.WithEntity(entity =>
{
entity.Set(new Transform
{
Position = new Vector3(0.0f, -1.5f, -5.0f),
Scale = new Vector3(10.0f, 0.01f, 10f)
});
entity.Set(Model.Load("Models/cube.obj"));
entity.Set(new Box(500, 1, 500));
entity.Set(new Static());
})
.WithSystem<MoveCamera>()
.WithSystem<LogTransform>(Stage.FixedUpdate)
.Run();
public class UpdateTransform : EntitySystem<BodyHandle, Transform>
{
protected override void Run(double delta, in Entity entity, ref BodyHandle handle, ref Transform transform)
{
var simulation = World.Get<Components.Physics>().Simulation;
transform.Position = simulation.Bodies[handle].Pose.Position;
}
}
This produces:
Transform { Position = <-65.96129, 5.8624425, -39.0519>, Rotation = <0, 0, 0>, Scale = <1, 1, 1> }
Transform { Position = <-187.52643, -0.71619415, -111.09422>, Rotation = <0, 0, 0>, Scale = <1, 1, 1> }
Transform { Position = <-187.3982, -0.4079471, -110.98699>, Rotation = <0, 0, 0>, Scale = <1, 1, 1> }
Transform { Position = <-190.50215, -1.4001498, -112.26572>, Rotation = <0, 0, 0>, Scale = <1, 1, 1> }
Considering the cube starts at new Vector3(0.0f, 0.0f, -5.0f)
according to the transfrom, I'm not sure how the first fixed update tick is changing the position so drastically. These positions don't indicate that the cube is falling straight down like it should be, do you have any idea what could be happening?
Nope! It's hard to tell given the layers of indirection involved, but clearly something is wonky.
Double check the time passed to Timestep
; it should be the same every time (in this use case). Peek at the body states after each timestep to see when things go off the rails.
If all else fails, try to reproduce it in the demos. It'll tend to make the problem obvious, or the failure to reproduce the problem will be informative.
omfg... the timestep was 16.666
instead of 0.01666
which just broke everything. Doing 1000 / 60
instead of 1 / 60
...
I'm trying to get started with a simple scenario, a cube to drop onto a plane. I'm using an ECS so I have split everything out to work with that. From what was shown in the self contained demo I'm assuming this should be all I need to get things running simply, however nothing happens when I run the scene. Note the cube.obj is 2x2x2 which is why I have the weird scale/box sizings. Any advice would be greatly appreciated. Thanks