Author Topic: [Tutorial] Vectors, Vector Math, Raycasts, and Radius Searches  (Read 10034 times)

Someone requested this, I decided to write it up.
Vectors
What the heck are these?
A 2D vector is made up of two parts, a direction (angle) and a magnitude (length). You will learn this in math class eventually for all you younger people.
In games, vector's aren't usually defined by an angle and magnitude. Instead, they're defined by their x and y components (their length in the x and y directions).
Here's a picture of a few vectors.


Your classic 2D vectors
Vector a is written using the direction (angle from x axis) and magnitude (length) method. Games dont normally use this but its for mathematical reference.
Vector b is a standard vector in component form (which is the format that most games use)
Vector c just shows the vector with a negative x component.

Dealing with 3D vectors can be a bit more complicated just because of the extra dimension (and if you want to do anything super technical, you're going to need to know more).
Torque (and many other things) use a 3 number vector being the X Y and Z of the endpoint of that vector which can make this a lot easier.
Torque vectors X Y Z values are seperated by spaces and are defined in quotes. A vector in torque would look like:
Code: [Select]
%myFirstVector = "1 4 39"; //Vector from 0,0,0 to X,Y,Z 1,4,39 respectivelyAll 3D vectors defined this way start form the origin 0,0,0 and go out to the X Y and Z value defined. It makes the math nice and easy.


You classic 3D vectors
Vector a and b are both vectors with the endpoints being the position of the bricks.

Vector Math
There's a lot of things that you can do with vectors (These are all in 2D representation from the origin but its the same principle in 3D)

Vector Addition
Here, we take a vector and add another vector to it. Essentially we just hook the two vectors onto to each other.
I've heard this refered to as the tip to tail method, you take the tip (end) of the first vector, and stick the tail (beginning) of the second vector onto that.
The code that is used to do this is:
Code: [Select]
%resultantVector = VectorAdd(%a,%b);
Vector Inverse
Here, we take a vector and make it negative. Doing this just reverses the direction by 180 degrees.
The code to take the inverse is as follows: (We scale (multiply) each value by negative one, reversing the direction of the vector))
Code: [Select]
%resultantVector = VectorScale(%a,-1);
Vector subtraction
It's best to understand the previous one before reading this.
Vector subtraction is like vector addition but instead of adding the second vector normally, you negate it first (this is the easiet explanation I've learned)
Here's the code:
Code: [Select]
%resultantVector = VectorSub(%a,%b);
Vector Length
Length of the vector.
You'll find it's the same as the distance formula in math if you learned it.
And again, here's the code:
Code: [Select]
%vectorLength = VectorLen(%a);
Vector Normalization
This takes the vector and reduces it's length to 1 but keeps the same direction. Called a normal vector once normalized.
In math, it's called a unit vector because it has a unit length (1). It's useful when you care about the direction of the vector over the length.
It's useful in the next explanation if you want to scale the vector to a specific length with the same direction.
Code code code:
Code: [Select]
%normalVector = VectorNormalize(%a);
Vector Scaling
This scales a vector to a scalar value (read: integer/number)
It multiplies the vector by a single number to make it longer or shorter.
This is useful with a normalized vector. We could normalize the vector and then scale it by three to get a vector with a length of three (without having to take in the original vector's length).
So much code, so little time:
Code: [Select]
%scaledVector = VectorScale(%a,3);
Vector Distance
This returns the distance between two vectors.
This can actually be done with all the above functions but that's out of the scope of this tutorial.
Developers developers developers developers:
Code: [Select]
%distanceBetweenTheTwo = VectorDist(%a,%b);

Container Raycast
A raycast is where we fire a line from a point, in a direction, for a certain length (the last two make up the endpoint of our raycast).

Wow, that was really helpful and vague Coburn...
So let me break this down, We'll start off with the first part, firing from a point.
A point in blockland is defined by it's position (which I like to represent as a vector).


You can see in this picture, that our brick is at 5,5,0.
Every point is like this, positions of vehicles, position of the player's eye, positions of those 100 music bricks that were spammed in someone's server.
So in a raycast, we start from one of these points and fire, but where?

The where, is determined by a direction and the length. Some engines fire a raycast with a direction and go infinitely, other's go for a certain distance. Torque wants an endpoint.
To find this endpoint, as mentioned above, a direction and a length are needed.
The direction is usually a normalized vector, which are great for directional tasks!
There are a few functions in the game that return normal vectors. Sometime though, you may just have to find a normal vector yourself with math (Oh boy!)
The length is the other thing we need. This is just a number for the length that our direction vector is going to go.

With both of these values, we can get an endpoint for our raycast.
We want to add a vector to the starting point to come up with the endpoint. In order to get that vector, we take the direction vector and scale it with the length scalar.
The code is below but I'll put it here as well.
Code: [Select]
VectorAdd(%starting_position,VectorScale(%direction_vector,%length))

Here we have the point (the eyeposition vector)
We have the normal vector which is our direction (the evyevector in blue)
Our length is just some value long enough for our purpose, we could say, 10
What happens is the raycast will continue along its length until it hits something, our brown brick.
From there, we can get the brick's id from the value returned by the container raycast function (as well as some other things including the point where it hit).

The code for the above in order:
Code: [Select]
%player = findClientByName("Coburn").player; //Find player
%eyepoint = %player.getEyePoint(); //Get his eye point
%eyevector = %player.getEyeVector(); //Get the direction he's looking
%length = 10; //Specify a length
%mask = $Typemasks::All; //Use a typemask
%raycast = containerRaycast(%eye, VectorAdd(%eye,VectorScale(%ev,%length)),%mask,%ignore_this_object);

The %raycast variable holds in information we need to continue on.
Its in the format of "[ID of the object hit] [Vectorx VectorY VectorZ for position the object was hit] [VectorX VectoY Vectorz for the direction of the normal of the face that was hit]"
To get these values we use
Code: [Select]
%object = getWord(%raycast,0); //Object it hit
%positionHit = getWords(%raycast,1,3); //Position the raycast hit
%normalDirection = getWords(%raycast,4,7); //The direction of the normal that it hit

Container Radius Search
This doesn't really have a lot to do with vectors but I thought I'd throw it in here.
Radius searching allows you to search a sphere for objects. This is useful in many different cases from things like doing special things in an explosion radius to selecting multiple objects in a radius to make building easier.
It's a similar concept as the raycast in that it looks for specific objects but it can find more than one (a raycast stops when it hits an object).
To perform a radius search you need two things, a point and a radius, pretty simple.

The point is where the radius searches center is.
The radius is how far out in EVERY direction the search will continue, effectively meaning you're searching a sphere.
A visualization of this can be seen below:


The red lines on the inside of the sphere represent the radius. It is basically how big the sphere is going to be and allows you to search in a bigger area for objects.

Because container radius search can retrieve multiple objects, there isn't a simple return.
It's much different to start on as opposed to a raycast.
The code to start one is as follows.

Code: [Select]
%player = findClientByName("Coburn").player; //Find player
%position = getWords(%player.getTransform(),0,2); //Get his position
%radius = 10; //Specify a radius to search
%mask = $Typemasks::All; //Use a typemask
initContainerRadiusSearch(%position, %radius, %mask);

This piece of code is actually really useless by itself because it doesn't return anything, it only starts the search.
To actually find the objects we need to call a seperate function, containerSearchNext
Code: [Select]
%object = containerSearchNext();What this does is go through each object that the search found until it runs out of objects.
To get all the objects, you can set up a simple loop like this
Code: [Select]
while(%object = containerSearchNext())
{
//Do something with each %object here like putting them into an array or something.
}

Two other useful functions are as follows
Code: [Select]
containerSearchCurrDist(); //Get's the distance from the current object to the center of the radius search
containerSearchCurrRadiusDist(); //Get's the distance from the closest point on that current object to the center of our radius search

That's about it for now. Might include box searches later if I get time to work with them at all.
In the above code you can see that we need a typemask... [insert link or more info here]
« Last Edit: February 23, 2013, 12:40:16 PM by DYLANzzz »

Love how quick modify works but the normal modify doesn't?


Common uses for raycasts that may be of use to you:
How to find out whether an object is in your FoV (or a FoV like space)
« Last Edit: October 07, 2013, 02:30:12 PM by DYLANzzz »

Tell me if I got anything wrong :3
« Last Edit: February 09, 2013, 07:19:32 PM by DYLANzzz »

Great job so far! Much appreciated, I'll put this to good use.
« Last Edit: February 06, 2013, 10:40:29 PM by Greek2me »

Very nice. Nice to see someone put such effort into a tutorial

Thank you for posting this, I have been very knowledgeable upon many things in Torque Script. Unfortunately, I did not know about this.

Great job so far! Much appreciated, I'll put this to good use.
Glad some people will be using this. Im gonna hopefully add most of the container features and all the vector math functions along with pictures and code snippets.

Bump for container radius search and proofread of first part

FINALLY, would you mind if I use this for my Torquescript tutorials ?  All credit will be given to you.

FINALLY, would you mind if I use this for my Torquescript tutorials ?  All credit will be given to you.
Not at all


Why name it "[Tutorial]"? Just name it "[Resource]"..

Why name it "[Tutorial]"? Just name it "[Resource]"..

Lol it's not really a resource, it's a tutorial.

kinda helpful for remember the arguments of containerRaycast.