Screen position of 3D point? [Solved]

Re the picture touch code: I didn’t recognise it! I’ve now looked back at my original code and seen what that does. It’s for moving the picture. Since you took out all the moving code, you should take this out too.

function PictureIsTouchedBy(t)
    local tc = screentoplane(t, vec3(0,0,0), vec3(1,0,0), vec3(0,1,0), Matrix)
    -- Was the picture touched?
    if math.abs(tc.x) > .5 or math.abs(tc.y) > .5 then return nil end
    return tc
end

Note that pos isn’t used either.

OK, but I still need to add 0.5 to tc.x and tc.y to get the right answers, ie

return tc + vec3(0.5,0.5,0.5)

EDIT - this may be because when I draw, I’m centring my picture on its position, using a sprite command.

Now - if I try next to get “which object did I touch” working, again in minimal form, is there a way I can always touch the front object? If you can give me the z value of the touch point, I can take it from there.

The three objects you’ve provided - cube, sphere and picture - should be sufficient for most purposes, as bounding boxes for 3D game objects.

@Ignatz from your nice link above i get

error: [string "function setup()..."]:100: attempt to call global 'applymatrix4' (a nil value)

could you include the needed library so it is 100% standalone?

@Jmv38 - sorry about that. I updated my gist with that and the changes from LoopSpace, here

https://gist.github.com/dermotbalson/286f386438d427d3c721

Touching the red picture will print the x,y position you touched as % of the width and height of the picture. So top left will give 1,0

Here’s what I would do for the return value. Since, you want the return value to make sense in terms of the picture then a vec2 seems to make most sense.

function PictureIsTouchedBy(t)
    local tc = screentoplane(t, vec3(0,0,0), vec3(1,0,0), vec3(0,1,0), Matrix)
    -- Was the picture touched?
    if math.abs(tc.x) > .5 or math.abs(tc.y) > .5 then return nil end
    return vec2(tc.x+.5,tc.y+.5)
end

@ignatz very useful, thanks!

@Jmv38 - thank Loopspace, it’s his code! =D>

@Loopspace thank you for this code.
@Ignatz but you also did some ‘3d for dummies’ rework, that is not quite useless. Teamwork often makes 1 + 1 > 2, (although i’m not sure loopspace will like this equation) :wink:

@Jmv38 - us dummies need to stick together, right? :wink:

@Jmv38, @LoopSpace - I simplified the code further for the user, so you can draw the sprite normally, rather than as a 1x1 image, and the touched function returns the vec2 pixel position.

https://gist.github.com/dermotbalson/3b1ec6169604bf87f09b

So now all you do to calculate touch points, is run SetMatrix() just after drawing your image (to store the model/view/projection matrix), then call PictureIsTouchedBy(t,s) in the touched function, where s is the vec2 size of your picture. This keeps the utility “footprint” to just two additional lines of code as before.

Additionally, you can have multiple pictures and the program will detect which was touched, and where. In this case, you need to store the result of SetMatrix() for each picture (because the utility code doesn’t store it) and pass it in the touched function.

The code above demonstrates this for two pictures.

@LoopSpace - so now I want to pick the front image that I touched

Can I do it like this, to get the z value of a touch (EDITED TO CORRECT ERROR)

--code as above, suppose I store the vec2 touch position in tp
local a = modelMatrix():translate(tp.x,tp.y,0)
depth = a[15] -- z value of touch

Then I can compare z values to figure out which object was touched

@LoppSpace - Here is some code with overlapping images. It seems to correctly identify which is in front when touched, as well as the touch position

https://gist.github.com/dermotbalson/42ddc35d4bb8a74be86a

@ignatz very good work, thanks.