In the previous section you were able to learn a lot about Vectors and Matrices. The matrices in particular proved to be a pretty dry and not always easily understandable subject matter.
This is why we will make this section a little more "exciting" in that we will align an eye’s Z axis with a target by re-creating the functionality of the Cinema 4D Align tag. Aligning a Matrix with a target is a situation that is encountered in many animation projects. It is therefore a good idea to practice creating such a function in XPresso yourself. You will notice that it is easier to work with matrices than you may think …
Again: You do not have to understand the mathematical background of this operation but rather develop a feel for how the alignment of matrices works as a whole.
Creating an XPresso tag
Open the following scene:
The scene contains the model of an eye and a target object, including materials and a background:
Right-click on the "Eye" Null Object in the Object Manager and create an XPresso tag.
We will create a User Data entry with which we can conveniently inform the Expression to which object the eye should be aligned. To do so, select the XPresso tag and select Add User Data … from the Attribute Manager’s
Change the name of the default entry to "Target" and set the Data Type to Link. This will create a Link data field in the XPresso tag’s Attributes with which we can define an object to which the eye should be aligned.
Click on OK to close the window and drag the "Target" object from the Object Manager into The Link field.
Setting up the Expression
Create an Object Node (XPresso/General). This Node will automatically reference the "Eye" object. Also create an output Port for global position (Coordinates/Global Position).
We also need a Global Position for the target object. Since we linked this using the XPresso tag’s User Data we must first access this User Data information. To do so, drag the XPresso tag from the Object Manager into the XPresso Editor. A new Object Node will be created that is linked with the XPresso tag. Create an output Port for this Node (User Data/Target).
In order to access the global position of the lined object we need to add another Node (XPresso/General/Object). Create an input Port (Object) for this Node and connect it with the Target output Port of the previously created Node. Also create a Global Position output Port (Coordinates/Global Position). Don’t be confused by the fact that the Node we created last has the name "Eye". This Node is now connected via its Object input Port with the Target object. Merely the name of the Node is not changed automatically.
We now have access to the global positions of both the eye and the target object. Next we will determine the correct alignment of the eye. This alignment vector will then be used as the Z axis of a Matrix and will augment the remaining (X, Y) axes. We will then determine the Matrix’ HPB Rotation Vector and enter this information into the "Eye" object’s parameters.
First we need to ascertain the alignment direction from the eye to the target object. This can be done by simply subtracting the position of the eye from that of the target object. To do so, create a new Math Node (XPresso/Calculation). Set the Node’s Data Type to Vector and the Function to Subtract. Finally, connect the Math Node’s input Ports with the Object Node’s output Ports.
We now have an alignment Vector that points from the eye to the target object. This Vector will serve as the Z axis of a Matrix. This, as well as the reconstruction of the still missing X and Y axes, will be taken care of by a special Node that we will create next: XPresso/Calculate/Vector2Matrix. Connect this new Node’s input Port with the Math Node’s output Port.
We now have a completed Matrix. The only thing that is missing now is the conversion of the Matrix to an HPB Rotation Vector that we can transfer to the eye as a Global Rotation. Here again we can use a special Node: XPresso/Calculate/Matrix2HPB. Connect this new Node’s input Port with the Vector2Matrix Node’s output Port.
The result of the calculation are the three components of the HPB rotation, as we see them in the right column of the Coordinates Manager when we select an object in the scene. For a more comprehensive overview we will combine these values to a single Vector. To do so, create a Real2Vector Node (XPresso/Adapter). Connect this Node’s input Ports with the Matrix2HPB Node’s output Ports.
In order for the eye to move as desired, the HPB Rotation Vector’s data must first be carried over to the "Eye" object. For this we will create one last Object Node (XPresso/General/Object), which will be linked to the eye. Create a Global Rotation input Port for this new Node and connect this Port with the Real2Vector Node’s output Port.
Close the XPresso Editor window, select the "Target" object and move it around slightly. The eye should automatically follow the object accordingly. Alternatively you can move the eye object and it will always look in the direction of the target object.
This simple example shows that matrices are nothing to be afraid of. Predefined Nodes are available for almost any type of complex mathematical operation, which makes working with XPresso much easier. Make sure you save the scene as it is so we can continue working with it in the next section.