Rules FAQ Members List Search Register Login

 Raised This Month: \$19 Target: \$400 4%

Author Message
stupok
Veteran Member
Join Date: Feb 2006
 05-01-2009 , 15:32   Half-Life Position, Velocity, and Angles (for n00bs) #1 Half-Life Position, Velocity, and Angles This guide is intended for newbies with a desire to learn about position, velocity, and angles. The goal is for you to be comfortable manipulating these variables in Pawn in AMXx in Half-Life. Dimensions dimension - a property of space; extension in a given direction 0th dimension There really is no dimension here--it's the 0th dimension, after all. You can think of it as an infinitely small point. It does not extend in any direction. We cannot specify a location in this dimension. 1st dimension Now we have a line in one direction. You can only change the length of the line. Many problems in physics are idealized to one-dimensional problems for simplicity. For example, falling bodies are often idealized to fall straight down with no deviation. We can specify a location in this dimension with one number. For example, a straight line starting from your floor going up to your ceiling. Let's say the floor is 0, the ceiling might be 2.5 (in meters, let's say). Any point in between would be between 0 and 2.5. In code, you can hold the position with a variable like this: Code: `new Float:fHeight` I'm only talking about the first dimension, so, strictly speaking, there is no explicit direction. You can only go back and forth. However, you can say the variable from my example exists in the Y-direction because our world is in three dimensions and saying "Y-direction" implies that we are talking about going up and down, in general. Depending on the context, you might say that a one-dimensional variable is in the X-direction or Z-direction. Typically, you only say that it is in the X or Y directions. 2nd dimension Finally! Now we can move up, down, left, and right (and any combination of these directions). More complicated physics problems are idealized in two dimensions. For example, a projectile's motion is idealized in two dimensions. We can specify a location in two dimensions with a pair of numbers. We call this pair of numbers coordinates. In writing, you usually see coordinates written like this (X, Y). The X-direction means left and right. The Y-direction means up and down. In code, you can hold the position with a variable like this: Code: `new Float:fPosition[2]` The variable is called an array and it holds two values. The first value, fPosition[0], should hold the position in the X-direction. The second value, fPosition[1], should hold the position in the Y-direction. (You can also use [1] for the X-direction and [0] for the Y-direction, but it's nice to do things in a standard way so others can understand your code quickly.) Code: ```public MakeHudMessage( id ) {     // X values range from 0 to 1, 0 is left edge of the screen, 1 is right edge of the screen     // Y values range from 0 to 1, 0 is top edge of the screen, 1 is bottom edge of the screen         new Float:fPosition[2]         fPosition[0] = 0.2 // x position     fPosition[1] = 0.5 // y position         set_hudmessage( 200, 100, 0, fPosition[0], fPosition[1], 0, 6.0, 12.0, 0.1, 0.2, 4 )         // red = 200, green = 100, blue = 0     // x position = 0.2, y position = 0.5     // effects = 0     // fxtime = 6.0     // holdtime = 12.0     // fadeintime = 0.1, fadeouttime = 0.2     // channel = 4         show_hudmessage( id, "Hi this is a hudmessage!" ) }``` set_hudmessage prepares a hud message with position, color, effects, and time show_hudmessage shows text in the way specified by set_hudmessage 3rd dimension OH BOY! Now we can move up, down, left, right, forwards, backwards AND any combination of these directions. We can specify a location in three dimensions with a group of three numbers. In writing, you usually see coordinates written like this (X, Y, Z). The Z-direction means forwards and backwards. BUT WAIT! The Z-direction means forwards and backwards in the picture above, but it actually means up and down in Half-Life. Why? The programmers of Half-Life decided to make the Z-direction up/down. So, forward/back/left/right are handled with the X and Y directions.In code, you can hold the position in three dimensions with a variable like this: Code: `new Float:fPosition[3]` fPosition[0] holds the position in the X-direction, fPosition[1] holds the position in the Y-direction, and fPosition[2] holds the position in the Z-direction. Code: ```public PlayWithOrigins( id ) {     new iOrigin[3]     get_user_origin( id, iOrigin )         // move the player 20 units in the Z-direction (upwards)     iOrigin[2] += 20         set_user_origin( id, iOrigin ) }``` Vectors So far, I've covered the 0th, 1st, 2nd, and 3rd dimensions. The code examples have dealt with coordinates representing positions, but I have hinted at a different use for three-dimensional arrays with my physics examples. You need to learn two new words: vector and scalar vector - a quantity possessing both magnitude and direction, represented by an arrow the direction of which indicates the direction of the quantity and the length of which is proportional to the magnitude scalar - representable by position on a scale or line; having only magnitude When we are dealing with positions, like the position of a player in a map or the position of text on the screen, we are dealing with scalar quantities. Scalar values have no direction, only magnitude (size). When you say a player is located at (X, Y, Z), you know nothing about whether or not he is moving. If he is moving, you don't know where. Velocity is a vector quantity. Let's jump into an example: Code: ```new Float:fVelocity[3] pev( id, pev_velocity, fVelocity )``` pev is a FakeMeta function used to retrieve values from entities pev_velocity tells pev() which value we are retrieving fVelocity holds the value we are retrieving, it must be a 3-dimensional array After executing this code, let's say that our velocity is now (100, 200, 0). This means we have a velocity in the X-direction of 100 units per second, a Y-velocity of 200 units per second, and a Z-velocity of 0 units per second. The numbers directly indicate the magnitude of the velocity. How can we find the direction? (Vector values have both magnitude AND direction.) Here is the situation, in picture form: Notice that the vectors both start at the origin (0, 0, 0) and extend away from it. To get the direction, you must combine all three component vectors (X, Y and Z) into one. (Components are pieces.) So, now we can see that fVelocity holds a vector value. That means you can discover the magnitude AND direction of the velocity by interpreting the values it holds. Speed versus Velocity They are not the same. Speed is a scalar quantity and velocity is a vector quantity. You can store speed in a variable like this: Code: `new Float:fSpeed` To store velocity, you must have a variable like this: Code: `new Float:fVelocity[3]` Speed means distance/time, like miles per hour (mph) or meters per second (m/s). It does not tell you where you are going. Velocity, when you're NOT dealing with code, is written in two parts. First, you say the speed like 40 mph (yes, speed is one part of velocity). Next, you must say the direction. For example, North. When we're dealing with code, you don't have two parts. Instead, you have to interpret the 3 values to figure out speed and direction. Extracting Speed from Velocity Remember Pythagoras? He has this nifty theorem: Code: `c * c = a * a + b * b` In English: C squared equals a squared plus b squared If you glance at the above image with the red, green, and pink arrows, you can see how this works. C is the length of the pink arrow, a is the length of the green arrow, and b is the length of the red arrow. In three dimensions, it's like this: Code: `hypotenuse * hypotenuse = x * x + y * y + z * z` (Hypotenuse is a fancy word for the sloped part of a right triangle. A right triangle is a triangle with a 90 degree angle.) Here's what we were looking for: Code: `speed * speed = x vel * x vel + y vel * y vel + z vel * z vel` Or, in real code: Code: ```new Float:fVelocity[3] // store some velocity into fVelocity // slow, inefficient way (but you get to see what it looks like) New Float:fSpeed = floatsqroot( fVelocity[0] * fVelocity[0] + fVelocity[1] * fVelocity[1] + fVelocity[2] * fVelocity[2] ) // fast, efficient way New Float:fSpeed = vector_length( fVelocity )``` Extracting Direction from Velocity We don't have North, South, East, and West in Half-Life. We just have angles, so that's how we'll represent the direction of our velocity. The math is more complicated, so let's leave it at this: Code: ```new Float:fVelocity[3] new Float:fAngle[3] // store some velocity vector_to_angle( fVelocity, fAngle )``` Example So, let's do something useful useless with our new knowledge. We are going to save the player's position, launch him in a random direction, and finally move him back to his original position. Code: ```public UselessFunction( id ) {     new Float:fOrigin[3]     new Float:fVelocity[3]         // save his origin     pev( id, pev_origin, fOrigin )         // create a random velocity     fVelocity[0] = random_float( 100.0, 500.0 ) * ( random_num(0,1) ? 1.0 : -1.0 )     fVelocity[1] = random_float( 100.0, 500.0 ) * ( random_num(0,1) ? 1.0 : -1.0 )     fVelocity[2] = random_float( 100.0, 500.0 ) * ( random_num(0,1) ? 1.0 : -1.0 )         // set his velocity, WOOSH     set_pev( id, pev_velocity, fVelocity )         // put him back to his original position in 2.0 seconds     set_task( 2.0, "PutMeBackPLZ", id, _:fOrigin, 3 ) } public PutMeBackPLZ( iOrigin[3], id ) {     // set his origin, YAWN     set_pev( id, pev_origin, iOrigin ) }``` set_pev is a FakeMeta function used to set various values for entities random_float generates a random number between two numbers random_num does the same thing, but returns an int rather than a float set_task is used to call a function after a few seconds Angles There is another use for three-dimensional arrays (variables like fVelocity[3]). They are used to store an entity's angles. Pitch, Yaw, and Roll I'm going to use your imagination to make this easy to understand. Imagine a hotdog and place it on the desk in front of you with one end pointing at the monitor. pitch - lift one end of the hotdog while the other end stays on the desk PUT IT BACK DOWN! yaw - now, spin the hotdog on the desk POINT IT AT THE MONITOR AGAIN! roll - now, roll the hotdog along the desk Now do the same actions you did to the hotdog, but move your head instead of the hotdog. (Tilt your head up/down, rotate left/right, and then roll it.) You should begin to feel a sort of satisfaction now that you understand the meaning of pitch, yaw, and roll. If not, yell at me. Here's a nice image that explains pitch, yaw, and roll. Thanks arkshine! (And thanks to the creator, whoever it is.) In Half-Life, the angles are stored thusly: Code: ```new Float:fAngle[3] fAngle[0] // pitch fAngle[1] // yaw fAngle[2] // roll ``` You can use pev() to retrieve the angles, just like we did with velocity or origin, but there are several different angles in Half-Life. You'll have to experiment with them to get a good idea of the purpose they serve. pev_angles - orientation of the entity pev_v_angle - orientation of the camera, (player's view), v_angle = view angle pev_punchangle - deviation from the view angle (POW! I punched you in the kisser and now your face rotated over there but you will slowly return back to your v_angle) You can get/set these just like the others, with FakeMeta or Engine: Code: ```// FakeMeta new Float:fAngles[3] pev( id, pev_angles, fAngles ) set_pev( id, pev_angles, fAngles ) // Engine entity_get_vector( id, EV_VEC_angles, fAngles ) entity_set_vector( id, EV_VEC_angles, fAngles )``` Normal What's a normal? Is it the opposite of a weird? Wow, I'm tired. More vocabulary for your hungry, hungry mind: plane - a flat or level surface normal - the dictionary definition is confusing, so here's mine: a line that is perpendicular to the plane Why is this useful? Well, it get's complicated. Example My Wall Text plugin makes use of positions, vectors, angles, and normals. The goal of the plugin is to aim at a wall and paint text on it. Here's the step-by-step process: 1. Get the position on the wall where the user is aiming. 2. Get the normal of the wall. (The wall is a plane and the normal points out of the wall into the world where the player exists.) 3. Make a vector pointing the to left (from the perspective of the wall's normal). 4. PAINT! 5. Move over to the left, using the vector we calculated. 6. Repeat steps 4-5 until finished. If you're observant, you'll notice that I've neglected to do this calculation for sloped surfaces like ramps. The plugin will work for perfectly vertical walls at any angle, but it will fail if you want to do a multi-line message on a sloped wall like a ramp, because I was too lazy to write the extra code. Here's the code: Code: ```CreateNewMessage( id, szMessage[MESSAGE_LEN] ) {     new Float:fAimOrigin[3]     new Float:fPlayerOrigin[3]         new Float:fAimVector[3]     new Float:fNormalVector[3]     new Float:fTextVector[3]         // user's view angle     pev( id, pev_v_angle, fAimVector )         // vector pointing in that direction     angle_vector( fAimVector, ANGLEVECTOR_FORWARD, fAimVector )         // user's origin     pev( id, pev_origin, fPlayerOrigin )         // lengthen vector and move it to user's origin     fAimVector[0] = fAimVector[0] * 9999.0 + fPlayerOrigin[0]     fAimVector[1] = fAimVector[1] * 9999.0 + fPlayerOrigin[1]     fAimVector[2] = fAimVector[2] * 9999.0 + fPlayerOrigin[2]         // execute traceline, grab normal vector and end position     new iTr = create_tr2()     engfunc( EngFunc_TraceLine, fPlayerOrigin, fAimVector, IGNORE_MONSTERS, id, iTr )     get_tr2( iTr, TR_vecEndPos, fAimOrigin )     get_tr2( iTr, TR_vecPlaneNormal, fNormalVector )     free_tr2( iTr )         // convert normal vector to angles     vector_to_angle( fNormalVector, fTextVector )         // get vector pointing to the right, from the perspective of the normal vector     angle_vector( fTextVector, ANGLEVECTOR_RIGHT, fTextVector )         // lengthen by width of one character, and point towards the left (from the perspective of the normal vector)     fTextVector[0] *= -1.0 * CHAR_WIDTH     fTextVector[1] *= -1.0 * CHAR_WIDTH     fTextVector[2] *= -1.0 * CHAR_WIDTH         // ... }``` __________________ Last edited by Arkshine; 03-01-2016 at 07:36.
TitANious
Veteran Member
Join Date: Feb 2009
Location: Denmark
 05-01-2009 , 15:33   Re: Half-Life Position, Velocity, and Angles (for n00bs) #2 Would help others GJ __________________ I dislike this. "A sneeze never comes alone!" <-- Important to remember.
Veteran Member
Join Date: Dec 2008
Location: Portugal
 05-01-2009 , 15:34   Re: Half-Life Position, Velocity, and Angles (for n00bs) #3 First. I will read it now. Edit: fuck __________________
stupok
Veteran Member
Join Date: Feb 2006
05-01-2009 , 15:34   Re: Half-Life Position, Velocity, and Angles (for n00bs)
#4

Quote:
lol, you have bad luck trying to be the first to post on my threads.
__________________
Veteran Member
Join Date: Dec 2008
Location: Portugal
05-01-2009 , 15:36   Re: Half-Life Position, Velocity, and Angles (for n00bs)
#5

Quote:
 Originally Posted by stupok lol, you have bad luck trying to be the first to post on my threads.
lol. so true.
__________________
TitANious
Veteran Member
Join Date: Feb 2009
Location: Denmark
05-01-2009 , 15:37   Re: Half-Life Position, Velocity, and Angles (for n00bs)
#6

Quote:
 Originally Posted by joaquimandrade First. I will read it now. Edit: fuck
YES!
__________________
I dislike this.

"A sneeze never comes alone!" <-- Important to remember.
xPaw
Retired AMX Mod X Moderator
Join Date: Jul 2008
 05-01-2009 , 15:44   Re: Half-Life Position, Velocity, and Angles (for n00bs) #7 PutMeBackDammit! __________________
Arkshine
AMX Mod X Plugin Approver
Join Date: Oct 2005
 05-01-2009 , 15:49   Re: Half-Life Position, Velocity, and Angles (for n00bs) #8 Woo.~~
Emp`
AMX Mod X Plugin Approver
Join Date: Aug 2005
Location: Decapod 10
 05-01-2009 , 16:16   Re: Half-Life Position, Velocity, and Angles (for n00bs) #9 Code: ``` set_task( 2.0, "PutMeBackDammit", id, fOrigin, 2 ) } public PutMeBackDammit( fOrigin[3], id )``` You are passing fOrigin into set_task (will give you warning tag mismatch). Either use _: or convert it to an int vector first. Secondly, you are only passing the first 2 dimensions through the set_task. Also, in PutMeBackDammit fOrigin[3] should be iOrigin[3] since it isn't really declared a float. I would suggest adding mins/maxs in the angles section. And lastly, clean up your language, it's a little annoying with all the "dammit"s. Anyway, cheers for the tut.
stupok
Veteran Member
Join Date: Feb 2006
 05-01-2009 , 16:36   Re: Half-Life Position, Velocity, and Angles (for n00bs) #10 Thanks for catching the mistakes. I used "dammit" with the intention of adding some humor to an otherwise boring read. Maybe you're right that it's inappropriate, so I've removed all of the occurrences. I'll cover mins/maxs shortly. Thanks! __________________

 Thread Tools Display Modes Linear Mode

 Posting Rules You may not post new threads You may not post replies You may not post attachments You may not edit your posts BB code is On Smilies are On [IMG] code is On HTML code is Off Forum Rules
 Forum Jump User Control Panel Private Messages Subscriptions Who's Online Search Forums Forums Home Server Discussion     Source Servers (SRCDS)     HL1 Servers (HLDS) AMX Mod X     News     Bug Reports     General     Off-Topic     Plugins         Suggestions / Requests         Approved Plugins         New Plugin Submissions         Unapproved/Old Plugins         Translation Request         High-Traffic Plugins             GunGame             UAIO (Ultimate All-In-One Plugin)             xREDIRECT             CSDM             AMX Super             RuneMod             Zombie Plague Mod             SuperHero Mod                 News                 Tech Support                 Scripting Help                 Off-Topic / General Chat                 Heroes                     Suggestions / Requests                     Approved Heroes                     New Submissions                     Unapproved/Old Heroes                         Module Heroes                     SuperHero Mod Stats - By 123                 (OLD) Bug Reports     Scripting         Scripting Help         Code Snippets/Tutorials         Module Coding     Donor Access SourceMod     News     General     Plugins         Plugins         Unapproved Plugins         Plugin/Gameplay Ideas and Requests         High-Traffic Plugins             SourceMod Anti-Cheat             Zombie:Reloaded             SourceBans / SourceBans++             VSH / Freak Fortress             Store             SM_Hosties             HLstatsX:CE     Scripting     Extensions     Snippets and Tutorials     Donor Access     Metamod: Source         Metamod:Source Plugins         Metamod:Source Questions         Coding MM:S Plugins & SM Extensions Hosted Stuff     Asherkin's Plugins         TFDodgeball         TF2Items         SteamTools     Bail's Plugins         CSDM         CS:S DM Off-Topic & Trash     Off-Topic     Trash

All times are GMT -4. The time now is 04:09.

 DMCA - Archive - Top