add raycast event

This commit is contained in:
ikpil 2023-07-03 23:04:14 +09:00
parent 14fd8b1d09
commit c3288618cf
2 changed files with 93 additions and 67 deletions

View File

@ -0,0 +1,9 @@
using DotRecast.Core;
namespace DotRecast.Recast.Demo.Messages;
public class RaycastEvent : IRecastDemoMessage
{
public required RcVec3f Start { get; init; }
public required RcVec3f End { get; init; }
}

View File

@ -94,8 +94,6 @@ public class RecastDemo : IRecastDemoChannel
private readonly float[] cameraEulers = { 45, -45 }; private readonly float[] cameraEulers = { 45, -45 };
private RcVec3f cameraPos = RcVec3f.Of(0, 0, 0); private RcVec3f cameraPos = RcVec3f.Of(0, 0, 0);
private RcVec3f rayStart = new RcVec3f();
private RcVec3f rayEnd = new RcVec3f();
private float[] projectionMatrix = new float[16]; private float[] projectionMatrix = new float[16];
private float[] modelviewMatrix = new float[16]; private float[] modelviewMatrix = new float[16];
@ -500,75 +498,21 @@ public class RecastDemo : IRecastDemoChannel
simIter++; simIter++;
} }
if (!_mouseOverMenu) if (processHitTest)
{ {
processHitTest = false;
RcVec3f rayStart = new RcVec3f();
RcVec3f rayEnd = new RcVec3f();
GLU.GlhUnProjectf(mousePos[0], viewport[3] - 1 - mousePos[1], 0.0f, modelviewMatrix, projectionMatrix, viewport, ref rayStart); GLU.GlhUnProjectf(mousePos[0], viewport[3] - 1 - mousePos[1], 0.0f, modelviewMatrix, projectionMatrix, viewport, ref rayStart);
GLU.GlhUnProjectf(mousePos[0], viewport[3] - 1 - mousePos[1], 1.0f, modelviewMatrix, projectionMatrix, viewport, ref rayEnd); GLU.GlhUnProjectf(mousePos[0], viewport[3] - 1 - mousePos[1], 1.0f, modelviewMatrix, projectionMatrix, viewport, ref rayEnd);
// Hit test mesh. SendMessage(new RaycastEvent()
DemoInputGeomProvider inputGeom = sample.GetInputGeom();
if (processHitTest && sample != null)
{ {
float? hit = null; Start = rayStart,
if (inputGeom != null) End = rayEnd,
{ });
hit = inputGeom.RaycastMesh(rayStart, rayEnd);
}
if (!hit.HasValue && sample.GetNavMesh() != null)
{
hit = NavMeshRaycast.Raycast(sample.GetNavMesh(), rayStart, rayEnd);
}
if (!hit.HasValue && sample.GetRecastResults() != null)
{
hit = PolyMeshRaycast.Raycast(sample.GetRecastResults(), rayStart, rayEnd);
}
RcVec3f rayDir = RcVec3f.Of(rayEnd.x - rayStart.x, rayEnd.y - rayStart.y, rayEnd.z - rayStart.z);
IRcTool rayTool = toolset.GetTool();
rayDir.Normalize();
if (rayTool != null)
{
Logger.Information($"click ray - tool({rayTool.GetTool().GetName()}) rayStart({rayStart.x:0.#},{rayStart.y:0.#},{rayStart.z:0.#}) pos({rayDir.x:0.#},{rayDir.y:0.#},{rayDir.z:0.#}) shift({processHitTestShift})");
rayTool.HandleClickRay(rayStart, rayDir, processHitTestShift);
}
if (hit.HasValue)
{
float hitTime = hit.Value;
if (0 != (_modState & KeyModState.Control))
{
// Marker
markerPositionSet = true;
markerPosition.x = rayStart.x + (rayEnd.x - rayStart.x) * hitTime;
markerPosition.y = rayStart.y + (rayEnd.y - rayStart.y) * hitTime;
markerPosition.z = rayStart.z + (rayEnd.z - rayStart.z) * hitTime;
}
else
{
RcVec3f pos = new RcVec3f();
pos.x = rayStart.x + (rayEnd.x - rayStart.x) * hitTime;
pos.y = rayStart.y + (rayEnd.y - rayStart.y) * hitTime;
pos.z = rayStart.z + (rayEnd.z - rayStart.z) * hitTime;
if (rayTool != null)
{
Logger.Information($"click - tool({rayTool.GetTool().GetName()}) rayStart({rayStart.x:0.#},{rayStart.y:0.#},{rayStart.z:0.#}) pos({pos.x:0.#},{pos.y:0.#},{pos.z:0.#}) shift({processHitTestShift})");
rayTool.HandleClick(rayStart, pos, processHitTestShift);
}
}
}
else
{
if (0 != (_modState & KeyModState.Control))
{
// Marker
markerPositionSet = false;
}
}
}
processHitTest = false;
} }
if (sample.IsChanged()) if (sample.IsChanged())
@ -698,6 +642,10 @@ public class RecastDemo : IRecastDemoChannel
{ {
OnNavMeshLoadBegan(args4); OnNavMeshLoadBegan(args4);
} }
else if (message is RaycastEvent args5)
{
OnRaycast(args5);
}
} }
private void OnGeomLoadBegan(GeomLoadBeganEvent args) private void OnGeomLoadBegan(GeomLoadBeganEvent args)
@ -821,7 +769,7 @@ public class RecastDemo : IRecastDemoChannel
string ymdhms = $"{now:yyyyMMdd_HHmmss}"; string ymdhms = $"{now:yyyyMMdd_HHmmss}";
var filename = Path.GetFileNameWithoutExtension(_lastGeomFileName); var filename = Path.GetFileNameWithoutExtension(_lastGeomFileName);
var navmeshFilePath = $"{filename}_{ymdhms}.navmesh"; var navmeshFilePath = $"{filename}_{ymdhms}.navmesh";
using var fs = new FileStream(navmeshFilePath, FileMode.Create, FileAccess.Write); using var fs = new FileStream(navmeshFilePath, FileMode.Create, FileAccess.Write);
using var bw = new BinaryWriter(fs); using var bw = new BinaryWriter(fs);
@ -854,4 +802,73 @@ public class RecastDemo : IRecastDemoChannel
Logger.Error(e, ""); Logger.Error(e, "");
} }
} }
private void OnRaycast(RaycastEvent args)
{
var rayStart = args.Start;
var rayEnd = args.End;
// Hit test mesh.
DemoInputGeomProvider inputGeom = sample.GetInputGeom();
if (sample == null)
return;
float? hit = null;
if (inputGeom != null)
{
hit = inputGeom.RaycastMesh(rayStart, rayEnd);
}
if (!hit.HasValue && sample.GetNavMesh() != null)
{
hit = NavMeshRaycast.Raycast(sample.GetNavMesh(), rayStart, rayEnd);
}
if (!hit.HasValue && sample.GetRecastResults() != null)
{
hit = PolyMeshRaycast.Raycast(sample.GetRecastResults(), rayStart, rayEnd);
}
RcVec3f rayDir = RcVec3f.Of(rayEnd.x - rayStart.x, rayEnd.y - rayStart.y, rayEnd.z - rayStart.z);
IRcTool rayTool = toolset.GetTool();
rayDir.Normalize();
if (rayTool != null)
{
Logger.Information($"click ray - tool({rayTool.GetTool().GetName()}) rayStart({rayStart.x:0.#},{rayStart.y:0.#},{rayStart.z:0.#}) pos({rayDir.x:0.#},{rayDir.y:0.#},{rayDir.z:0.#}) shift({processHitTestShift})");
rayTool.HandleClickRay(rayStart, rayDir, processHitTestShift);
}
if (hit.HasValue)
{
float hitTime = hit.Value;
if (0 != (_modState & KeyModState.Control))
{
// Marker
markerPositionSet = true;
markerPosition.x = rayStart.x + (rayEnd.x - rayStart.x) * hitTime;
markerPosition.y = rayStart.y + (rayEnd.y - rayStart.y) * hitTime;
markerPosition.z = rayStart.z + (rayEnd.z - rayStart.z) * hitTime;
}
else
{
RcVec3f pos = new RcVec3f();
pos.x = rayStart.x + (rayEnd.x - rayStart.x) * hitTime;
pos.y = rayStart.y + (rayEnd.y - rayStart.y) * hitTime;
pos.z = rayStart.z + (rayEnd.z - rayStart.z) * hitTime;
if (rayTool != null)
{
Logger.Information($"click - tool({rayTool.GetTool().GetName()}) rayStart({rayStart.x:0.#},{rayStart.y:0.#},{rayStart.z:0.#}) pos({pos.x:0.#},{pos.y:0.#},{pos.z:0.#}) shift({processHitTestShift})");
rayTool.HandleClick(rayStart, pos, processHitTestShift);
}
}
}
else
{
if (0 != (_modState & KeyModState.Control))
{
// Marker
markerPositionSet = false;
}
}
}
} }