Checking if an entity is within a players view
-
- Posts: 514
- Joined: Sat May 01, 2010 10:12 pm
- Contact:
Checking if an entity is within a players view
Im having troubles on how I would code it to check if a certain entity is within the current viewing angles of the player. anyone mind pointing me in the right direction? And if Im a little unclear, let me explain.
Your the player. Say theres a rocket launcher on the ground. How could you check and see if that rocket launchers within the players camera? And lets just say you turn around and you can no longer see the rocket launcher. How could I calculate that?
Your the player. Say theres a rocket launcher on the ground. How could you check and see if that rocket launchers within the players camera? And lets just say you turn around and you can no longer see the rocket launcher. How could I calculate that?
Re: Checking if an entity is within a players view
QuakeC isn't my thing but here goes a guess ...
Code: Select all
void() canseeitem =
{
local entity e;
e = findradius(self.origin, 1024);
while(e) // Run through a loop of everything within 1024 Quake feet of player
{
if(infront(e) == TRUE) // Limit to those that in front
{
if (e.flags & FL_ITEM) // You will need to customize this line
{
// Do something to the item
e.jumparound = TRUE;
}
}
e = e.chain; // Next ...
}
}
The night is young. How else can I annoy the world before sunsrise? Inquisitive minds want to know ! And if they don't -- well like that ever has stopped me before ..
-
- Posts: 514
- Joined: Sat May 01, 2010 10:12 pm
- Contact:
Re: Checking if an entity is within a players view
That's not what I'm trying to do haha. That checks around the player. With that code, the rocket could be behind the player and still detect it. I'm thinking something more like fisible from frikbots but from the perspective of the players v_angle detecting what the player can actually see.
Re: Checking if an entity is within a players view
This mod, monsters can only move if you aren't looking at them:
http://quake-1.com/quakec-gallery/angel.zip
if(infront(e) == TRUE) // Limit to those that are front <----- This is kinda in the above code.
infront is why a grunt doesn't see you from behind.
http://quake-1.com/quakec-gallery/angel.zip
Is that so?Mexicouger wrote:That checks around the player. With that code, the rocket could be behind the player and still detect it.
if(infront(e) == TRUE) // Limit to those that are front <----- This is kinda in the above code.
infront is why a grunt doesn't see you from behind.
The night is young. How else can I annoy the world before sunsrise? Inquisitive minds want to know ! And if they don't -- well like that ever has stopped me before ..
-
- Posts: 2126
- Joined: Sat Nov 25, 2006 1:49 pm
Re: Checking if an entity is within a players view
Mexicouger wrote:That's not what I'm trying to do haha. That checks around the player. With that code, the rocket could be behind the player and still detect it. I'm thinking something more like fisible from frikbots but from the perspective of the players v_angle detecting what the player can actually see.
Actually, the code also checks if the entity is in front the player.
I know FrikaC made a cgi-bin version of the quakec interpreter once and wrote part of his website in QuakeC (LordHavoc)
-
- Posts: 514
- Joined: Sat May 01, 2010 10:12 pm
- Contact:
Re: Checking if an entity is within a players view
Thanks Baker! It seems I deleted some valuable code when I was cleaning out my QC. If you look in ai.qc, the function I wanted to use was:
Golden!
Code: Select all
/*
=============
infront
returns 1 if the entity is in front (in sight) of self
=============
*/
float(entity targ) infront =
{
local vector vec;
local float dot;
makevectors (self.angles);
vec = normalize (targ.origin - self.origin);
dot = vec * v_forward;
if ( dot > 0.3)
{
return TRUE;
}
return FALSE;
};
Re: Checking if an entity is within a players view
This post is basically an explaination of the infront function.
in qc terms:
cos(anglebetweenvectors) == normalisedvector1 * normaliseedvector2
so vector*vector will be 1 if they are identical, -1 if they point in opposite directions, and 0 if they point 90 degrees to each other.
Considering the greatest angle difference you can have is 0 to 180 and fields of view are measured in both directions instead of just one, ((fwd*normalilze(targetpos - sourcepos)) > cos(fovvalue/2)) can be used to check whether the direction is within the given field-of-view angle.
cos, however, is an extension, but you can replace the result of that function with a constant (for example, quake's collision code reguarly uses 0.7 for surfaces that are considered pointing upwards for 'onground' checks).
Note that this is NOT the same as 'onscreen', as this would require a circular screen. The virtual circular screen will generally have the same width as the screen, thus this may fail for the corners of the screen. Also, you may also need to pay attention to bounding boxes.
Additionally, makevectors(self.angles) is generally only valid when angles_x=0 (which is true for monsters). If used for a player, you should be using makevectors(self.v_angle) instead. This will scale correctly with pitch (instead of being 1/3rd), and will also work around an old (unfixable) sw quake bug where .angles_x on alias models is inverted.
(qc's vector*vector operation/instruction is actually a 3-componant dotproduct)
(dotproduct is useful for all sorts of things!)
in qc terms:
cos(anglebetweenvectors) == normalisedvector1 * normaliseedvector2
so vector*vector will be 1 if they are identical, -1 if they point in opposite directions, and 0 if they point 90 degrees to each other.
Considering the greatest angle difference you can have is 0 to 180 and fields of view are measured in both directions instead of just one, ((fwd*normalilze(targetpos - sourcepos)) > cos(fovvalue/2)) can be used to check whether the direction is within the given field-of-view angle.
cos, however, is an extension, but you can replace the result of that function with a constant (for example, quake's collision code reguarly uses 0.7 for surfaces that are considered pointing upwards for 'onground' checks).
Note that this is NOT the same as 'onscreen', as this would require a circular screen. The virtual circular screen will generally have the same width as the screen, thus this may fail for the corners of the screen. Also, you may also need to pay attention to bounding boxes.
Additionally, makevectors(self.angles) is generally only valid when angles_x=0 (which is true for monsters). If used for a player, you should be using makevectors(self.v_angle) instead. This will scale correctly with pitch (instead of being 1/3rd), and will also work around an old (unfixable) sw quake bug where .angles_x on alias models is inverted.
(qc's vector*vector operation/instruction is actually a 3-componant dotproduct)
(dotproduct is useful for all sorts of things!)
Re: Checking if an entity is within a players view
I made this in the past days to get some effects, if the entity is infront and visible with the precise angles CSQC add some bloom effect ... maybee seems crapy in this early release
http://www.youtube.com/watch?v=t0E2K1Dy8Ek
http://www.youtube.com/watch?v=t0E2K1Dy8Ek
hi, I am nahuel, I love quake and qc.
-
- Posts: 1395
- Joined: Tue Feb 24, 2009 4:39 pm
- Location: Italy
Re: Checking if an entity is within a players view
Very very nice effect Nahuel! I loved it! Sun light is lightmapped or dynamic (achieving dynamic sun lights in DP is my only motivation of life in these days! )?
Meadow Fun!! - my first commercial game, made with FTEQW game engine
Re: Checking if an entity is within a players view
hello tunedude, the map is darker, so is just a dynamic light place un a specific place !
@Spike it is posible to get something like (infront) function but instead of using a speciffic point like "self.origin" to use an area? i speak about an entire area of the brush, a something like func_wall, I wanna to get the bloom oriented effect with a brush, not with the specific origin of the entity . Thanks in advance
@Spike it is posible to get something like (infront) function but instead of using a speciffic point like "self.origin" to use an area? i speak about an entire area of the brush, a something like func_wall, I wanna to get the bloom oriented effect with a brush, not with the specific origin of the entity . Thanks in advance
hi, I am nahuel, I love quake and qc.
Re: Checking if an entity is within a players view
This is a very interesting topic.
Thank you Mexicouger for starting this thread and Nahuel for your demonstration.
It brings so many new ideas into the mind.
I am working on a zombie modification at the moment, in which the Axe weapon plays a special role.
Implementing a QC "zombiecheck" to find out if a zombie is in range and then starting an Axe animation,
where it starts to glow. Because zombies are killable with the Axe.
It is like a "holy-zombie-killing" weapon in this mod...
So this thread-knowledge is very helpful to achive this task.
Thank you again.
Seven
Thank you Mexicouger for starting this thread and Nahuel for your demonstration.
It brings so many new ideas into the mind.
I am working on a zombie modification at the moment, in which the Axe weapon plays a special role.
Implementing a QC "zombiecheck" to find out if a zombie is in range and then starting an Axe animation,
where it starts to glow. Because zombies are killable with the Axe.
It is like a "holy-zombie-killing" weapon in this mod...
So this thread-knowledge is very helpful to achive this task.
Thank you again.
Seven
Re: Checking if an entity is within a players view
Nahuel, can you not just define a direction in the map, and use that against the player's v_forward? then its no specific point at all, though would be purely based upon the player's view direction.
Re: Checking if an entity is within a players view
Ironically I spent a couple of hours yesterday trying to do exactly this, and then found this post today. Figures.
This bit is much more messy than Baker's example (probably just stick with his), but it works.
I run this function through W_WeaponFrame(); in weapons.qc so that it runs all the time, and I do that with a lot of other functions that require constant "monitoring". Is that bad to do? Or should it go in player pre or post think or something?
This bit is much more messy than Baker's example (probably just stick with his), but it works.
Code: Select all
.float seen;
.string combatant; //replace with classname or something else if you want.
void () CheckVisible=
{
local entity targ;
targ = find (world, combatant, "yes"); //using this instead of findradius allowed me to look for specific entities.
if (visible(targ)) { //I don't actually know if I need this part...
if (infront(targ)) {
targ.seen = 1; //this gives the entity a value so its behaviour can be changed accordingly. I wanted certain monsters to ONLY move when seen.
}
else {
targ.seen = 0;
}
}
};
Re: Checking if an entity is within a players view
W_WeaponFrame is called from PlayerPostThink, so it's cleaner to just call those monitoring functions from PlayerPostThink.Alex wrote:I run this function through W_WeaponFrame(); in weapons.qc so that it runs all the time, and I do that with a lot of other functions that require constant "monitoring". Is that bad to do? Or should it go in player pre or post think or something?
But if the functions are handling stuff not directly related to a player, then it's best to use the normal 'think' function of entities, otherwise in coop they will get called more often than you expected.