I'm working on a 3D project in OpenGL. Picking objects is my thing to worry about, but right now I can't get the main thing working. Which is casting a ray from my camera using the mouse. I've been digging through too many examples including raycasting without "unproject", but they literally give me the same result! They are almost working, and now I am pretty much stuck and do not know what to do.
Consider my method I've picked last:
function CCamera.GetRay(x: Single; y: Single;) : TVector3;
var
mouseX: single;
mouseY: single;
invVP: TMatrix4;
screenPos: TVector4;
worldPos: TVector4;
worldPos3: TVector3;
dir: TVector3;
begin
// NDC
mouseX := x / (fViewportWidth * 0.5) - 1.0;
mouseY := y / (fViewportHeight * 0.5) - 1.0;
invVP := mView * mProjection;
// invVP.SetInversed; // Inversed doesn't even cast the ray close to where I want it cast at.
// mProjection * mView would also generate behavior that isn't close to what I want.
screenPos.Init(mouseX, -mouseY, 1.0, 1.0);
worldPos := invVP * screenPos;
worldPos3.Init(worldPos.X, worldPos.Y, worldPos.Z);
dir := worldPos3.Normalize();
Exit(dir);
end;
Literally. Every. Single. Example gives me the same result! This is the one I will stick to.
And then, I would determine the camera ray's end position as such:
UPDATED code:
procedure TOpenGLControl.OnMouseDown(Sender: TObject; Button:
TMouseButton; Shift: TShiftState; X: Integer; Y: Integer);
var
ray_start: TVector3;
ray_end: TVector3;
ray_dir: TVector3;
begin
ray_start := GetCamera.GetPosition(); // Position of the camera
ray_dir := GetCamera.GetRay(X, Y); // Pass 2D mouse coordinates
ray_end := ray_start + ray_dir * 50.0; // Max distance of 50 units
Invalidate();
end;
Using Neslib.FastMath for the math functions and attributes. So, basically, what happens is that the further I click from the center of the world (where the triangle is), the ray strives closer to the center. Check image.