rj-action-library/Runtime/Physics/CollisionData.cs

177 lines
3.9 KiB
C#

using Godot;
using System.Collections;
using System.Collections.Generic;
using Godot.Collections;
using System;
namespace Rokojori
{
public class CollisionData
{
public bool hasCollision = false;
public Node collider;
public Vector3 normal;
public Vector3 position;
public Shape3D shape;
public Rid rid;
public static bool HasCollisionMask( Node n )
{
return n is CsgShape3D || n is CollisionObject3D;
}
public static uint GetCollisionMask( Node n )
{
if ( n is CsgShape3D )
{
return ( n as CsgShape3D ).CollisionMask;
}
if ( n is CollisionObject3D )
{
return ( n as CollisionObject3D ).CollisionMask;
}
return 0;
}
public static bool HasCollisionLayer( Node n )
{
return n is CsgShape3D || n is CollisionObject3D;
}
public static uint GetCollisionLayer( Node n )
{
if ( n is CsgShape3D )
{
return ( n as CsgShape3D ).CollisionLayer;
}
if ( n is CollisionObject3D )
{
return ( n as CollisionObject3D ).CollisionLayer;
}
return 0;
}
public void Get( PhysicsRayQueryParameters3D ray, PhysicsDirectSpaceState3D physicsState )
{
var result = physicsState.IntersectRay( ray );
if ( ! result.ContainsKey( "collider" ) )
{
hasCollision = false;
return;
}
hasCollision = true;
collider = result[ "collider" ].As<Node>();
normal = result[ "normal" ].AsVector3();
position = result[ "position" ].AsVector3();
shape = result[ "shape" ].As<Shape3D>();
rid = result[ "rid" ].AsRid();
// RJLog.Log( "Has Collision:", HierarchyName.Of( collider ), ">> at position:", position, "with normal:", normal );
}
public static CollisionData FindCollision( World3D world, PhysicsRayQueryParameters3D rayParameters, Func<CollisionData,bool> predicate )
{
var physics = world.DirectSpaceState;
var excludes = new Array<Rid>();
var maxHits = 10000;
for ( int i = 0; i < maxHits; i++ )
{
rayParameters.Exclude = excludes;
var collisionData = new CollisionData();
collisionData.Get( rayParameters, physics );
if ( ! collisionData.hasCollision )
{
return null;
}
if ( predicate( collisionData ) )
{
return collisionData;
}
excludes.Add( collisionData.rid );
}
return null;
}
public static int MultiRayCast( World3D world, PhysicsRayQueryParameters3D rayParameters, List<CollisionData> collisionsOutput )
{
var physics = world.DirectSpaceState;
var excludes = new Array<Rid>();
var numCollisions = 0;
for ( int i = 0; i < collisionsOutput.Count; i++ )
{
rayParameters.Exclude = excludes;
var collisionData = collisionsOutput[ i ];
collisionData.Get( rayParameters, physics );
if ( ! collisionData.hasCollision )
{
return i;
}
excludes.Add( collisionData.rid );
numCollisions ++;
}
return numCollisions;
}
public static List<CollisionData> MultiRayCast( World3D world, PhysicsRayQueryParameters3D rayParameters, int maxHits = 100 )
{
var physics = world.DirectSpaceState;
var excludes = new Array<Rid>();
var collisions = new List<CollisionData>();
for ( int i = 0; i < maxHits; i++ )
{
rayParameters.Exclude = excludes;
var collisionData = new CollisionData();
collisionData.Get( rayParameters, physics );
if ( ! collisionData.hasCollision )
{
return collisions;
}
excludes.Add( collisionData.rid );
collisions.Add( collisionData );
}
return collisions;
}
}
}