# JoyOfVex16

### Day 16

More tricks with attributes and the copy sop!

This time to make it a little easier to visualise, we'll make a colour coded cube that's scaled down on z, so its clear to see where its local x y z axis are.

Make a box, and put this in a primitive wrangle to colour the faces:

```
@Cd = @N;
if (min(@Cd)<0) {
@Cd = 0.1;
}
```

Because @N will be negative for the faces that point down (-y), back (-z) or left (-x), I check for faces that have negative colour, and set their colour to 0.1, ie a dark gray. This will just make it easier to see what the copy sop is doing later on.

Append a transform sop, set the group to 2, and set uniform scale to about 0.6. That will taper the face that points down the z-axis, giving you this shape:

*Jan 2023: Hello, it's future Matt here. Testing this in 19.5, it seems the default prim ordering has changed since when I wrote this; the z-face is now prim 0. So make sure to put 0 in the group field, not 2 if you're reading this in the future...*

Feed that to the first input of a copy sop, and our grid to the right. Insert a wrangle between the copy sop and the grid, and lets do some stuff.

As explained earlier, the copy sop will point the z-axis of the copied geo to point along @N of the template geo. With no other info, it will point the copied geo x-axis along the world x-axis, so the red face will be pointing towards world-x.

You can override this by adding a new vector attribute, @up:

```
v@up = {0,0,1};
```

With this defined, each cube's y-axis (ie the green side) will point along world-z:

If you think of this as skewering a shape on a knitting needle, if i you have a single needle the shape can still spin around the needle axis, but if you skewer it on 2 needles at 90 degrees, you've essentially locked its rotation. Defining a stable rotation, vs a undefined or ambiguous rotation, like just using @N, is a common task when animating copy sop geo.

So for example, we could spin the cubes by animating @up. If you wanted to plot a circle, you can set the @up vector x-component with sin(@Time), and the z-component with cos(@Time):

```
v@up = set(sin(@Time),0,cos(@Time));
```

Which means you can do interesting per-copy offsets by adjusting Time per point:

```
float t = @Time+@ptnum*0.1;
v@up = set(sin(t),0,cos(t));
```

Or as always, use channels:

```
float t = @Time+@ptnum*ch('offset');
v@up = set(sin(t),0,cos(t));
```

And start to introduce the same usual suspects from previous lessons:

```
float d = length(@P);
float t = @Time+d*ch('offset');
v@up = set(sin(t),0,cos(t));
```

etc:

```
float d = length(@P);
float t = @Time+d*ch('offset');
v@up = set(sin(t),0,cos(t));
@P.y += sin(t*2)*0.5;
```

### Exercises

- Balls in a line that bounce one after the other (hint: use a line as your template geometry, and use a chramp to draw in a small bounce curve in with a long flat area to either side of it)
- As above, but shapes that bounce in a circle
- What happens if you use a transform sop to rotate and shift the template geometry? Does the copied geo stay consistent?

prev: JoyOfVex15 this: JoyOfVex16 next: JoyOfVex17

main menu: JoyOfVex