Added Physics.Raycast and Transform shortcut on entity objects

This commit is contained in:
Antoine Pilote
2024-09-04 22:26:59 -04:00
parent ea97133e94
commit 732e94899c
10 changed files with 148 additions and 107 deletions

View File

@@ -554,7 +554,7 @@ namespace Nuake
}
}
std::vector<RaycastResult> DynamicWorld::Raycast(const Vector3& from, const Vector3& to)
std::vector<ShapeCastResult> DynamicWorld::Raycast(const Vector3& from, const Vector3& to)
{
// Create jolt ray
const auto& fromJolt = JPH::Vec3(from.x, from.y, from.z);
@@ -566,22 +566,24 @@ namespace Nuake
_JoltPhysicsSystem->GetNarrowPhaseQuery().CastRay(ray, JPH::RayCastSettings(), collector);
// Fetch results
std::vector<RaycastResult> raycastResults;
std::vector<ShapeCastResult> raycastResults;
if (collector.HadHit())
{
int num_hits = (int)collector.mHits.size();
JPH::BroadPhaseCastResult* results = collector.mHits.data();
// Format result
for (int i = 0; i < num_hits; ++i)
{
const float hitFraction = results[i].mFraction;
const JPH::Vec3& hitPosition = ray.GetPointOnRay(results[i].mFraction);
RaycastResult result
auto bodyId = static_cast<JPH::BodyID>(results[i].mBodyID);
auto layer = _JoltBodyInterface->GetObjectLayer(bodyId);
ShapeCastResult result
{
Vector3(hitPosition.GetX(), hitPosition.GetY(), hitPosition.GetZ()),
hitFraction
hitFraction,
Vector3(0, 0, 0),
layer
};
raycastResults.push_back(std::move(result));

View File

@@ -84,7 +84,7 @@ namespace Nuake
void MoveAndSlideCharacterController(const Entity& entity, const Vector3& velocity);
void AddForceToRigidBody(Entity& entity, const Vector3& force);
std::vector<RaycastResult> Raycast(const Vector3& from, const Vector3& to);
std::vector<ShapeCastResult> Raycast(const Vector3& from, const Vector3& to);
std::vector<ShapeCastResult> CastShape(const Vector3& from, const Vector3& to, const Ref<PhysicShape>& shape);
void StepSimulation(Timestep ts);
void Clear();

View File

@@ -42,7 +42,7 @@ namespace Nuake
m_World->Clear();
}
std::vector<RaycastResult> PhysicsManager::Raycast(const Vector3& from, const Vector3& to)
std::vector<ShapeCastResult> PhysicsManager::Raycast(const Vector3& from, const Vector3& to)
{
return m_World->Raycast(from, to);
}

View File

@@ -50,7 +50,7 @@ namespace Nuake
void Reset();
std::vector<RaycastResult> Raycast(const Vector3& from, const Vector3& to);
std::vector<ShapeCastResult> Raycast(const Vector3& from, const Vector3& to);
std::vector<ShapeCastResult> Shapecast(const Vector3& from, const Vector3& to, const Ref<Physics::PhysicShape>& shape);
const std::vector<Physics::CollisionData> GetCollisions();

View File

@@ -10,6 +10,8 @@ namespace Nuake
{
Vector3 WorldPosition;
float Fraction;
Vector3 ImpactNormal;
float Layer;
};
struct ShapeCastResult

View File

@@ -282,21 +282,6 @@ namespace Nuake
const auto& result = PhysicsManager::Get().GetWorld()->Raycast(from, to);
// We multiply by 3 since we have 3 floats per hit result: vector3.
wrenEnsureSlots(vm, static_cast<int>(result.size() * 3));
wrenSetSlotNewList(vm, 0);
uint32_t index = 1;
for (auto& r : result)
{
wrenSetSlotDouble(vm, index, r.WorldPosition.x);
wrenSetSlotDouble(vm, index + 1, r.WorldPosition.y);
wrenSetSlotDouble(vm, index + 2, r.WorldPosition.z);
wrenInsertInList(vm, 0, -1, index);
wrenInsertInList(vm, 0, -1, index + 1);
wrenInsertInList(vm, 0, -1, index + 2);
index += 3;
}
}
static void MoveAndSlide(WrenVM* vm)

View File

@@ -73,6 +73,14 @@ namespace Nuake {
return Coral::Array<float>::New(results);
}
Coral::Array<float> Raycast(float fromX, float fromY, float fromZ, float toX, float toY, float toZ)
{
const Vector3 from = { fromX, fromY, fromZ };
const Vector3 to = { toX, toY, toZ };
auto hits = PhysicsManager::Get().Raycast(from, to);
return ConvertHitsToArray(hits);
}
Coral::Array<float> ShapeCastCapsule(float fromX, float fromY, float fromZ, float toX, float toY, float toZ, CapsuleInternal capsuleInternal)
{
auto capsule = CreateRef<Physics::Capsule>(capsuleInternal.Radius, capsuleInternal.Height);
@@ -104,6 +112,7 @@ namespace Nuake {
RegisterMethod("Debug.DrawShapeCapsuleIcall", &DrawShapeCapsule);
RegisterMethod("Debug.DrawShapeCylinderIcall", &DrawShapeCylinder);
RegisterMethod("Physic.RayCastIcall", &Raycast);
RegisterMethod("Physic.ShapeCastCapsuleIcall", &ShapeCastCapsule);
RegisterMethod("Physic.ShapeCastBoxIcall", &ShapeCastBox);
}

View File

@@ -343,106 +343,109 @@ namespace Nuake
}
}
const std::string baseTypeName = std::string(type->GetBaseType().GetFullName());
if (baseTypeName != "Nuake.Net.Entity")
if (type->GetBaseType())
{
continue;
}
m_BaseEntityType = type->GetBaseType();
auto typeSplits = String::Split(type->GetFullName(), '.');
std::string shortenedTypeName = typeSplits[typeSplits.size() - 1];
NetGameScriptObject gameScriptObject;
gameScriptObject.coralType = type;
gameScriptObject.exposedVars = std::vector<ExposedVar>();
gameScriptObject.Base = baseTypeName;
for (auto& f : type->GetFields())
{
for (auto& a : f.GetAttributes())
const std::string baseTypeName = std::string(type->GetBaseType().GetFullName());
if (baseTypeName != "Nuake.Net.Entity")
{
if (a.GetType() == exposedFieldAttributeType)
continue;
}
m_BaseEntityType = type->GetBaseType();
auto typeSplits = String::Split(type->GetFullName(), '.');
std::string shortenedTypeName = typeSplits[typeSplits.size() - 1];
NetGameScriptObject gameScriptObject;
gameScriptObject.coralType = type;
gameScriptObject.exposedVars = std::vector<ExposedVar>();
gameScriptObject.Base = baseTypeName;
for (auto& f : type->GetFields())
{
for (auto& a : f.GetAttributes())
{
ExposedVar exposedVar;
exposedVar.Name = f.GetName();
auto typeName = f.GetType().GetFullName();
ExposedVarTypes varType = ExposedVarTypes::Unsupported;
bool hasDefaultValue = a.GetFieldValue<Coral::Bool32>("HasDefaultvalue");
if (typeName == "System.Single")
if (a.GetType() == exposedFieldAttributeType)
{
varType = ExposedVarTypes::Float;
ExposedVar exposedVar;
exposedVar.Name = f.GetName();
if (hasDefaultValue)
auto typeName = f.GetType().GetFullName();
ExposedVarTypes varType = ExposedVarTypes::Unsupported;
bool hasDefaultValue = a.GetFieldValue<Coral::Bool32>("HasDefaultvalue");
if (typeName == "System.Single")
{
exposedVar.Value = a.GetFieldValue<float>("DefaultValueInternalFloat");
}
}
else if (typeName == "System.Double")
{
varType = ExposedVarTypes::Double;
}
else if (typeName == "System.String")
{
varType = ExposedVarTypes::String;
varType = ExposedVarTypes::Float;
if (hasDefaultValue)
if (hasDefaultValue)
{
exposedVar.Value = a.GetFieldValue<float>("DefaultValueInternalFloat");
}
}
else if (typeName == "System.Double")
{
exposedVar.Value = a.GetFieldValue<Coral::String>("DefaultValueInternalString");
varType = ExposedVarTypes::Double;
}
}
else if (typeName == "System.Boolean")
{
varType = ExposedVarTypes::Bool;
if (hasDefaultValue)
else if (typeName == "System.String")
{
exposedVar.Value = a.GetFieldValue<Coral::Bool32>("DefaultValueInternalBool");
varType = ExposedVarTypes::String;
if (hasDefaultValue)
{
exposedVar.Value = a.GetFieldValue<Coral::String>("DefaultValueInternalString");
}
}
}
else if (typeName == "System.Numerics.Vector2")
{
varType = ExposedVarTypes::Vector2;
}
else if (typeName == "System.Numerics.Vector3")
{
varType = ExposedVarTypes::Vector3;
}
else if (typeName == "Nuake.Net.Entity")
{
varType = ExposedVarTypes::Entity;
}
else if (typeName == "Nuake.Net.Prefab")
{
varType = ExposedVarTypes::Prefab;
}
else if (typeName == "System.Boolean")
{
varType = ExposedVarTypes::Bool;
if (varType != ExposedVarTypes::Unsupported)
{
exposedVar.Type = varType;
gameScriptObject.exposedVars.push_back(exposedVar);
}
if (hasDefaultValue)
{
exposedVar.Value = a.GetFieldValue<Coral::Bool32>("DefaultValueInternalBool");
}
}
else if (typeName == "System.Numerics.Vector2")
{
varType = ExposedVarTypes::Vector2;
}
else if (typeName == "System.Numerics.Vector3")
{
varType = ExposedVarTypes::Vector3;
}
else if (typeName == "Nuake.Net.Entity")
{
varType = ExposedVarTypes::Entity;
}
else if (typeName == "Nuake.Net.Prefab")
{
varType = ExposedVarTypes::Prefab;
}
Logger::Log("Exposed field detected: " + std::string(f.GetName()) + " of type " + std::string(f.GetType().GetFullName()) );
if (varType != ExposedVarTypes::Unsupported)
{
exposedVar.Type = varType;
gameScriptObject.exposedVars.push_back(exposedVar);
}
Logger::Log("Exposed field detected: " + std::string(f.GetName()) + " of type " + std::string(f.GetType().GetFullName()));
}
}
}
}
// Add to the brush map to retrieve when exporting FGD
if (isBrushScript)
{
gameScriptObject.Description = brushDescription;
gameScriptObject.isTrigger = isTrigger;
m_BrushEntityTypes[shortenedTypeName] = gameScriptObject;
}
// Add to the brush map to retrieve when exporting FGD
if (isBrushScript)
{
gameScriptObject.Description = brushDescription;
gameScriptObject.isTrigger = isTrigger;
m_BrushEntityTypes[shortenedTypeName] = gameScriptObject;
}
if (isPointScript)
{
gameScriptObject.Description = pointDescription;
m_PointEntityTypes[shortenedTypeName] = gameScriptObject;
if (isPointScript)
{
gameScriptObject.Description = pointDescription;
m_PointEntityTypes[shortenedTypeName] = gameScriptObject;
}
m_GameEntityTypes[shortenedTypeName] = gameScriptObject;
}
m_GameEntityTypes[shortenedTypeName] = gameScriptObject;
}
}

View File

@@ -88,8 +88,21 @@ namespace Nuake.Net
}
}
public string Target { get { unsafe { return EntityGetTargetIcall(ECSHandle); } }}
protected TransformComponent internalTransform;
public TransformComponent Transform
{
get
{
if(internalTransform == null)
{
internalTransform = GetComponent<TransformComponent>()!;
}
return internalTransform;
}
}
public string Target { get { unsafe { return EntityGetTargetIcall(ECSHandle); } }}
public int ID { get; set; }
public int ECSHandle { get; set; } = -1;

View File

@@ -9,6 +9,7 @@ using System.Runtime.InteropServices;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using static Nuake.Net.Physic;
namespace Nuake.Net
{
@@ -118,10 +119,36 @@ namespace Nuake.Net
SENSORS = 5
}
internal static unsafe delegate*<float, float, float, float, float, float, NativeArray<float>> RayCastIcall;
internal static unsafe delegate*<float, float, float, float, float, float, BoxInternal, NativeArray<float>> ShapeCastBoxIcall;
internal static unsafe delegate*<float, float, float, float, float, float, float, NativeArray<float>> ShapeCastSphereIcall;
internal static unsafe delegate*<float, float, float, float, float, float, CapsuleInternal, NativeArray<float>> ShapeCastCapsuleIcall;
internal static unsafe delegate*<float, float, float, float, float, float, CapsuleInternal, NativeArray<float>> ShapeCastCylinderIcall;
public static List<ShapeCastResult> RayCast(Vector3 from, Vector3 to)
{
List<ShapeCastResult> result = [];
unsafe
{
NativeArray<float> resultICall = RayCastIcall(from.X, from.Y, from.Z, to.X, to.Y, to.Z);
for (int i = 0; i < resultICall.Length / 7; i++)
{
int index = i * 7;
ShapeCastResult shapeCastResult = new()
{
ImpactPosition = new Vector3(resultICall[index + 0], resultICall[index + 1], resultICall[index + 2]),
ImpactNormal = new Vector3(resultICall[index + 3], resultICall[index + 4], resultICall[index + 5]),
Fraction = resultICall[index + 6],
Layer = (Layers)resultICall[index + 7]
};
result.Add(shapeCastResult);
}
return result;
}
}
public static List<ShapeCastResult> ShapeCast(Vector3 from, Vector3 to, Box box)
{
List<ShapeCastResult> result = [];