1+ using System ;
12using System . Linq ;
23using System . Numerics ;
34using NUnit . Framework ;
@@ -17,6 +18,13 @@ namespace Robust.UnitTesting.Shared.Physics;
1718[ TestFixture ]
1819internal sealed class RayCast_Test
1920{
21+ public enum SensorCastKind
22+ {
23+ RayAll ,
24+ RayClosest ,
25+ Shape ,
26+ }
27+
2028 private static TestCaseData [ ] _rayCases =
2129 {
2230 // Ray goes through
@@ -55,6 +63,34 @@ internal sealed class RayCast_Test
5563 new ( new SlimPolygon ( Box2 . UnitCentered ) , new Transform ( Vector2 . Zero , Angle . Zero ) , - Vector2 . UnitY , null ) ,
5664 } ;
5765
66+ private static TestCaseData [ ] _sensorCases =
67+ {
68+ new TestCaseData ( SensorCastKind . RayAll , true , false )
69+ . SetName ( "RayCast all returns hard fixtures without sensor query flag" ) ,
70+ new TestCaseData ( SensorCastKind . RayAll , true , true )
71+ . SetName ( "RayCast all returns hard fixtures with sensor query flag" ) ,
72+ new TestCaseData ( SensorCastKind . RayAll , false , false )
73+ . SetName ( "RayCast all filters sensor fixtures without sensor query flag" ) ,
74+ new TestCaseData ( SensorCastKind . RayAll , false , true )
75+ . SetName ( "RayCast all returns sensor fixtures with sensor query flag" ) ,
76+ new TestCaseData ( SensorCastKind . RayClosest , true , false )
77+ . SetName ( "RayCast closest returns hard fixtures without sensor query flag" ) ,
78+ new TestCaseData ( SensorCastKind . RayClosest , true , true )
79+ . SetName ( "RayCast closest returns hard fixtures with sensor query flag" ) ,
80+ new TestCaseData ( SensorCastKind . RayClosest , false , false )
81+ . SetName ( "RayCast closest filters sensor fixtures without sensor query flag" ) ,
82+ new TestCaseData ( SensorCastKind . RayClosest , false , true )
83+ . SetName ( "RayCast closest returns sensor fixtures with sensor query flag" ) ,
84+ new TestCaseData ( SensorCastKind . Shape , true , false )
85+ . SetName ( "ShapeCast returns hard fixtures without sensor query flag" ) ,
86+ new TestCaseData ( SensorCastKind . Shape , true , true )
87+ . SetName ( "ShapeCast returns hard fixtures with sensor query flag" ) ,
88+ new TestCaseData ( SensorCastKind . Shape , false , false )
89+ . SetName ( "ShapeCast filters sensor fixtures without sensor query flag" ) ,
90+ new TestCaseData ( SensorCastKind . Shape , false , true )
91+ . SetName ( "ShapeCast returns sensor fixtures with sensor query flag" ) ,
92+ } ;
93+
5894 [ Test , TestCaseSource ( nameof ( _rayCases ) ) ]
5995 public void RayCast ( Vector2 origin , Vector2 direction , Vector2 ? point )
6096 {
@@ -113,6 +149,55 @@ public void ShapeCast(IPhysShape shape, Transform origin, Vector2 direction, Vec
113149 }
114150 }
115151
152+ [ Test , TestCaseSource ( nameof ( _sensorCases ) ) ]
153+ public void SensorFixtureCasts ( SensorCastKind kind , bool hardFixture , bool includeSensors )
154+ {
155+ var sim = RobustServerSimulation . NewSimulation ( ) . RegisterEntitySystems ( f =>
156+ {
157+ f . LoadExtraSystemType < RayCastSystem > ( ) ;
158+ } ) . InitializeInstance ( ) ;
159+ SetupSensorFixture ( sim , out var mapId , out var target , hardFixture ) ;
160+ var raycast = sim . System < RayCastSystem > ( ) ;
161+
162+ var flags = QueryFlags . Dynamic | QueryFlags . Static ;
163+ if ( includeSensors )
164+ flags |= QueryFlags . Sensors ;
165+
166+ var filter = new QueryFilter
167+ {
168+ LayerBits = 1 ,
169+ Flags = flags ,
170+ } ;
171+
172+ var hits = kind switch
173+ {
174+ SensorCastKind . RayAll => raycast . CastRay (
175+ mapId ,
176+ Vector2 . UnitX / 2f ,
177+ Vector2 . UnitY * 3f ,
178+ filter ) ,
179+ SensorCastKind . RayClosest => raycast . CastRayClosest (
180+ mapId ,
181+ Vector2 . UnitX / 2f ,
182+ Vector2 . UnitY * 3f ,
183+ filter ) ,
184+ SensorCastKind . Shape => raycast . CastShape (
185+ mapId ,
186+ new PhysShapeCircle ( 0.1f ) ,
187+ new Transform ( Vector2 . UnitX / 2f , Angle . Zero ) ,
188+ Vector2 . UnitY * 3f ,
189+ filter ,
190+ RayCastSystem . RayCastAllCallback ) ,
191+ _ => throw new ArgumentOutOfRangeException ( nameof ( kind ) , kind , null ) ,
192+ } ;
193+
194+ var expected = hardFixture || includeSensors
195+ ? new [ ] { target }
196+ : Array . Empty < EntityUid > ( ) ;
197+
198+ Assert . That ( hits . Results . Select ( hit => hit . Entity ) . ToArray ( ) , Is . EqualTo ( expected ) ) ;
199+ }
200+
116201 private void Setup ( ISimulation sim , out MapId mapId )
117202 {
118203 var entManager = sim . Resolve < IEntityManager > ( ) ;
@@ -142,4 +227,38 @@ private void Setup(ISimulation sim, out MapId mapId)
142227 entManager . System < SharedTransformSystem > ( ) . SetLocalRotation ( grid . Owner , Angle . FromDegrees ( 90 ) ) ;
143228 entManager . System < SharedTransformSystem > ( ) . SetLocalPosition ( grid . Owner , Vector2 . UnitX / 2f ) ;
144229 }
230+
231+ private void SetupSensorFixture ( ISimulation sim , out MapId mapId , out EntityUid target , bool hard )
232+ {
233+ var entManager = sim . Resolve < IEntityManager > ( ) ;
234+ var mapSystem = entManager . System < SharedMapSystem > ( ) ;
235+ var fixtureSystem = entManager . System < FixtureSystem > ( ) ;
236+ var physicsSystem = entManager . System < SharedPhysicsSystem > ( ) ;
237+
238+ mapSystem . CreateMap ( out mapId ) ;
239+ var grid = mapSystem . CreateGridEntity ( mapId ) ;
240+
241+ for ( var i = 0 ; i < 3 ; i ++ )
242+ {
243+ mapSystem . SetTile ( grid , new Vector2i ( 0 , i ) , new Tile ( 1 ) ) ;
244+ }
245+
246+ target = SpawnCastTarget ( entManager , fixtureSystem , physicsSystem , grid . Owner , new Vector2 ( 0.5f , 1f ) , hard ) ;
247+ }
248+
249+ private EntityUid SpawnCastTarget (
250+ IEntityManager entManager ,
251+ FixtureSystem fixtureSystem ,
252+ SharedPhysicsSystem physicsSystem ,
253+ EntityUid parent ,
254+ Vector2 position ,
255+ bool hard )
256+ {
257+ var uid = entManager . SpawnEntity ( null , new EntityCoordinates ( parent , position ) ) ;
258+ var physics = entManager . AddComponent < PhysicsComponent > ( uid ) ;
259+ fixtureSystem . CreateFixture ( uid , "fix1" , new Fixture ( new PhysShapeCircle ( 0.25f ) , 1 , 1 , hard ) ) ;
260+ physicsSystem . SetCanCollide ( uid , true , body : physics ) ;
261+ Assert . That ( physics . CanCollide ) ;
262+ return uid ;
263+ }
145264}
0 commit comments