 Howdy guys, this is IndiePixel. So in this tutorial, we're going to continue our VEX series on points and lines. And talk about how to recreate that line tool. So here we have the recreation of the line tool. So it's just got the length. We have our points. All right, and we also have direction now. Awesome. We're also going to cover the ramp parameter that we can automatically hook up using VEX. It's super easy. I just wanted to cover that so you guys can see how that's done. And then finally, we're going to do a little trigonometry and create a circle out of our line. All right. And then in this case, we don't have a perfect circle. So let's add some more points there. Awesome. So we're going to learn how to do all that stuff. So let's get started. So what I'm going to do is jump up and out just so we can start fresh. And I'm going to create a new geometry node over here and delete that file. And let's just hide the previous line that we created. So let's start by creating that line. So I'm going to create a attribute wrangle node. It's our friend. All right. And what I'm going to do actually, in this case, first just name this. I'm going to give this a name of custom line. And what I'm going to do is pop open the script editor. So I'm going to hit Alt E on the keyboard with my mouse over the VEX expression window right here. So the first few things that we need. So we need a length property or variable. So let's do a float called length. All right. And this is going to be equal to a CH, a channel. OK. And we're just going to call this length. So that's the name. That's the label that's going to show up here in the window. And then what I want to do is create a point count. So we need an int for that. So we're going to call this point count. And that's equal to CHI for integer channel. And we're just going to call this points. All right. And then what I want to do is provide a direction value. So let's do a vector. And we're going to call this dir for direction. And that's going to be CHV for a vector channel. OK. So we're just going to label this direction like so. OK. So let's hit Apply and Accept. And what we need to do is just expose these channels. So we hit the little button over here. All right. And that provides us with some values. So I'm just going to leave this at 1. And let's just create two points for now. And we'll just put a direction of 1, like so. All right. So let's continue on and open that script editor again over here. And what I want to do is make sure that the direction's always normalized. Because we can come in here. And the user can come in and just keep adding value. And we don't necessarily want that to add onto our length. We want the length to control the length of the line, not the direction and the length. So in order to make sure that we always have a direction that's a value of 1 or normalized, we normalize it. So we're going to say dir is equal to normalize dir. So that just ensures that we always have a normalized direction vector. OK. So moving on, let's create a points array. That needs to be initialized to an int, like so. And this is going to store all the points that we create. And the reason why we do this is because we want to create a primitive out of all the points by the end of this particular vex expression. OK. And in order to create that primitive, we need to provide it an array of points. So let's then resize that array. So it's provided points. And then let's provide it the point count so we can tell it what to resize to. Awesome. So let's hit Apply. Make sure we don't have any error, so we're good. So far. All right, so now we are pretty much ready to go. The last thing that we really need to provide to this expression is the step value. Now the step value determines where on the line each point gets placed. So how far out or how far along the line should each point get placed? So if we only have two points, then we should just be the full length. So 0 is going to be at the center, or at world center. And then point 2 would be at the full length, so 1. So how do we create this step value? So what I want to do is create a float, because it's going to be a float value. I'm going to call it step value. OK. And all we need to do is take that length and divide it by the point count, like so. And now right off the bat, that doesn't necessarily work for us. So if we were to actually debug this, so let me hit Accept over here. And let's actually debug this down here in the geometry spreadsheet. And I want to actually run this over details, not points. So I'm going to set this to detail, because I just want to run this once. So in order to debug this value, I'm just going to turn it into an attribute by putting the at symbol there. And you'll notice that our step value now is 0.5. Now that isn't necessarily what we want, because we have two points, a length of 1.5 will only give us half this length. If we had more points, you can see that we're getting a value change, but it's not entirely accurate. So what we need to do is subtract 1 from this, like so. And then you'll notice that we have a value of 1. When we're at two points, and we're at 3, we have a value of 0.5. And that works because you'll have 0.0 at the bottom. You'll move up 0.5 for 0.1, and then move up another 0.5 for 0.2, giving us a full length of 1. And for some reason, that's working, but I always like to make sure I'm casting these two at the correct values, because point count is an integer. So this is just me being picky there. It is working, though. So we are now ready to move on to our for loop. So let's do a for int i equals 0. And i is less than the point count. All right. Let's say i plus plus. All right. So now let's go and actually create our points. OK, so the first thing we need to do, just like we saw in part one, is create the position value. So we need a vector, and we're just going to call this the point pause. OK, and this point pause is going to be the length. Actually, sorry, it's not the length. It's the direction. So we want to take the direction, that vector. That's a normalized vector. We want to multiply it by the step value. And in this case, because I made it an attribute, which don't necessarily need anymore. Let's just make it a regular variable. So let's go in here and say our step value times the current iteration, so the i iterator here. Because what that'll do is it'll increment as we loop through this for loop. All right, so we're going to be pointing in that direction, then multiplying this vector with this scalar right here. OK, perfect. So now that we have our position, let's do the add point. So again, remember, we want to store each point as we create them. So we need to create a new int called the cur ID. It could be called whatever you want, but I'm going to call it the cur ID. It stands for the current ID of this point that we're about to create. So add point, and we want to do the geo self. So we just add it to this particular node, and we want to give it that point pause. That's the position. And then finally, we want to add that point that we just created to that points array. So points I is equal to cur ID. And there we go. Now we have our three points, and we have points along that length. And if we make this longer, you can see the points are retaining their spacing. Awesome, just like the line node. OK, so to finish this particular custom line node, all we need to do is add it to a prim. So we're going to say add prim. And this prim is going to be added to the geo self. We're going to make it into a poly line. And we're going to give it the points that we created up here. And then we added all the points that we created to it. And boom, now we have an official line. It works exactly, or almost exactly, like the line node. OK, so here we have the original line node. Same deal, direction. We can always do an origin if we wanted to. Also, if you wanted to offset it in a particular position, so to do something like that, you would just go up here. Let's open up our script editor again. We can do the vector offset. And we can do another chv. We'll just call this offset. OK, and down here, we'll just add these two guys together. So direction plus offset, and hit apply. So now we need to expose that, and it's not working. That's weird. Oh, I have the wrong line selected. Oh, OK, so I just had the wrong node actually visible. So I don't want to actually add it to this, because it's being multiplied by that step value. So all we need to do is actually add it here. So offset, so after the multiplication. And we actually want to do that. There we go. So now if I were to move this up and down, now we have our offset. Awesome. Can offset it in any direction that we want. So now we have successfully created or recreated. Let me close this. So we've successfully recreated that line node. Now, you're probably thinking to yourself, that's not very useful to me. Really, this is just an exercise in getting comfortable with using VEX. And just understanding the principles behind how some of these things are constructed. By practicing this over and over again, it'll just help cement it into your brain. So moving on, let's get rid of this line node. All right, so moving on. Now that we have a line to work with, let's just make it sit up in the line direction like so. So let's cover the ramp next. So I'm going to create another wrangle node. And we're going to feed that into that first input there. And for this one, we are going to run over points, because I want to go through each point. And what we're going to do is we're going to create a ramp parameter. So what I want to do is create a float. And I'm going to call this ramp. And this is equal to CH ramp. That's really all you need to do to create a ramp that we can actually edit down here. And so I'm going to give it a name. This is the label, so this is just going to be called the ramp. And what I want to do is give it some sort of gradient value. So some value that goes from 0 to 1 over the length of the line. All right, so what we need to do is we actually need to create another float called the gradient. And this is going to be equal to that PT num divided by the number of points, minus 1. OK. And again, I always just like to make sure I'm casting these appropriately. OK. And we can pump that gradient value now into that ramp. Make sure we put our semicolons at the end here. All right, perfect. So let's actually make sure we're getting a value from 0 to 1 for this gradient. So what I'm going to do is turn it into an attribute, just so I can see the result over here in the attribute spreadsheet. Now, if you don't have this open or I don't know how to get it open, there's a couple ways you could do this. You can hit this little drop-down arrow here and say split pane top bottom. Right click on it and select the geometry spreadsheet. Or you can hit alt bracket, so the right bracket. And that'll split it automatically for you. And then you could just switch it. Or you can hit alt 8. So alt 8, like so. OK, let's go back to that scene view. All right, so now we have a ramp parameter. And I need to open that spreadsheet again, so I can see I feel naked without it. All right, so what we want to do now is just use the values. So let's create the parameter. Now we have a ramp down here. Awesome. So what I want to do is something really simple just to demonstrate this. I'm going to say p, the position of the current point that we're on, and the x position is equal to the ramp value, this current ramp value. Because now we're sampling the ramp using this gradient value. So we're sampling it from 0 to 1. And now we get something we can control. Easy peasy. It's a lot less work than having to create a point bop like this jumping inside. Not that this is a lot of work either. I'm just saying. I always like to show the alternative methods. And we do a ramp parameter. And because we don't have a gradient on it yet, so we would have to literally either create the gradient here, which you would do the same thing. So we would need to do a int to float. We need two of those. So we take the point number, the number of points. We want to subtract a constant from our number of points. And 1 is good. And then we would divide the current point number by the number of points minus 1. And that gives us our gradient value, 0 to 1. OK. So I don't need that anywhere. And we would put that into the input of the ramp. And then we could do a bind export up here and call this the gradient or the ramp value, like so. All right. So that now puts that value onto each point. It's kind of weird. It's not showing up, but it's working, I swear. Let's actually call it new ramp. Might be a naming convention, yeah. And you'd want to make this a spline ramp. And we're not getting any values because if you come up here, we don't have any value. There we go. So there you go. So to further conclude that, we would then have to take a vector to float, feed in the current position to a float to vector, like so. So let's do the y and the z. Take that as the new x. And now you have this guy. I probably should add these two together. Oh, I have the velocity value in there. OK, so now we're good. My apologies. So now we have that same effect that we got with this guy. All right, so in the attribute wrangle, it just took three lines of code. In the point bop node, we had to create quite a few nodes in order to make that work. So it saves time. Just learning a little bit of x always does save time. All right, so let's go and create the circle, which is actually not that difficult either. It's using just the sine and cosine. All right, so let's create another wrangle node. And what we want to do is we want to create that gradient value again. All right, so I'm going to create a float. And we're going to run over points for this because we want to position each point on the line. So I'm going to create that gradient. And it's going to be equal to that pt num. I should create a preset out of this. And num points minus 1. And we'll put the parentheses around that and cast it to a float because I'm picky. So we need the semicolon. And there we go. So now we have our gradient value. And then all we really need to do is just I'm going to make this a circle around the yz axis. So we want to position the y using the cosine and position the z using the sine. And the way that we do this is we're just going to say at p.y is equal to the cosine of the gradient. Let's see what this does first. z is equal to the cosine. Sorry, I don't need to actually spell it out, the gradient. All right. And what we get is a line up here. And that's awfully weird. All right. What we want to do is we want to actually multiply this by some value that gives us 360 degrees. And that value is 2 times pi. So let's go in here. And we'll multiply this by 2 times dollar sign pi. And then times 2 times dollar sign pi. Oh, and I actually made a mistake here. I need to make this a design function. And with that, we are good to go. So all we need to do now is add more points. OK, so we can just go back to our custom line. Let me just add more points so we have a perfect circle, like so. All right, so that's really all I wanted to show. I will make these little exercises available on Gumroad, either on Gumroad or on my website. I'm still working on everything. So anyways, I'll make these available so you guys can download them and use them in your own exercises. OK, thanks so much.