Check if player is looking
Check if player is looking
How can I check if an entity is within the players view?
And have it work for multiple players
And have it work for multiple players
Creator of jelys_pizzaria and motorbike, and player of persistent kingdoms. RIP
- Krock
- Developer
- Posts: 4650
- Joined: Thu Oct 03, 2013 07:48
- GitHub: SmallJoker
- Location: Switzerland
- Contact:
Re: Check if player is looking
The FOV value is not exposed to the Lua API, although you could calculate the "top down" X/Z angle between the player's line of sight and the object position.
Demo:
You could also use the dot product of the two vectors to check whether it's within 90°.
Demo:
You could also use the dot product of the two vectors to check whether it's within 90°.
- Attachments
-
- geometry.png (8 KiB) Viewed 388 times
Last edited by Krock on Mon Jul 08, 2019 17:51, edited 1 time in total.
Look, I programmed a bug for you. >> Mod Search Engine << - Mods by Krock - DuckDuckGo mod search bang: !mtmod <keyword here>
Re: Check if player is looking
XD I don't what that means
Isn't there something called raycast or something like that that makes it so you can check.
EDIT: My comment said caked instead of called (stupid auto correct)
Isn't there something called raycast or something like that that makes it so you can check.
EDIT: My comment said caked instead of called (stupid auto correct)
Last edited by Extex on Mon Jul 08, 2019 23:47, edited 1 time in total.
Creator of jelys_pizzaria and motorbike, and player of persistent kingdoms. RIP
Re: Check if player is looking
See: https://mathinsight.org/dot_productExtex wrote:XD I don't what that means
Isn't there something caked raycast or something like that that makes it so you can check.
and: https://www.mathsisfun.com/algebra/vect ... oduct.html
The dot product of a with unit vector u, denoted a⋅u, is defined to be the projection of a in the direction of u,
or the amount that a is pointing in the same direction as unit vector u.
Code: Select all
(a dot b) = ||a|| ||b|| cos θ
(a dot b) = vector dot product:
Code: Select all
(x1,y1) dot (x2,y2) = (x1 * x2) + (y1 * y2)
(x1,y1,z1) dot (x2,y2,z2) = (x1 * x2) + (y1 * y2) + (z1 * z2)
||a|| = The length of a:
Code: Select all
||(x,y)|| = SQRT(x^2 + y^2)
||(x,y,z)|| = SQRT(x^2 + y^2 + z^2)
You want to determine the angle between vectors a and b such that
it lies within the wanted range of [0 to 90 degs] or [0 to 1.57 rads, 0 to π/2 rads].
1) calcuate (a dot b)
2) calcuate ||a|| and ||b|| -- multiply the two values together
3) plug in vaules from step 1 and 2 into: (a dot b) = ||a|| ||b|| cos θ
EG:
STEP1 = STEP2 * cos θ
STEP1/STEP2 = cos θ
arccos(STEP1/STEP2) = θ ; θ must be between 0 and 90 degrees
-----------------
If a visual representation is needed the first link: https://mathinsight.org/dot_product
has an interactive representation of this (where you can move the vectors around, etc and get a
good idea of what is actually happening)
Re: Check if player is looking
O_O XD could someone just give me a snippet?
I don't understand these super complicated math things
Or even how I'd put it to code
Isn't there just like a
I don't understand these super complicated math things
Or even how I'd put it to code
Isn't there just like a
Code: Select all
if minetest.in_player_view() then
--Code
end
Creator of jelys_pizzaria and motorbike, and player of persistent kingdoms. RIP
Re: Check if player is looking
Or maybe like:
Code: Select all
local pitch = player:get_look_vertical()
local yaw = player:get_yaw()
local angle = 180
local view = minetest.get_in_range(pos, pitch, yaw, angle)
local entities_in_view = view.objects
--code that makes it run one thing at a time
if entities_in_view[0] then
--do something
end
Creator of jelys_pizzaria and motorbike, and player of persistent kingdoms. RIP
Re: Check if player is looking
if you don't know physics this works fine, it compare if the object is front of the player (if the object is farther then a position front of the player)
Code: Select all
viewfield=function(player,ob)
local pos1=player:get_pos()
local pos2 = ob:get_pos()
local d = player:get_look_dir()
return vector.distance(pos1,pos2)>vector.distance({x=pos1.x+d.x,y=pos1.y+d.y,z=pos1.z+d.z},pos2)
end
- Attachments
-
- s.png (1.08 KiB) Viewed 388 times
Re: Check if player is looking
i was trying the angle stuff, and it looks like this
but now?
Code: Select all
local A = math.sqrt(pos1.x^2+pos1.y^2)
local B = math.sqrt(pos2.x^2+pos2.y^2)
local dot = (pos1.x*pos2.x)+(pos1.y*pos2.y)
local A1=dot
local A2=A*B
print(math.acos(A1/A2),user:get_look_horizontal())
Re: Check if player is looking
Yes, that math is correct based on the formulas I posted.AiTechEye wrote:i was trying the angle stuff, and it looks like thisbut now?Code: Select all
local A = math.sqrt(pos1.x^2+pos1.y^2) local B = math.sqrt(pos2.x^2+pos2.y^2) local dot = (pos1.x*pos2.x)+(pos1.y*pos2.y) local A1=dot local A2=A*B print(math.acos(A1/A2),user:get_look_horizontal())
You can see this in action using the interactive applet from mainsight.org:The dot product is positive for acute angles and negative for obtuse angles.
Code: Select all
https://mathinsight.org/dot_product#applet:dot_product_projection
Code: Select all
local result = math.acos(A1/A2) -- this just another way of saying (a dot b)/||b||
-- local result = A1 / B
local limit = 10 -- limit length of a to some value
if (result < 0 or A > limit) then
-- object/entity not in view (negative value, obtuse angle, > 90 degs) (or too far away)
else
-- object/entity in view (zero or a positive value, acute angles, 0 to 90 degs)
end
NOTE: the project of a onto b results in essentially quantifying how much of a intersects b (if a were in the same direction as a b).
When the result is zero, a and b do not intersect, because they are perpendicular (ie a in the direction of b result in a zero-length vector).
If a is longer than b it might be prudent to limit the result to a specific distance.
Also:
a⋅b = ∥a∥∥b∥cos θ -- the projection of a in the direction of b
(a⋅b)/∥b∥ = ∥a∥cos θ -- the projection of a onto b
Another issue is that the above code does not take into account the z coordinate and will only check
if a and b are in a 2-d space ... (ie the result is the same regardless of whether the entity is above or below the player).
----
This will take into account the z-coordinate:
Code: Select all
local A = math.sqrt(pos1.x^2+pos1.y^2+pos1.z^2)
local B = math.sqrt(pos2.x^2+pos2.y^2+pos2.z^2)
local dot = (pos1.x*pos2.x)+(pos1.y*pos2.y)+(pos1.z*pos2.z)
I'll make another post describing how to get a look_vector once I run through the math.
Re: Check if player is looking
I have worked out the math by creating a test mod and have confirmed that the below code works.neoh4x0r wrote:get_look_horizontal --returns yaw in radians (this is not a vector)
I'll make another post describing how to get a look_vector once I run through the math.
Code: Select all
local function get_entity_in_view(player,entity)
local Vp = player:get_pos() -- get the player's position
local Ve = entity:get_pos() -- get the position position of the entity
local Dc = player:get_look_dir() -- the camera direction as a normalized vector (unit vector, length=1)
local Vpe = vector.subtract(Ve, Vp) -- point to entity from player's position
local Dpe = vector.normalize(Vpe) -- create a unit vector from this new vector
local a = Dpe -- set vector a to entities direction
local b = Dc -- set vector b to camera direction
local dot = (a.x * b.x) + (a.y * b.y) + (a.z * b.z) -- calculate (a dot b)
-- The equation to derive the angle is: (a dot b) / |a||b| = cos θ
-- However, the length of a and b are 1 when using normalized (unit) vectors
-- so the equation becomes: (a dot b) = cos θ ... and θ = arccos(a dot b)
local angle_rads = math.acos(dot)
local angle_degs = angle_rads * (180 / math.pi)
-- note1: that as the distance between the player and entity decreases the viewing angle becomes larger
-- probably due to how minetest distorts the worlds around the edges (perspective transform)
-- so if the player is very cose the entity the max angle might need to be increase to 70 degrees
-- note2: 45 degrees is the max here, because the angle is measured for half of the field-of-view
-- the total FOV is 90 degrees
if angle_degs < 0 or angle_degs > 45 then
print("entity not in view")
else
print("entity in view")
end
end
Re: Check if player is looking
your posted code looks pretty easy, but for us that don't know advanced math this math was just impossible to even guess how it works, thanks a lot :)I have worked out the math by creating a test mod and have confirmed that the below code works.
i was changing the code, so now entityes can see too
player or entity (ob1) see ob2
Code: Select all
local function in_view(ob1,ob2)
local p1 = ob1:get_pos()
local a = vector.normalize(vector.subtract(ob2:get_pos(), p1))
local b
if ob1:get_luaentity() then
local yaw = math.floor(ob1:get_yaw()*100)/100
b = {x=math.sin(yaw)*-1,y=0,z=math.cos(yaw)*1}
elseif ob1:is_player() then
b=ob1:get_look_dir()
else
return false
end
local deg = math.acos((a.x*b.x)+(a.y*b.y)+(a.z*b.z)) * (180 / math.pi)
return not (deg < 0 or deg > 50) --45 ... cuz minetest is using a somewhat wide screen size
end
Re: Check if player is looking
@AiTechEye
I was just looking at the latest logs on github for minetest and I came across this commit:
https://github.com/minetest/minetest/co ... 2ae25d719a
to this:
Also you can use vector.direction(a,b) instead of calling vector.subtract and then normalize.
The various methods can be found here:
https://github.com/minetest/minetest/bl ... vector.lua
I was just looking at the latest logs on github for minetest and I came across this commit:
https://github.com/minetest/minetest/co ... 2ae25d719a
So your this part of your code can be changed from (also using math.deg)Add vector.dot and vector.cross
Mostly copied from MarkuBu's code
Code: Select all
local deg = math.acos((a.x*b.x)+(a.y*b.y)+(a.z*b.z)) * (180 / math.pi)
Code: Select all
local deg = math.deg(math.acos(vector.dot(a,b))
Code: Select all
local a = vector.direction(p1, ob2:get_pos())
https://github.com/minetest/minetest/bl ... vector.lua
Who is online
Users browsing this forum: No registered users and 4 guests