Inside3D!
     

gettaginfo (origin of tag issues)

 
Post new topic   Reply to topic    Inside3d Forums Forum Index -> QuakeC Programming
View previous topic :: View next topic  
Author Message
Chris



Joined: 05 Aug 2006
Posts: 78

PostPosted: Wed Nov 19, 2008 12:46 pm    Post subject: gettaginfo (origin of tag issues) Reply with quote

So I've never managed to see these functions dp offers working properly or could ever get them to work. my latest endeavor is into adding smoke particles to the end of a gun's barrel referencing it's "mflash" tag. However the origins its returning are far far outside of the map. Could someone point me in the right direction for what to use as the tag's final origin ? This is my current code:

Code:


   local float TagIndex;
   local vector org;

   TagIndex= gettagindex(cl_RHand, "mflash");
   org = gettaginfo(cl_RHand, TagIndex);

   pointparticles(particleseffectforname("gun_smoke"), org, '0 0 0', 1);



Now I'm positive the pointparticles exist (setting them to player's origin I see them fine). However they appear far far outside the map and I don't know the mathematical relation to the actual origin of the tag (which is what I assume it is SUPPOSED to be giving me in the first place.)

am I right in simply setting the vector returned from the gettaginfo as the origin to set my smoke? Or is there some other secret undocumented calculation I'm missing?

Also before someone suggests it: No, the origin it is returning isn't '0 0 0', it indeed is returning some value based off of the tag, however the value returned is not the world space origin of the tag which is what it is documented as returning. I am using the latest available build off of dp's website.
Back to top
View user's profile Send private message MSN Messenger
jim



Joined: 05 Aug 2005
Posts: 400
Location: In The Sun

PostPosted: Wed Nov 19, 2008 2:17 pm    Post subject: Reply with quote

I use this to spawn an item drop from a character's hand tag:

Code:

tindex = gettagindex(self, "helper_l_hand");

if(tindex)
   tagvec = gettaginfo(self, tindex);

// spawn it there
drop = spawn();
if(tagvec)
   drop.origin = self.origin + tagvec;


It looks like you don't add the org into cl_RHand.origin. Now they're added into the map origin, which is why they appear outside the map.
_________________
zbang!
Back to top
View user's profile Send private message Visit poster's website
Chris



Joined: 05 Aug 2006
Posts: 78

PostPosted: Wed Nov 19, 2008 7:10 pm    Post subject: Reply with quote

Code:

   TagIndex = gettagindex(cl_RHand, "mflash");
   org = gettaginfo(cl_RHand, TagIndex);
   pointparticles(particleseffectforname("gun_smoke"),  cl_RHand.origin + org, '0 0 0', 1);


This still produces way outside of map results. More so even if this worked then the documentation is wrong because its supposed to be worldspace not local space which I've informed LH of countless times over the past year but it has never been sought to.

Mind you this is in CSQC, I've heard directly from him tag origins work in CSQC and someone somewhere had it working well enough, however I don't see anyone's proper implementation with it working. This is a continually updating thing, cl_RHand is always in front of the player so its not the actual entity may be off, and the tag does change when fired and it's location changes when I move so I know it has a tag. It either simply does not work or this is not how you do it.

Does anyone have source with this implemented correctly? Or any reason why it may be producing these results? Does it have something to do with the v_forward / v_right / v_up vectors it sets and I use those not origin? I know the pattern isn't random but when I set my view to the spot it "thinks" the tag is its just quickly moving away from map very far.

Does this break on CSQC models with specific render flags? Someone please with a modicum of knowledge reply this is becoming so frustrating Sad
Back to top
View user's profile Send private message MSN Messenger
Spike



Joined: 05 Nov 2004
Posts: 944
Location: UK

PostPosted: Thu Nov 20, 2008 3:37 am    Post subject: Reply with quote

Code:

vector getlerpedtaginfo(entity ent, float tagnum)
{
   //personally I consider it a bug that this function is needed.
   //this function exactly duplicates the gettaginfo builtin (by using it)
   //but ensures that interpolation based on frame2 happens.
   //this matches how the renderer will lerp frames.

   float frame2ness = ent.lerpfrac;
   float frame1ness = 1-frame2ness;
   float f1=ent.frame;
   float f2=ent.frame2;
//it doesn't matter what the ent's lerpfrac currently is.
   vector f1o, f1f, f1r, f1u;
   vector f2o, f2f, f2r, f2u;
   vector v_origin;

   //make sure both frames are set, in case the builtin is fixed
   ent.frame = f1;
   ent.frame2 = f1;
   f1o = gettaginfo(ent, tagnum);
   f1r=v_right;f1f=v_forward;f1u=v_up;

   ent.frame = f2;
   ent.frame2 = f2;
   v_origin = gettaginfo(ent, tagnum);

   //restore the entity
   ent.frame = f1;
   ent.frame2 = f2;

   //lerp the current frame2 with the cached frame1 values
   v_forward = f1f*frame1ness+v_forward*frame2ness;
   v_right = f1r*frame1ness+v_right*frame2ness;
   v_up = f1u*frame1ness+v_up*frame2ness;
   v_origin = f1o*frame1ness+v_origin*frame2ness;

   return v_origin;
}

vector RotateVectorsByTag_QC(entity ent, float tagnum)
{
   vector saveang=ent.angles;
   vector saveorg=ent.origin;

   vector oldx=v_forward, oldy=('0 0 0'-v_right), oldz=v_up;
   vector oldo=ent.origin;

   ent.angles = '0 0 0';
   ent.origin = '0 0 0';
   vector ango=getlerpedtaginfo(ent, tagnum);
   ent.angles = saveang;
   ent.origin = saveorg;
//note: v_right is actually left, in tags.
   vector angx=v_forward, angy=v_right, angz=v_up;

//quake3 always normalizes, darkplaces does not.
   angx = normalize(angx);
   angy = normalize(angy);
   angz = normalize(angz);

   //multiply out the tag matrix with the previous matrix.
   v_forward_x = angx_x*oldx_x + angx_y*oldy_x + angx_z*oldz_x;
   v_forward_y = angx_x*oldx_y + angx_y*oldy_y + angx_z*oldz_y;
   v_forward_z = angx_x*oldx_z + angx_y*oldy_z + angx_z*oldz_z;
   v_right_x   = angy_x*oldx_x + angy_y*oldy_x + angy_z*oldz_x;
   v_right_y   = angy_x*oldx_y + angy_y*oldy_y + angy_z*oldz_y;
   v_right_z   = angy_x*oldx_z + angy_y*oldy_z + angy_z*oldz_z;
   v_up_x      = angz_x*oldx_x + angz_y*oldy_x + angz_z*oldz_x;
   v_up_y      = angz_x*oldx_y + angz_y*oldy_y + angz_z*oldz_y;
   v_up_z      = angz_x*oldx_z + angz_y*oldy_z + angz_z*oldz_z;

   v_right = '0 0 0'-v_right;

   //transform the tag's origin
   saveorg = oldo;
   saveorg_x += ango_x * oldx_x;
   saveorg_y += ango_x * oldx_y;
   saveorg_z += ango_x * oldx_z;
   saveorg_x += ango_y * oldy_x;
   saveorg_y += ango_y * oldy_y;
   saveorg_z += ango_y * oldy_z;
   saveorg_x += ango_z * oldz_x;
   saveorg_y += ango_z * oldz_y;
   saveorg_z += ango_z * oldz_z;
   return saveorg;
}

void RotateVectorsByAngle_QC(vector angle)
{
   vector oldx=v_forward, oldy='0 0 0'-v_right, oldz=v_up;
   angle_x = -angle_x;
   makevectors(angle);
   vector angx=v_forward, angy='0 0 0'-v_right, angz=v_up;

   v_forward_x = angx_x*oldx_x + angx_y*oldy_x + angx_z*oldz_x;
   v_forward_y = angx_x*oldx_y + angx_y*oldy_y + angx_z*oldz_y;
   v_forward_z = angx_x*oldx_z + angx_y*oldy_z + angx_z*oldz_z;
   v_right_x   = angy_x*oldx_x + angy_y*oldy_x + angy_z*oldz_x;
   v_right_y   = angy_x*oldx_y + angy_y*oldy_y + angy_z*oldz_y;
   v_right_z   = angy_x*oldx_z + angy_y*oldy_z + angy_z*oldz_z;
   v_up_x      = angz_x*oldx_x + angz_y*oldy_x + angz_z*oldz_x;
   v_up_y      = angz_x*oldx_y + angz_y*oldy_y + angz_z*oldz_y;
   v_up_z      = angz_x*oldx_z + angz_y*oldy_z + angz_z*oldz_z;

   v_right = '0 0 0'-v_right;
}


DISCLAIMER:
it needs a really recent version of fteqcc due to the variably initialised locals. You can recode that easily enough.

the above functions provide:
void RotateVectorsByAngle_QC(vector angle);
vector RotateVectorsByTag_QC(entity ent, float tagnum);

The first will rotate the v_forward/v_right/v_up vectors around the given angle without altering the origin.
The second will rotate the v_forward/v_right/v_up vectors around the given entity based on its current origin/angles.

that is:
//make sure self.origin and self.angles are valid and where the view is positioned/is oriented.
makevectors(self.angles);
org = rotatevectorsbytag(self, self.tagnum)
//org + v_* are set to where the tag is on the given model
ent2.origin = org;
org = rotatevectorsbytag(ent2, ent2.tagnum)
//org + v_* are set to where the tag is on the ent2 entity when the ent2 entity is attached to self.

csqc supports RF_USEAXIS, which means that you can use the above code to position/orient your ents using the same kind of code as figuring out where your shots should appear, as well as give full control over machine gun barrel rotations, etc.

Alternatively you can supposedly use attachments. I've not done so myself, so I'm not sure how painful they will be.

The above code will work just fine on an md3 model. its not tested on zym/dpm but it'll work fine there anyway.




Anyway, your original code puts the ents far outside the map because gettaginfo doesn't consider viewmodels.
so cl_RHand.origin = vieworigin; cl_RHand.angles = viewangles;
and then clear them out again after.

Anyway, my code is probably mostly useless, although it might be useful if you want to be able to use interpolated tags... DP doesn't do that for some reason, but in that case you don't need the lot.
_________________
What's a signature?
Back to top
View user's profile Send private message Visit poster's website
Chris



Joined: 05 Aug 2006
Posts: 78

PostPosted: Thu Nov 20, 2008 7:27 pm    Post subject: Reply with quote

Interesting information above, but the small bit of your post in reference to answering this issue i am confused on.

Right now it seems the only way for the model to have it's tags found is to not be a VF_VIEWMODEL? So this means that I need to make it render normall like any other csqc object in the world. The issues here though are the weapon's shadows being shown, (floating arms and gun mid air isn't exactly a welcome issue). Also now the gun of course clips with the world when looking close to walls.

From your post it sounds like you somehow bypass this but I have no idea really what you mean "clear them out later" or what you're assigning. Please elaborate preferably with small simple examples.
Back to top
View user's profile Send private message MSN Messenger
Spike



Joined: 05 Nov 2004
Posts: 944
Location: UK

PostPosted: Fri Nov 21, 2008 12:32 am    Post subject: Reply with quote

gettaginfo doesn't consider RF_VIEWMODEL.
consider this a bug if you want.

RF_VIEWMODEL means 'stick it on the view, and add view bobbing'
unfortunatly the view bobbing can't be easily replicated in csqc for positioning particles, as the times are not always the same.

sticking it on the view is easy, you can just set the origins and angles to match the view. I'm not sure how significant weapon bob is.

For positioning entities, this is fine, as all such entities are relative to each other, and all have RF_VIEWMODEL set. They're just not expressed in world space.

For anything complex (basically particles and mixing world/viewmodel space) its probably best to implement your own bobbing, and simply not use RF_VIEWMODEL.

RF_DEPTHHACK is technically separate, and has the value 4, and will be a view model but positioned in world space. It should presumably have the same shadow lights properties... I'm not sure how its considered in FTE and certainly not in DP (for reference, RF_VIEWMODEL implies RF_DEPTHHACK).

But yeah, if you're adding your entities with RF_VIEWMODEL then any origins returned are relative to the viewmodel's bob matrix **which is not (currently) accessable to csqc**. But you can implement your own and override it by using RF_DEPTHHACK instead of RF_VIEWMODEL and then pretranslate/rotate.

Did that clarify anything?
_________________
What's a signature?
Back to top
View user's profile Send private message Visit poster's website
Chris



Joined: 05 Aug 2006
Posts: 78

PostPosted: Fri Nov 21, 2008 8:35 pm    Post subject: Reply with quote

Okay, ya I figured to just use the renderflags for depthhack and noshadow and I don't really care for weapon bob at the moment so it is ok having that short coming. However for DP the .effects flags don't seem to work on weapons, so I've opted to just use the renderflags ones.

Of course now the biggest short coming of mine is handeling hiding it when chase_active is 1, but I can of course do that in one way or another on my own.
Back to top
View user's profile Send private message MSN Messenger
Display posts from previous:   
Post new topic   Reply to topic    Inside3d Forums Forum Index -> QuakeC Programming All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2004 phpBB Group