@@ -21,7 +21,7 @@ public partial class PhysicsSystem : SystemBase, IListener<RaycastRequest>, ILis
2121 private readonly List < RaycastHit > hits ;
2222 private readonly List < uint > toRemove ;
2323 private readonly List < uint > usedShapes ;
24- private readonly Array < BodyState > physicsObjectState ;
24+ private readonly Array < PhysicsObjectState > physicsObjectStates ;
2525 private readonly Dictionary < uint , CompiledBody > bodies ;
2626 private readonly Dictionary < uint , CompiledShape > shapes ;
2727 private readonly Dictionary < ( int , bool ) , uint > handleToBody ;
@@ -53,7 +53,7 @@ public PhysicsSystem(Simulator simulator, World world) : base(simulator)
5353 hits = new ( ) ;
5454 toRemove = new ( ) ;
5555 usedShapes = new ( ) ;
56- physicsObjectState = new ( ) ;
56+ physicsObjectStates = new ( ) ;
5757 bodies = new ( ) ;
5858 shapes = new ( ) ;
5959 handleToBody = new ( ) ;
@@ -90,7 +90,7 @@ public override void Dispose()
9090 handleToBody . Dispose ( ) ;
9191 shapes . Dispose ( ) ;
9292 bodies . Dispose ( ) ;
93- physicsObjectState . Dispose ( ) ;
93+ physicsObjectStates . Dispose ( ) ;
9494 bepuSimulation . Dispose ( ) ;
9595 bufferPool . Dispose ( ) ;
9696 gravity . Dispose ( ) ;
@@ -117,14 +117,30 @@ void IListener<PhysicsUpdate>.Receive(ref PhysicsUpdate message)
117117 gravity . Write ( GetGlobalGravity ( ) ) ;
118118 AddMissingComponents ( ) ;
119119 ApplyPointGravity ( message . deltaTime ) ;
120- CreateAndDestroyPhysicsObjects ( ) ;
120+
121+ // create shapes and bodies for entities that dont have them yet
122+ int capacity = ( world . MaxEntityValue + 1 ) . GetNextPowerOf2 ( ) ;
123+ int currentLength = this . physicsObjectStates . Length ;
124+ if ( currentLength < capacity )
125+ {
126+ this . physicsObjectStates . Length = capacity ;
127+
128+ // reset the new entires to default
129+ for ( int i = currentLength ; i < capacity ; i ++ )
130+ {
131+ this . physicsObjectStates [ i ] = default ;
132+ }
133+ }
134+
135+ Span < PhysicsObjectState > physicsObjectStates = this . physicsObjectStates . AsSpan ( ) ;
136+ CreateAndDestroyPhysicsObjects ( physicsObjectStates ) ;
121137
122138 if ( message . deltaTime > 0 )
123139 {
124140 bepuSimulation . Timestep ( ( float ) message . deltaTime ) ;
125141 }
126142
127- CopyPhysicsObjectStateToEntities ( bodyType , ltwType ) ;
143+ CopyPhysicsObjectStateToEntities ( physicsObjectStates ) ;
128144 }
129145
130146 private void ApplyPointGravity ( double deltaTime )
@@ -241,7 +257,7 @@ public uint GetPhysicsEntity(int handle, bool isStatic)
241257 return handleToBody [ ( handle , isStatic ) ] ;
242258 }
243259
244- private void CreateAndDestroyPhysicsObjects ( )
260+ private void CreateAndDestroyPhysicsObjects ( Span < PhysicsObjectState > physicsObjectStates )
245261 {
246262 //remove shapes and bodies of entities that dont exist anymore
247263 toRemove . Clear ( ) ;
@@ -261,7 +277,7 @@ private void CreateAndDestroyPhysicsObjects()
261277 bepuSimulation . Bodies . Remove ( body . DynamicBody ) ;
262278 }
263279
264- physicsObjectState [ ( int ) bodyEntity ] = default ;
280+ physicsObjectStates [ ( int ) bodyEntity ] = default ;
265281 body . Dispose ( ) ;
266282 toRemove . Add ( bodyEntity ) ;
267283 }
@@ -272,13 +288,6 @@ private void CreateAndDestroyPhysicsObjects()
272288 bodies . Remove ( bodyEntity ) ;
273289 }
274290
275- //create shapes and bodies for entities that dont have them yet
276- int capacity = ( world . MaxEntityValue + 1 ) . GetNextPowerOf2 ( ) ;
277- if ( physicsObjectState . Length < capacity )
278- {
279- physicsObjectState . Length = capacity ;
280- }
281-
282291 usedShapes . Clear ( ) ;
283292
284293 ComponentQuery < IsBody , LocalToWorld , WorldRotation > bodyQuery = new ( world ) ;
@@ -329,6 +338,7 @@ private void CreateAndDestroyPhysicsObjects()
329338 usedShapes . Add ( shapeHash ) ;
330339
331340 //make sure a physics body exists for this combination of (shape, type)
341+ ref PhysicsObjectState state = ref physicsObjectStates [ ( int ) entity ] ;
332342 bool isStatic = type == BodyType . Static ;
333343 Vector3 worldOffset = Vector3 . Transform ( localOffset , ltwRotation ) ;
334344 Vector3 desiredWorldPosition = worldPosition + worldOffset ;
@@ -338,6 +348,10 @@ private void CreateAndDestroyPhysicsObjects()
338348 compiledBody = CreateBody ( body , compiledShape , desiredWorldPosition , desiredWorldRotation ) ;
339349 bodies . Add ( entity , compiledBody ) ;
340350 handleToBody . Add ( ( compiledBody . handle , isStatic ) , entity ) ;
351+ state . position = desiredWorldPosition ;
352+ state . rotation = desiredWorldRotation ;
353+ state . linearVelocity = Vector3 . Zero ;
354+ state . angularVelocity = Vector3 . Zero ;
341355 }
342356 else if ( compiledBody . version != body . version || compiledBody . type != type || newShape )
343357 {
@@ -356,10 +370,13 @@ private void CreateAndDestroyPhysicsObjects()
356370 isStatic = compiledBody . type == BodyType . Static ;
357371 bodies [ entity ] = compiledBody ;
358372 handleToBody . Add ( ( compiledBody . handle , isStatic ) , entity ) ;
373+ state . position = desiredWorldPosition ;
374+ state . rotation = desiredWorldRotation ;
375+ state . linearVelocity = Vector3 . Zero ;
376+ state . angularVelocity = Vector3 . Zero ;
359377 }
360378
361379 //copy values from entity onto physics object (if different from last known state)
362- ref BodyState state = ref physicsObjectState [ ( int ) entity ] ;
363380 if ( isStatic )
364381 {
365382 StaticReference staticReference = bepuSimulation . Statics . GetStaticReference ( compiledBody . StaticBody ) ;
@@ -414,7 +431,7 @@ private void CreateAndDestroyPhysicsObjects()
414431 }
415432 }
416433
417- private void CopyPhysicsObjectStateToEntities ( int bodyType , int ltwType )
434+ private void CopyPhysicsObjectStateToEntities ( Span < PhysicsObjectState > physicsObjectStates )
418435 {
419436 foreach ( uint bodyEntity in bodies . Keys )
420437 {
@@ -430,7 +447,7 @@ private void CopyPhysicsObjectStateToEntities(int bodyType, int ltwType)
430447 StaticDescription description = staticReference . GetDescription ( ) ;
431448 Vector3 finalWorldPosition = description . Pose . Position - worldOffset ;
432449 Quaternion finalWorldRotation = description . Pose . Orientation ;
433- physicsObjectState [ ( int ) bodyEntity ] = new ( finalWorldPosition , finalWorldRotation , Vector3 . Zero , Vector3 . Zero ) ;
450+ physicsObjectStates [ ( int ) bodyEntity ] = new ( finalWorldPosition , finalWorldRotation , Vector3 . Zero , Vector3 . Zero ) ;
434451
435452 //copy bounds
436453 if ( ! world . ContainsComponent < WorldBounds > ( bodyEntity ) )
@@ -477,7 +494,7 @@ private void CopyPhysicsObjectStateToEntities(int bodyType, int ltwType)
477494
478495 ref AngularVelocity angularVelocity = ref world . GetComponent < AngularVelocity > ( bodyEntity ) ;
479496 angularVelocity . value = velocity . Angular ;
480- physicsObjectState [ ( int ) bodyEntity ] = new ( finalWorldPosition , finalWorldRotation , velocity . Linear , velocity . Angular ) ;
497+ physicsObjectStates [ ( int ) bodyEntity ] = new ( finalWorldPosition , finalWorldRotation , velocity . Linear , velocity . Angular ) ;
481498
482499 //copy bounds
483500 if ( ! world . ContainsComponent < WorldBounds > ( bodyEntity ) )
0 commit comments