177 lines
3.9 KiB
C#
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;
|
|
|
|
}
|
|
}
|
|
} |