CSQC Tracelines
Moderator: InsideQC Admins
10 posts
• Page 1 of 1
CSQC Tracelines
I'm trying to get ents sent to CSQC via sendentity to be hit by tracelines, but my trace never detects anything. Has anyone got an idea what the problem is? This is in FTE.
SSQC:
CSQC:
SSQC:
- Code: Select all
float(entity to, float sendflags) explobox_send =
{
WriteByte(MSG_ENTITY, 1);
WriteByte(MSG_ENTITY, sendflags);
WriteCoord(MSG_ENTITY, self.origin_x);
WriteCoord(MSG_ENTITY, self.origin_y);
WriteCoord(MSG_ENTITY, self.origin_z);
WriteByte(MSG_ENTITY, self.modelindex);
return 1;
};
void() spawn_explobox =
{
self.classname = "misc_explobox";
self.solid = SOLID_BBOX;
self.movetype = MOVETYPE_NONE;
precache_model ("progs/exbox.mdl");
setmodel (self, "progs/exbox.mdl");
setsize (self, '-16 -16 -16', '16 16 16');
precache_sound ("weapons/r_exp3.wav");
self.health = 20;
self.th_die = explobox_boom;
self.takedamage = DAMAGE_AIM;
self.touch = explobox_touch;
self.origin_z = self.origin_z + 32;
// the original quake exploboxes were oriented on a corner, but our new .mdl is centered
// around its origin, therefore we need to nudge it a bit
self.origin_x += 16;
self.origin_y += 16;
self.SendEntity = explobox_send;
if (!droptofloor())
{
dprint ("misc_explobox fell out of level at ");
dprint (vtos(self.origin));
dprint ("\n");
remove(self);
}
};
void() misc_explobox =
{
self.nextthink = time + 0.2;
self.think = spawn_explobox;
};
CSQC:
- Code: Select all
void() checkshit =
{
local vector o, v;
o = getviewprop(VF_ORIGIN);
v = getviewprop(VF_ANGLES);
makevectors(v);
traceline(o, o + v_forward * 4096, FALSE, world);
// traceline never detects anything
if (trace_ent != world)
eprint(trace_ent);
};
float(float evtype, float scanx, float chary, float devid) CSQC_InputEvent =
{
if (evtype == IE_KEYDOWN)
{
if (chary == 101)
{
checkshit();
return TRUE;
}
}
return FALSE;
};
void CSQC_Ent_Update (float isnew)
{
local float enttype = readbyte();
local float flags;
switch (enttype)
{
case 1:
flags = readbyte();
self.origin_x = readcoord();
self.origin_y = readcoord();
self.origin_z = readcoord();
setorigin(self, self.origin);
setmodelindex(self, readbyte());
self.drawmask = MASK_ENGINE;
if (isnew)
{
self.solid = SOLID_BBOX;
self.movetype = MOVETYPE_TOSS;
setorigin(self, self.origin);
self.classname = "misc_explobox";
}
break;
default:
break;
}
};
Last edited by c0burn on Thu May 26, 2016 7:25 am, edited 1 time in total.
- c0burn
- Posts: 208
- Joined: Fri Nov 05, 2004 12:48 pm
- Location: Liverpool, England
Re: CSQC Tracelines
Not saying I have any idea why your code isn't working as expected but... usually I prefer
because traceline can actually hit the world, and your test would not detect it.
- Code: Select all
if (trace_fraction < 1.0)
because traceline can actually hit the world, and your test would not detect it.
I know FrikaC made a cgi-bin version of the quakec interpreter once and wrote part of his website in QuakeC
(LordHavoc)
-

frag.machine - Posts: 2090
- Joined: Sat Nov 25, 2006 1:49 pm
Re: CSQC Tracelines
Saw this post just now. Please frag.machine, can you please explain how to use trace_fraction? I never understood how to use it.
Is it the percentage of world hit by line(0.1 = 10%, 0.5 = 50%, etc.)?
Thanks in advance for your clarification
Is it the percentage of world hit by line(0.1 = 10%, 0.5 = 50%, etc.)?
Thanks in advance for your clarification
Meadow Fun!! - my first commercial game, made with FTEQW game engine
- toneddu2000
- Posts: 1352
- Joined: Tue Feb 24, 2009 4:39 pm
- Location: Italy
Re: CSQC Tracelines
trace_fraction:
if you cast a ray from A to B, that ray you can hit planes C,D,E,F, etc. each plane has its own plane and normal.
distfromA = dotproduct(A, planenormal) - planedist;
distfromB = dotproduct(B, planenormal) - planedist;
fraction = distfromA / (distfromB-distfromA);
endpos = A + (B-A)*fraction;
if you're doing triangle-based collision, then there are 3 more dotproducts against endpos and the 3 planes that define the edges of the triangle.
brush collision does some traces against every single plane of the brush to figure out which plane it actually hit (furthest, so long as it wasn't clipped by another plane).
bsp collision provides an ordered tree of planes, with the results of plane checks determining which other leafs/planes need to be checked.
the actual trace that is returned by traceline is then the trace against the plane which resulted in the lowest fraction (where it actually hit the geometry that included that plane, and where the far side is considered solid with the near side not).
things get more messy when using traceboxes - the plane distances are expanded according to the size of the box. in the case of q1bsp these distances are precomputed, hence why only certain 'hull' sizes work correctly.
so yes, fraction is the (decimal)percentage of the distance travelled. 0 if it hit immediately, 50% if the wall was half of the distance away, and 1 if it travelled the full distance without hitting anything.
the startsolid flag is poorly defined. logic dictates that it can only be set when fraction is 1, which makes testing for it unreliable. often you'll want to ignore startsolid, because it can be better to allow traces through solids if you're already inside them as a way to attempt to counter any precision issues. alternatively you can do what nq player physics does, and just teleport the player back to their oldorigin if the player gets stuck.
the other contents flags are similarly unreliable, and reflect only the nearest impact. if you're pushing against a submodel while in water, if it detects and impact against that submodel then you won't be in water, but if you move away slightly then suddenly you will be. pointcontents is more reliable for this sort of thing.
if you cast a ray from A to B, that ray you can hit planes C,D,E,F, etc. each plane has its own plane and normal.
distfromA = dotproduct(A, planenormal) - planedist;
distfromB = dotproduct(B, planenormal) - planedist;
fraction = distfromA / (distfromB-distfromA);
endpos = A + (B-A)*fraction;
if you're doing triangle-based collision, then there are 3 more dotproducts against endpos and the 3 planes that define the edges of the triangle.
brush collision does some traces against every single plane of the brush to figure out which plane it actually hit (furthest, so long as it wasn't clipped by another plane).
bsp collision provides an ordered tree of planes, with the results of plane checks determining which other leafs/planes need to be checked.
the actual trace that is returned by traceline is then the trace against the plane which resulted in the lowest fraction (where it actually hit the geometry that included that plane, and where the far side is considered solid with the near side not).
things get more messy when using traceboxes - the plane distances are expanded according to the size of the box. in the case of q1bsp these distances are precomputed, hence why only certain 'hull' sizes work correctly.
so yes, fraction is the (decimal)percentage of the distance travelled. 0 if it hit immediately, 50% if the wall was half of the distance away, and 1 if it travelled the full distance without hitting anything.
the startsolid flag is poorly defined. logic dictates that it can only be set when fraction is 1, which makes testing for it unreliable. often you'll want to ignore startsolid, because it can be better to allow traces through solids if you're already inside them as a way to attempt to counter any precision issues. alternatively you can do what nq player physics does, and just teleport the player back to their oldorigin if the player gets stuck.
the other contents flags are similarly unreliable, and reflect only the nearest impact. if you're pushing against a submodel while in water, if it detects and impact against that submodel then you won't be in water, but if you move away slightly then suddenly you will be. pointcontents is more reliable for this sort of thing.
- Spike
- Posts: 2892
- Joined: Fri Nov 05, 2004 3:12 am
- Location: UK
Re: CSQC Tracelines
Thanks a lot Spike, as always very detailed answer! 
The description you posted of trace_fraction is of course, about how it works in C engine, right?
It means "do something only if the ray didn't intercept anything solid", right? But, the thing I cannot understand is: why should I need that information?
Usually I use tracelines (I use it for 100 other thing but most of it for) either for physics or for weapon code.
Usually I do something like that:
If I add
How can change the weapon damage code?
Thanks again for your great explanation!
The description you posted of trace_fraction is of course, about how it works in C engine, right?
?? Every plane has its own plane? And when do you talk about planes, do you mean bsp faces splitted in quad faces(2 triangles joined by 1 edge)?Spike wrote:each plane has its own plane and normal.
Ok, so, writingso yes, fraction is the (decimal)percentage of the distance travelled. 0 if it hit immediately, 50% if the wall was half of the distance away, and 1 if it travelled the full distance without hitting anything. wrote:
- Code: Select all
if (trace_fraction == 1){
//do something
}
It means "do something only if the ray didn't intercept anything solid", right? But, the thing I cannot understand is: why should I need that information?
Usually I use tracelines (I use it for 100 other thing but most of it for) either for physics or for weapon code.
Usually I do something like that:
- Code: Select all
//mouse fire check
//refire check
traceline(weapon fire source,weapon fire source+ v_forward * how far weapon can shoot,0,self);
if (trace_ent.takedamage){
trace.ent.health-=whatever;
}
If I add
- Code: Select all
if(trace_fraction != 0){
if (trace_ent.takedamage){
trace.ent.health-=whatever;
}
}
How can change the weapon damage code?
Thanks again for your great explanation!
Meadow Fun!! - my first commercial game, made with FTEQW game engine
- toneddu2000
- Posts: 1352
- Joined: Tue Feb 24, 2009 4:39 pm
- Location: Italy
Re: CSQC Tracelines
There is a lot of applications to trace_fraction, but I mostly use it for either proportional damage or because as I said is a more reliable collision test than checking trace_ent directly.
I know FrikaC made a cgi-bin version of the quakec interpreter once and wrote part of his website in QuakeC
(LordHavoc)
-

frag.machine - Posts: 2090
- Joined: Sat Nov 25, 2006 1:49 pm
Re: CSQC Tracelines
Thanks frag.machine, so, why
it's
could it be considered as "if the tracing ray hasn't hit anything yet, let's see if the trace_ent has requirements I'm looking for"?
Thanks again
if (trace_fraction < 1.0)
it's
?a more reliable collision test than checking trace_ent directly
could it be considered as "if the tracing ray hasn't hit anything yet, let's see if the trace_ent has requirements I'm looking for"?
Thanks again
Meadow Fun!! - my first commercial game, made with FTEQW game engine
- toneddu2000
- Posts: 1352
- Joined: Tue Feb 24, 2009 4:39 pm
- Location: Italy
Re: CSQC Tracelines
If trace_fraction is less than 1.0 means it hit something (including the world).
if trace_ent == world either can be "I hit nothing, then I will return a null reference entity (trace_ent == world and trace_fraction == 1.0)
OR
"I hit the world, thus I'll return it, even though I normally return it when I hit nothing too (trace_ent == world but trace_fraction < 1.0).
traceline has a very particular behaviour regarding entities it may ignore. In DP and FTE its behaviour was extended (and additional buitins like tracebox are supported), making it even more complicated to understand.
I remember reading some stuff from FrikaC that helped me a lot. Check the Wiki.
EDIT: added wiki link.
if trace_ent == world either can be "I hit nothing, then I will return a null reference entity (trace_ent == world and trace_fraction == 1.0)
OR
"I hit the world, thus I'll return it, even though I normally return it when I hit nothing too (trace_ent == world but trace_fraction < 1.0).
traceline has a very particular behaviour regarding entities it may ignore. In DP and FTE its behaviour was extended (and additional buitins like tracebox are supported), making it even more complicated to understand.
I remember reading some stuff from FrikaC that helped me a lot. Check the Wiki.
EDIT: added wiki link.
I know FrikaC made a cgi-bin version of the quakec interpreter once and wrote part of his website in QuakeC
(LordHavoc)
-

frag.machine - Posts: 2090
- Joined: Sat Nov 25, 2006 1:49 pm
Re: CSQC Tracelines
As far as I know ssqc and csqc don't know anything about each others (but they can share data, though). So, basically is as they would live in different dimensions. I usually do all the traceline computation in ssqc and then sendentity a vector and then I read that vector in csqc and make all the magic directly in csqc. Sorry cannot to help you more now but I'm replying from mobile and it's impossible for me to write code with phone.. 
Meadow Fun!! - my first commercial game, made with FTEQW game engine
- toneddu2000
- Posts: 1352
- Joined: Tue Feb 24, 2009 4:39 pm
- Location: Italy
Re: CSQC Tracelines
This is why I hate smartphones. I saw first post on my mobile and I thought c0burn's post it was the last one and I replied to it. Back to pc I found out it was the first one...grrrr 
Meadow Fun!! - my first commercial game, made with FTEQW game engine
- toneddu2000
- Posts: 1352
- Joined: Tue Feb 24, 2009 4:39 pm
- Location: Italy
10 posts
• Page 1 of 1
Who is online
Users browsing this forum: No registered users and 1 guest