This is more of a learning experience rather than a tutorial - it's far better to understand than to just follow. With that in mind, I'm going to warn you that there's lot of maths involved...

Maths!

Pi, or π:

Pi is a magical number used in circles and you can use Math.PI to get it easily.
====

Radians:

Pi radians = 180°

You don't need to know much about this at all, all you need to know is converting degrees into radians is done by the following:

degrees / 57.29578F
or
degrees / (180 / Math.PI)

====

Sine and Cosine:

Sine and Cosine are functions used in entity animations for getting a part to move back and forth repeatedly because they repeat every 360° or 2 Pi radians.
You can use MathHelper.sin() or MathHelper.cos() to get them easily.

Parameters:
par1 - time
par2 - movement speed
par3 - ???
par4 - rotation yaw (clockwise rotation round the Y axis)
par5 - rotation pitch (clockwise rotation round the X axis)
par6 - ???
par7Entity - the entity for this model

??? = I've not got enough of an idea to teach this.

If you didn't quite understand that, don't worry. Hopefully, par1 and par2 will be much clearer by the end of this guide. This is the method that is mainly used to animate mobs and the one we're going to pay attention to.

The Very Basics: Rotation Angles

What is a Rotation Angle?

You should be familiar with your model's boxes, and if not then take a look the the boxes you already have in your model file. Here's an example:

This is taken from my mod's Dendroid Elder arm. In terms of animation, the only thing important here is the .setRotationPoint() method.
If you have been using Techne, you will have noticed "Offset" and "Position". Position determines the rotation point of the model's box. This is very important.

The model's rotations are based around this rotation point. As a result, if the box is an arm like the example above, the rotation point should be where the shoulder is. If it's a head, it should be where it meets the neck. If you have any models which have not set rotation points like that, they should be altered before proceeding or you will get visual errors.

The image above shows the same model with two different rotation points. The one on the left will make the model's tail spin around as normal, while the one on the right will make the tail spin from the bottom, resulting in a 'detached' tail. It is important that the rotation points are where the joints of the model are.

What does Changing it do?

Changing the angle of rotation for a model's box will change it's rotation around the rotation point discussed above. Doing it in code is similar to using the three slider bars in Techne. Here's an image:

Here you can see the x and y rotations around the x and y axes. Positive rotations are clockwise and negative rotations are counter-clockwise. By changing the rotation angle, you are changing how the model looks.

The Difference between Techne and Code

You might notice that there is a difference between what Techne says and what is in the code. This is because the code doesn't use degrees, it uses radians. You can refer back to the maths section above for how to convert degrees into radians, or you can hover your mouse over the Techne reading as such:

46.864/(180/Pi) = 0.8179311 which is roughly the same.

More Basics: Animation

Animating a mob is usually done by changing its rotation angles. Here is an example of doing that in the method mentioned beforehand:

This is an example of code for walking animations. rotateAngleX, rotateAngleY and rotateAngleZ are respective rotation angles for each axis in radians. To understand this, we can look at some graphs.

Working inside cos(x) with the time parameter

MathHelper.cos(par1);

Let's treat start with the most basic part of the code: MathHelper.cos(par1)
Take rotation in radians as the y axis and par1 (or time) as the x axis:

Blue = cos(x)

You should be able to see that as time increases, the value of rotation changes, creating a repeating "swinging" motion.

Here are the properties of the rotateAngleX = MathHelper.cos(par1) line of code on its own and what it means for walking animations:

It repeats as the cosine function repeats - the model's leg will swing back and forth.

It is limited between 1 and -1 - the model's leg swing will peak at negative and positive 1F, or 57.23°.

It starts at "1" when it begins - the model's leg will start outstretched at 0 seconds.

MathHelper.cos(par1 * a);

Now let's look at the next part. Here's a sine graph that should help explain it:

Blue = sin(x)
Red = sin(x * 2)

Here you can see that sin(x * 2) repeats twice as fast as sin(x). This means that sin(x * 0.5) would repeat half as fast as sin(x). By multiplying par1 (or time), you are changing the time taken for a full swing to occur.
So you can say that " * 0.6662F " just slows down the walking time so that the model's leg walks at the best-looking speed possible.

MathHelper.cos(par1 * 0.6662 + (float)Math.Pi);

The left leg's code varies slightly, but why? Let's take a look at that + sign and what it does in a graph:

Blue = cos(x) = sin(x + Pi / 2)
Red = sin(x)

You can see that they're both the same shape, just in different positions. The "+" part of that code can be said to shift where the graph starts.
Therefore, " + (float)Math.Pi " changes the position of the left leg so that it isn't the same as the right leg. In fact, in this case it makes the left leg opposite to the right leg which is sort of similar to real walking.

Working outside cos(x) with the speed parameter

MathHelper.cos(par1 * 0.6662) * 1.4F;

Previously, I mentioned that MathHelper.cos(par1) was limited between the angles "1" and "-1". You can change this by multiplying the number outside of the brackets. Here's another graph, though I don't really think it's necessary if you've just understood this:

Blue = cos(x)
Red = cos(x) * 2
Green = cos(x) * 0.5

You can see that multiplying outside of the brackets changes the limits of the graph.
So if you had a creature that was very acrobatic and swung its legs up to it's face and then to the back of its head, you'd have to multiply by a number larger than one, while a mob that takes baby steps would require multiplying by a number smaller than one.

MathHelper.cos(par1 * 0.6662) * 1.4F * par2;

Last but not least is par2 (or speed). If you've been coding along to this, you might have noticed that your mob's legs don't stop moving. That might be pretty cool if you're making something such as a helicopter blade, but for most mobs that's a problem.
If you take par2 as speed, what it does in animating should be immediately obvious. Here are two of its effects:

If the entity is stationary, par2 = 0. Anything multiplied by 0 is 0, so in terms of animation, it stops the legs moving when the entity isn't.

It's outside of the brackets, so it will increase the limit. If it increases, so will the limits and therefore, the faster the entity moves the larger its stride length. (this means that if you want it to move its legs faster instead of increasing its leg swing, you'll have to put it inside the brackets).

Not so Basic: model1.addChild(model2);

Ok, that all works for a single box, but what if I have more than one joined together? There is a massive problem when creating limbs made of multiple parts and I'll demonstrate with an analogy:

Imagine your arm as a model - you have your upper arm, lower arm, hand and fingers. Your rotation points would be your shoulder, elbow, wrist and the multiple joints between your finger parts.
If they were unconnected, moving your upper arm would work but your lower arm would be left floating, like this:

A Dendroid Elder going in for a punch but leaving his arm behind

Now you could solve it by setting all of the rotation points to the shoulder and moving each piece by the same amount, but it would prevent you from bending your elbow or any other part of your body.

The rotation points need to move with the model, and the following piece of code does this for you:

//This goes into the constructor
Arm_R.addChild(Arm_RE);

Your upper arm is the parent and the child would be your lower arm. Here I use ARM_RE (Arm right extension) as the child for ARM_R (Arm right)
You can keep doing this if your model's limb has multiple parts. For example, if it had a long vine arm, it would look like this:

//In the constructor remember
VineArm_1a.addChild(VineArm_2a);
VineArm_2a.addChild(VineArm_3a);
VineArm_3a.addChild(VineArm_4a);

Removing Renders

You will also need to remove the render for the child parts or it shows up twice:

However, there is another slight change that is necessary: addChild() makes the rotation point of the child relative to the parent's rotation point, which means you'll have to edit the rotation points again.

Here's an explanation if you don't understand what is meant by making rotation points relative:

Say that you have two points and their coordinates A(0, 1, 2) and B (0, 2, 4).

These points are set relative to the origin, O(0, 0, 0)

A(0, 1, 2) = O(0, 0, 0) + (0, 1, 2)

B(0, 2, 4) = O(0, 0, 0) + (0, 2, 4)

However, addChild() makes the parent's rotation point the origin for the child so:

A(0, 1, 2) is now (0, 0, 0) for B

B(0, 2, 4) is therefore now B(0, 2, 4) - A(0, 1, 2) = b(0, 1, 2)

Where capital letters are the original rotation points in Techne and lowercase letters are the ones used for child boxes in code.

It may seem a little hard to understand, so here's an example:

The Rotation Point of VineArm_1a in Techne = (-10F, -4F, -2F)
The Rotation Point of VineArm_2a in Techne = (-15F, -4F, -2F)

The Rotation Point of VineArm_2a relative to VineArm_1a = (-5F, -0F, -0F)

Rotation angles are also relative to the parent, which means you'll have to do everything you did above to the rotation angles. To be explained further...
=====

I hope you've understood this guide and that it's helped you
If there's anything that isn't clear, please comment below.

What are you having trouble with understanding? I'll try and clarify anything you need.
Though if you're referring to the last section, I will need to update it as it could be explained better and I've missed some key information out.

Oh man this was (will be) a great help, as I am working with a few other guys on a mod and we were having troubles with the rotations when adding multiple joints to the arm.

This tutorial is GREAT!!!
I love the fact that you focus on the learning experience and make people LEARN what they are doing!
Thank you for creating this

I'm adding a link to your tutorial to my tutorial database so people can search for and find it easily!

So if you're making an arm move in two places, like the example above, would you put the rotations points both at the shoulder, and addChild makes it move, or one at the elbow and one at the shoulder before addChild?

So if you're making an arm move in two places, like the example above, would you put the rotations points both at the shoulder, and addChild makes it move, or one at the elbow and one at the shoulder before addChild?

You want the lower arm to have its rotation point at the elbow, which has to be set relative to the rotation point at the shoulder.

Without addChild, you have to set them both at the shoulder and it becomes incredibly difficult to move the lower arm correctly.
With addChild, you set the rotation points where the joints should be and then calculate the child arm's rotation point relative to the parent's.

This is the best animation tutorial I have ever seen. but I still don't know how to apply the code properly like. One of my mobs I want it to be flying at least 2 blocks above the ground when its walking, and have it curl its legs up into a point as its flying, and of course have its wings moving but I don't know where to begin with it.

Two years, rotations had confused me more than anything else mentioned in this thread. Mostly because when I started modding there wasn't really any program to assist in the creation of models.

If only this thread had been here two years ago...

In your rotation point example you have
//Before
setRotation(VineArm_1a, -10F, -4F, -2F);
setRotation(VineArm_2a, -15F, -4F, 2F);

//After
setRotation(VineArm_1a, -10F, -4F, -2F);
setRotation(VineArm_2a, -5F, -0F, 0F);
Most of my setRotation values (export from Techne) are 0F, 0F, 0F

The setRotationPoint method for all the boxes have various values. Are these what get subtracted for child boxes?

Here is an abbreviated sample of my Techne generated code:

So I have a body with a 'thigh' attached and a lower leg attached to the thigh. I understand using the setChild to 'attach' the lower leg to the thigh but don't understand the changing of the setRotation example you gave.

In your rotation point example you have
//Before
setRotation(VineArm_1a, -10F, -4F, -2F);
setRotation(VineArm_2a, -15F, -4F, 2F);

//After
setRotation(VineArm_1a, -10F, -4F, -2F);
setRotation(VineArm_2a, -5F, -0F, 0F);
Most of my setRotation values (export from Techne) are 0F, 0F, 0F

The setRotationPoint method for all the boxes have various values. Are these what get subtracted for child boxes?

Here is an abbreviated sample of my Techne generated code:

So I have a body with a 'thigh' attached and a lower leg attached to the thigh. I understand using the setChild to 'attach' the lower leg to the thigh but don't understand the changing of the setRotation example you gave.

This will be SO helpful when I get into hardcore modding.

Making note of the URL now.

Rollback Post to RevisionRollBack

The Darkness will win one day, and light's time being the winner is nearing it's end. Because light is overrated.
IntelliJ > Eclipse because better autocomplete and inbuilt command line. Oh, and use the latest version for mods.
My heavily work in progress Minecraft Modding API and mod loader, N-API: https://github.com/Niadel/N-API
Code changes from 1.7 to 1.8 for us modders (that I found): https://gist.github.com/Niadel/2d2db8dd89de27f970a7

To post a comment, please login or register a new account.

Maths!Pi, or π:

Pi is a magical number used in circles and you can use Math.PI to get it easily.

====

Radians:

Pi radians = 180°

You don't need to know much about this at all, all you need to know is converting degrees into radians is done by the following:

====

Sine and Cosine:

Sine and Cosine are functions used in entity animations for getting a part to move back and forth repeatedly because they repeat every 360° or 2 Pi radians.

You can use MathHelper.sin() or MathHelper.cos() to get them easily.

Blue = cos(x)

Red = sin(x)

The MethodHere I'll be covering the following method only:

Parameters:

par1 - time

par2 - movement speed

par3 - ???

par4 - rotation yaw (clockwise rotation round the Y axis)

par5 - rotation pitch (clockwise rotation round the X axis)

par6 - ???

par7Entity - the entity for this model

??? = I've not got enough of an idea to teach this.

If you didn't quite understand that, don't worry. Hopefully, par1 and par2 will be much clearer by the end of this guide. This is the method that is mainly used to animate mobs and the one we're going to pay attention to.

The Very Basics: Rotation AnglesWhat is a Rotation Angle?You should be familiar with your model's boxes, and if not then take a look the the boxes you already have in your model file. Here's an example:

This is taken from my mod's Dendroid Elder arm. In terms of animation, the only thing important here is the .setRotationPoint() method.

If you have been using Techne, you will have noticed "Offset" and "Position". Position determines the rotation point of the model's box. This is very important.

The model's rotations are based around this rotation point. As a result, if the box is an arm like the example above, the rotation point should be where the shoulder is. If it's a head, it should be where it meets the neck. If you have any models which have not set rotation points like that, they should be altered before proceeding or you will get visual errors.

The image above shows the same model with two different rotation points. The one on the left will make the model's tail spin around as normal, while the one on the right will make the tail spin from the bottom, resulting in a 'detached' tail. It is important that the rotation points are where the joints of the model are.

What does Changing it do?Changing the angle of rotation for a model's box will change it's rotation around the rotation point discussed above. Doing it in code is similar to using the three slider bars in Techne. Here's an image:

Here you can see the x and y rotations around the x and y axes. Positive rotations are clockwise and negative rotations are counter-clockwise. By changing the rotation angle, you are changing how the model looks.

The Difference between Techne and CodeYou might notice that there is a difference between what Techne says and what is in the code. This is because the code doesn't use degrees, it uses radians. You can refer back to the maths section above for how to convert degrees into radians, or you can hover your mouse over the Techne reading as such:

46.864/(180/Pi) = 0.8179311 which is roughly the same.

More Basics: AnimationAnimating a mob is usually done by changing its rotation angles. Here is an example of doing that in the method mentioned beforehand:

This is an example of code for walking animations. rotateAngleX, rotateAngleY and rotateAngleZ are respective rotation angles for each axis in radians. To understand this, we can look at some graphs.

Working inside cos(x) with the time parameterMathHelper.cos(par1);Let's treat start with the most basic part of the code: MathHelper.cos(par1)

Take rotation in radians as the y axis and par1 (or time) as the x axis:

Blue = cos(x)

You should be able to see that as time increases, the value of rotation changes, creating a repeating "swinging" motion.

Here are the properties of the rotateAngleX = MathHelper.cos(par1) line of code on its own and what it means for walking animations:

MathHelper.cos(par1 * a);Now let's look at the next part. Here's a sine graph that should help explain it:

Blue = sin(x)

Red = sin(x * 2)

Here you can see that sin(x * 2) repeats twice as fast as sin(x). This means that sin(x * 0.5) would repeat half as fast as sin(x). By multiplying par1 (or time), you are changing the time taken for a full swing to occur.

So you can say that " * 0.6662F " just slows down the walking time so that the model's leg walks at the best-looking speed possible.

MathHelper.cos(par1 * 0.6662 + (float)Math.Pi);The left leg's code varies slightly, but why? Let's take a look at that + sign and what it does in a graph:

Blue = cos(x) = sin(x + Pi / 2)

Red = sin(x)

You can see that they're both the same shape, just in different positions. The "+" part of that code can be said to shift where the graph starts.

Therefore, " + (float)Math.Pi " changes the position of the left leg so that it isn't the same as the right leg. In fact, in this case it makes the left leg opposite to the right leg which is sort of similar to real walking.

Working outside cos(x) with the speed parameterMathHelper.cos(par1 * 0.6662) * 1.4F;Previously, I mentioned that MathHelper.cos(par1) was limited between the angles "1" and "-1". You can change this by multiplying the number outside of the brackets. Here's another graph, though I don't really think it's necessary if you've just understood this:

Blue = cos(x)

Red = cos(x) * 2

Green = cos(x) * 0.5

You can see that multiplying outside of the brackets changes the limits of the graph.

So if you had a creature that was very acrobatic and swung its legs up to it's face and then to the back of its head, you'd have to multiply by a number larger than one, while a mob that takes baby steps would require multiplying by a number smaller than one.

MathHelper.cos(par1 * 0.6662) * 1.4F * par2;Last but not least is par2 (or speed). If you've been coding along to this, you might have noticed that your mob's legs don't stop moving. That might be pretty cool if you're making something such as a helicopter blade, but for most mobs that's a problem.

If you take par2 as speed, what it does in animating should be immediately obvious. Here are two of its effects:

Not so Basic: model1.addChild(model2);Ok, that all works for a single box, but what if I have more than one joined together? There is a massive problem when creating limbs made of multiple parts and I'll demonstrate with an analogy:

Imagine your arm as a model - you have your upper arm, lower arm, hand and fingers. Your rotation points would be your shoulder, elbow, wrist and the multiple joints between your finger parts.

If they were unconnected, moving your upper arm would work but your lower arm would be left floating, like this:

A Dendroid Elder going in for a punch but leaving his arm behind

Now you could solve it by setting all of the rotation points to the shoulder and moving each piece by the same amount, but it would prevent you from bending your elbow or any other part of your body.

The rotation points need to move with the model, and the following piece of code does this for you:

Your upper arm is the parent and the child would be your lower arm. Here I use ARM_RE (Arm right extension) as the child for ARM_R (Arm right)

You can keep doing this if your model's limb has multiple parts. For example, if it had a long vine arm, it would look like this:

Removing RendersYou will also need to remove the render for the child parts or it shows up twice:

Relative Rotation PointsHowever, there is another slight change that is necessary: addChild() makes the rotation point of the child relative to the parent's rotation point, which means you'll have to edit the rotation points again.

Here's an explanation if you don't understand what is meant by making rotation points relative:

It may seem a little hard to understand, so here's an example:

The Rotation Point of VineArm_1a in Techne = (-10F, -4F, -2F)

The Rotation Point of VineArm_2a in Techne = (-15F, -4F, -2F)

The Rotation Point of VineArm_2a relative to VineArm_1a = (-5F, -0F, -0F)

CodeRelative Rotation AnglesRotation angles are also relative to the parent, which means you'll have to do everything you did above to the rotation angles. To be explained further...

=====

I hope you've understood this guide and that it's helped you

If there's anything that isn't clear, please comment below.

Great tutorialThough if you're referring to the last section, I will need to update it as it could be explained better and I've missed some key information out.

I love the fact that you focus on the learning experience and make people LEARN what they are doing!

Thank you for creating this

I'm adding a link to your tutorial to my tutorial database so people can search for and find it easily!

Bleach Mod

You want the lower arm to have its rotation point at the elbow, which has to be set relative to the rotation point at the shoulder.

Without addChild, you have to set them both at the shoulder and it becomes incredibly difficult to move the lower arm correctly.

With addChild, you set the rotation points where the joints should be and then calculate the child arm's rotation point relative to the parent's.

If only this thread had been here two years ago...

But seriously, good job!

//Before

setRotation(VineArm_1a, -10F, -4F, -2F);

setRotation(VineArm_2a, -15F, -4F, 2F);

//After

setRotation(VineArm_1a, -10F, -4F, -2F);

setRotation(VineArm_2a, -5F, -0F, 0F);

Most of my setRotation values (export from Techne) are 0F, 0F, 0F

The setRotationPoint method for all the boxes have various values. Are these what get subtracted for child boxes?

Here is an abbreviated sample of my Techne generated code:

Body = new ModelRenderer(this, 0, 0);

Body.addBox(-3F, 18F, 0F, 5, 4, 7);

Body.setRotationPoint(0F, 1F, 0F);

Body.setTextureSize(128, 64);

Body.mirror = true;

setRotation(Body, -0.2094395F, 0F, 0F);

LRrThigh = new ModelRenderer(this, 29, 14);

LRrThigh.addBox(0F, 0F, -1F, 2, 1, 3);

LRrThigh.setRotationPoint(2F, 22F, 1F);

LRrThigh.setTextureSize(128, 64);

LRrThigh.mirror = true;

setRotation(LRrThigh, -0.3490659F, 0F, 0F);

LRrLeg = new ModelRenderer(this, 43, 14);

LRrLeg.addBox(-1F, 0F, -3F, 2, 1, 3);

LRrLeg.setRotationPoint(3F, 23F, 3F);

LRrLeg.setTextureSize(128, 64);

LRrLeg.mirror = true;

setRotation(LRrLeg, 0F, 0F, 0F);

So I have a body with a 'thigh' attached and a lower leg attached to the thigh. I understand using the setChild to 'attach' the lower leg to the thigh but don't understand the changing of the setRotation example you gave.

Thank you for your tutorial.

I figured it out by trial and error.

Making note of the URL now.

IntelliJ > Eclipse because better autocomplete and inbuilt command line. Oh, and use the latest version for mods.

My heavily work in progress Minecraft Modding API and mod loader, N-API: https://github.com/Niadel/N-API

Code changes from 1.7 to 1.8 for us modders (that I found): https://gist.github.com/Niadel/2d2db8dd89de27f970a7