Forum

CSQC Tracelines

Discuss CSQC related programming.

Moderator: InsideQC Admins

CSQC Tracelines

Postby c0burn » Wed May 25, 2016 8:57 pm

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:

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: 206
Joined: Fri Nov 05, 2004 12:48 pm
Location: Liverpool, England

Re: CSQC Tracelines

Postby frag.machine » Wed May 25, 2016 11:29 pm

Not saying I have any idea why your code isn't working as expected but... usually I prefer
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)
User avatar
frag.machine
 
Posts: 2055
Joined: Sat Nov 25, 2006 1:49 pm

Re: CSQC Tracelines

Postby toneddu2000 » Sat Jun 11, 2016 11:02 am

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
toneddu2000
 
Posts: 1286
Joined: Tue Feb 24, 2009 4:39 pm
Location: Italy

Re: CSQC Tracelines

Postby Spike » Sat Jun 11, 2016 1:04 pm

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.
Spike
 
Posts: 2876
Joined: Fri Nov 05, 2004 3:12 am
Location: UK

Re: CSQC Tracelines

Postby toneddu2000 » Sat Jun 11, 2016 6:53 pm

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?
Spike wrote:each plane has its own plane and normal.
?? 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)?

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. wrote:
Ok, so, writing
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! :)
toneddu2000
 
Posts: 1286
Joined: Tue Feb 24, 2009 4:39 pm
Location: Italy

Re: CSQC Tracelines

Postby frag.machine » Sun Jun 12, 2016 3:22 pm

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)
User avatar
frag.machine
 
Posts: 2055
Joined: Sat Nov 25, 2006 1:49 pm

Re: CSQC Tracelines

Postby toneddu2000 » Mon Jun 13, 2016 7:40 pm

Thanks frag.machine, so, why
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
toneddu2000
 
Posts: 1286
Joined: Tue Feb 24, 2009 4:39 pm
Location: Italy

Re: CSQC Tracelines

Postby frag.machine » Mon Jun 13, 2016 9:32 pm

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.
I know FrikaC made a cgi-bin version of the quakec interpreter once and wrote part of his website in QuakeC :) (LordHavoc)
User avatar
frag.machine
 
Posts: 2055
Joined: Sat Nov 25, 2006 1:49 pm

Re: CSQC Tracelines

Postby toneddu2000 » Tue Jun 14, 2016 1:07 pm

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.. :confused:
toneddu2000
 
Posts: 1286
Joined: Tue Feb 24, 2009 4:39 pm
Location: Italy

Re: CSQC Tracelines

Postby toneddu2000 » Fri Jun 17, 2016 5:12 pm

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 :confused:
toneddu2000
 
Posts: 1286
Joined: Tue Feb 24, 2009 4:39 pm
Location: Italy


Return to CSQC Programming

Who is online

Users browsing this forum: No registered users and 1 guest