PDA

View Full Version : Vector confusion


Nial
06-05-2007, 04:25 AM
I've been struggling with Vector usage in the HL2 SDK. Basically, what I'm attempting to do is get a vector location that represents the waist of a player.

In my mind, I imagined using GetAbsOrigin() to retrieve the base location of the player (the feet), and then adding a vector like: Vector( 0, -90, 0 ); I'm obviously getting confused here. To me, the above vector should point upwards, along the Y axis.

GetAbsOrigin() + Vector (0, -90, 0); // Move up from the players feet.

Obviously I have this drastically wrong. Digging around in existing code, I've found stuff like this... which spawns objects where the player is pointing his/her crosshair:


Vector vecForward;
AngleVectors( EyeAngles(), &vecForward );

Vector vecOrigin = GetAbsOrigin() + Vector(vecForward.x, vecForward.y, vecForward.z) * 256 + Vector(0,0,64);
QAngle vecAngles( 0, GetAbsAngles().y - 90, 0 );


Now, from there, I understand that: we're retrieving the players base position, and then we're adding the Forward vector to it (as retrieved from AngleVectors). After that, I'm not certain why *256 is necessary, unless it's just specifying the distance in front of the player that we're looking to spawn the object.

The way I understand it: Vectors are used to specify location, Angles are used to specify rotation around the specified axis.

Can anyone give me some insight?

Marine
06-05-2007, 04:58 AM
In theory you could get the position of any bone in a player model. Check out the GetBone and GetAttachment ;)

vinla
06-05-2007, 05:55 AM
Hi Nial,

I am not infornt of my machine with the SDK on, but I'll try to help.

Firstly is SetAbsOrigin actuall returning a Vector? Sounds like a method to set the origin rather than retrieve it. Maybe you need to look for GetAbsOrigin() or use the underlying member variable directly?

Secondly a vector is made up of two things

* A direction
* a magnitude

Normalised vectors (i.e. vectors with a magnitude of 1) can be used to specify a direction.

Vectors used to specify a location are in escence saying if your start at the opriin (0,0,0) and travel x in the direction y you will get the point z. Where x is the magnitude of the vector and y is the direction of the vector.

In the case of trying to find the middle of the character you are not too far from the correct code. However, I believe that Z is the "up" axis and not "y" (which is contrary to directX standards I know) - although I might be wrong on this.

Don't be fooled by AngleVectors, this method will return you the 3 perpendicular and normalized vectors. One in the same direction as the input vector, one to the right of the vector, and one "up" from the vector. Note I put "up" in inverted commas, it is not up as in world co-odinates, but up from the perspective of the input vector. I know it is quite confusing.

Another handy function is VectorMA this allows you Multiply and Add a vector to an existing vector to get a new vector.

So the code you are looking for might be


Vector absOrigin = GetAbsOrigin();
Vector middle;
Vector up = new Vector(0,0,90);

VectorMA(middle, up, 96, absOrigin)


middle should now contain the vector you are looking for. I can't vouch for this code as, like I said, I am not at my home computer right now, but it might give you something to look at.

As Marienio states, GetBones() might be worth looking at, but if this is for a simple task then Vector maths would be a light weight, quick and simple solution.

Hope this helps.

Ging
06-05-2007, 06:44 AM
The usage you want is something more like this:


Vector vOrigin = pPlayer->GetAbsOrigin();
vOrigin += new Vector(0, 0, 90);


Z is indeed up (which may be against API standards, but is standard in 3D math) so keep that in mind when dealing with vectors in the future. The multiplication by 256 does indeed result in movement along the vector specified (vecForward).

vinla
06-05-2007, 07:05 AM
Cheers Ging,

My sample was a little mixed up (and wrong - my up vector should have been 0,0,1 not 90 ), that is much simpler. Although I did want to point out the VectorMA function as it is very useful when you want to move along a direction specified by another vector.

Not too sure about Z being standard up in 3D maths, I always thought that Y was considered to be UP, because it standard 2D cartesian X is across and Y is up and in 3d cartesian Z is introduced as depth. This is generally accepted throughout the graphics industry at least (hence Z buffering, i.e. depth buffering). It just seemed to me that valve had thier own way for some reason. Not that it matters, its just a little confusing.

Ging
06-05-2007, 08:46 AM
The orientation of the Z-Axis depends on where you're coming from in terms of education, pure mathematicians tend to use Y as 'up', engineers / physics types tend to use Z as 'up'.

Computers use Z like they because the monitor forms the X/Y plane - changing that when you're working between 2D and 3D would get mighty confusing, so the X/Y plane is maintained and the Z is used to represent depth. Of course, that doesn't mean much when you're dealing with a virtual representation, it's a bit like zero gravity, anywhere can be up, it's all about how you orientate yourself.

Nial
06-05-2007, 10:39 AM
Yes, I was confused about the direction of the Z axis. I'd always been told that Y represented vertical direction. And I did mean GetAbsOrigin. Typo!

Sadly, I'm still having problems:


Vector TS = GetAbsOrigin() + Vector(0, 0, 90);
UTIL_SetOrigin( pT, TS );
pT->Spawn();


This code has no effect. The object still spawns at the players feet. Using the += operator results in the following compile error:


Vector TS = GetAbsOrigin();
TS += new Vector(0, 0, 90);
UTIL_SetOrigin( pT, TS );



error C2679: binary '+=' : no operator found which takes a right-hand operand of type 'Vector *' (or there is no acceptable conversion)
2> c:\roone\src\public\vector.h(113): could be 'Vector &Vector::operator +=(const Vector &)'

Marine
06-05-2007, 11:03 AM
I would still (Personally), use a bones position, as it is going to be so much more accurate. Use:


LookupBone( "Bone Name" );

and

GetBonePosition( Bone integer--function above, value to put origin, value to put angles );

Nial
06-05-2007, 12:33 PM
Aha, I found the root of the problem. I was calling my BaseClass Spawn function, which was causing trouble with my objects positioning.

Thanks for all the help!

SteveUK
06-07-2007, 11:24 PM
Why did you add 90" on the height? A player is 76" (6 feet) tall.