Raypick funktioniert nur bedingt.
Verfasst: 08.02.2024, 10:38
Hallo :) ich habe mich gestern daran gemacht, eine Funktion zu erstellen, mit der ich Entitys mi der Maus picken kann. Ich habe gesehen das es dafür mehrere Möglichkeiten gibt und dachte, dass sich ein Raycast ganz gut eignen könnte. Jedoch habe ich das Problem das das ganze nicht so richtig funktionieren mag.
Mit dieser Klasse erstelle ich den Raycast
und dann Prüfe ich hiermit ob es zu einer Intersection zwischen cast und aabb eines entitys kommt
Es ist nun so, dass der cast nicht wirklich in Richtung der Maus verläuft und ich die Message box für den kontakt auch erhalte wenn ich nicht auf das Entity klicke.
Beste grüße
Andy
Mit dieser Klasse erstelle ich den Raycast
Code: Alles auswählen
public class MouseRay
{
public vec3 CurrentRay { get; set; }
public mat4 ProjectionMatrix { get; set; }
public mat4 ViewMatrix { get; set; }
public Camera Camera { get; set; }
public MouseRay(Camera camera)
{
this.Camera = camera;
}
private void GenerateMatrix(Camera camera)
{
vec3 cameraPosition = camera.Location.ToGlmVec3();
Vec3 cameraFront = Utils.CalculateCameraFront2(camera);
ProjectionMatrix = mat4.Perspective(Utils.ToRadians(45.0f), camera.Size.X / camera.Size.Y, camera.Near, camera.Far);
ViewMatrix = mat4.LookAt(cameraPosition, cameraPosition + cameraFront.ToGlmVec3(), new vec3(0.0f, 1.0f, 0.0f));
}
public Vec3 RayCast(float mouseX, float mouseY, Viewport viewport)
{
this.GenerateMatrix(this.Camera);
var ndc = GetNDC(mouseX, mouseY, viewport);
var clip = new vec4(ndc.x, ndc.y, -1f, 1f);
var eye = GetEyeCords(clip);
vec3 ray_wor = GetWorldCords(eye);
return new Vec3(ray_wor);
}
private vec3 GetWorldCords(vec4 eye)
{
vec3 rey_wor = (ViewMatrix.Inverse * eye).xyz;
return rey_wor.Normalized;
}
public vec4 GetEyeCords(vec4 clip)
{
vec4 ray_eye = ProjectionMatrix.Inverse * clip;
return new vec4(ray_eye.x, ray_eye.y, -1f, 0f);
}
public vec2 GetNDC(float x, float y, Viewport viewport)
{
float ndcX = (2.0f * x) / viewport.Width - 1.0f;
float ndcY = 1.0f - (2.0f * y) / viewport.Height;
return new vec2(ndcX, -ndcY);
}
}
Code: Alles auswählen
start = this.Camera.Location;
end = MouseRay.RayCast(e.X, e.Y, Viewport);
foreach (var layer in this.Scene.Layer)
{
foreach (var entity in layer.Elements)
{
StaticMeshBehavior staticMeshBehavior = (StaticMeshBehavior)entity.GetBehavior<StaticMeshBehavior>();
if (staticMeshBehavior != null)
{
Genesis.Physics.Aabb aabb = Genesis.Physics.Aabb.FromBulletRigidBody(staticMeshBehavior.RigidBody);
if (Genesis.Physics.Aabb.IntersectRay(start, end, aabb.Min, aabb.Max))
{
MessageBox.Show("contact");
}
}
}
}
Beste grüße
Andy