Added Physics.Raycast and Transform shortcut on entity objects
This commit is contained in:
@@ -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));
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -10,6 +10,8 @@ namespace Nuake
|
||||
{
|
||||
Vector3 WorldPosition;
|
||||
float Fraction;
|
||||
Vector3 ImpactNormal;
|
||||
float Layer;
|
||||
};
|
||||
|
||||
struct ShapeCastResult
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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 = [];
|
||||
|
||||
Reference in New Issue
Block a user