# Code

## Getting a camera position in Vex, using optransform and cracktransform

In an earlier post I used a very unwieldy approach to get the position of a null in vex. Since then I have used a method where an object_merge SOP is set to transform “into this object” and then a point function can easily read the first point in the null to arrive at a center position. The problem with this is that you are reading the icon geometry for the object and in the case of a null this is ok, but the camera icon has each point offset from it’s origin.

Enter optransform and cracktransform. The optransform function will let you set a path to the camera (or whatever else you may want to use) and then populates a matrix with the target’s transforms. You can then extract out the position as a vector using the cracktransform function… this function if pretty powerful and at first confusing but essentially it has a switch which let’s you specify the portion of the matrix you need.

In the example above I used these functions to get the camera position and then used that position to compute a direction in “camera space’ to allow a ray SOP to project scattered points onto an object as a camera projection. Sounds complex, but it’s not. Here’s the wrangle which uses optransform and cracktransform to get the camera position:

```vector @cdir;
vector @raydir;
matrix camMatrix = optransform(chs("camera"));
//get a matrix with the camera's transforms.
@cdir = cracktransform(0, 0, 0, {0,0,0}, camMatrix);
//extract out the camera position as a vector
@raydir = normalize(@P-@cdir);
//get a vector to project pointo from camera```

## Dot Product and Edges in Vex

Getting the dot product of two vectors is infinitely useful, and easy in Vex. In this example I get a vector pointing from scattered particles to the camera and then get their dot product with the surface normal at that point. This gives you a very good idea of whether the surface is facing or perpendicular to the camera at any given point.

In this case, I simply cull any point which isn’t close to a value of zero, indicating the surface is perpendicular to the camera. If instead I culled particles that were less than zero I would be removing all back-facing (occluded) particles, which is perhaps more useful but less visually interesting. Since I am left with only particles near the edges of the geometry it’s easy to connect them with lines and get an “edge detection” kind of look.

Here’s the Vex wrangle I used. Note an earlier polyframe node gave me point normals on the scattered points to work with.

```float threshold = chf("Threshold");
//User input threshold
vector camPos = point(1, "P", 0);
//The position of the imported camera
vector toCam = normalize(camPos - @P);
//A vector from each point to the camera)
//@N = toCam;
//Use to visualize toCam as normals
f@angle = dot(toCam, @N);
//The dot product of the normal and toCam vectors.
if (@angle > threshold || @angle < -1*threshold){
removepoint(0,@ptnum);
}```

I’ve used this edge culling in production a few times, to create anime style speedlines and particle effects like rain strikes and halos. Culling particles behind geometry is of course also handy, though raycast solutions are much cleaner for that kind of thing. Next, we’ll use a simple dot product calculation to cull points and create a gradient effect.

## Vex and VOPs – A Twist Deformer (Part 2)

So twisting some points around the origin was easy, but not useful as a generalized tool since you really need to place the twist anywhere it’s needed in world space.

The trick to this is to create and store a transformation matrix based on the origin of your control object, then move your deforming geometry to the origin via the inverse of that matrix. Then, after performing the deformation, apply the stored transformation matrix to move your deformed geometry back to where it was in world space.

Getting the vex wrangle right took me a fair amount of teeth pulling because I’m so new, and frankly it feels like it could be reduced to something a lot simpler. Email me if you see a better or cleaner way! Here’s what I ended up with:

```// Create vectors to fill matrix using the second node input's transform
vector translate = set(`chs(opinputpath(".", 1)+"/tx")`,`chs(opinputpath(".", 1)+"/ty")`,`chs(opinputpath(".", 1)+"/tz")`);
vector rotate = set(`chs(opinputpath(".", 1)+"/rx")`,`chs(opinputpath(".", 1)+"/ry")`,`chs(opinputpath(".", 1)+"/rz")`);
vector scale = {1,1,1}; // I'm not worrying about scale...
// Build the transform matrix of the control object
matrix xform = invert(maketransform(0, 0, translate, rotate, scale));
// Apply the matrix to the current points to move them to the origin centered on control object
@P *= xform;
4@xform_matrix = xform;```

Yeah so there you go, that takes up a pointwrangle before the deform VOP and then a little wrangle after it returns the points to world space:

`@P *= invert(4@xform_matrix);`

Here’s a houdini take on that original twist scene using this setup:

## Vex and VOPs – A Twist Deformer

Now let’s do something a bit more demanding. We will replicate the twist deformer I made in ICE in VOPs, and then use some vex wrangles to allow a control object to place the twist deformation anywhere on the object in world space. Here’s the actual twist deform VOP, with a little extra to make the twist into a whirlpool funnel shape:

Pretty straightforward, the VOP takes a radius of points around the origin and pull them down in Y as well as rotates them around the origin, with a falloff based on distance and ramps to allow for user control.