7 days of unlimited WordPress themes, plugins & graphics - for free!* Unlimited asset downloads! Start 7-Day Free Trial
FREELessons: 8Length: 45 minutes

Next lesson playing in 5 seconds

Cancel
  • Overview
  • Transcript

2.6 Animating Complex Shapes

Sometimes you may need to create complex shapes with individual moving parts, like a bicycle or an airplane. In this lesson, you will learn how to create and animate complex shapes using a more abstract example.

Useful Links

2.6 Animating Complex Shapes

Hello and welcome back, in this lesson we're going to talk about creating animations with more complex shapes. You may have some 3D objects you wanna create that have multiple moving parts, something like a bicycle with spinning wheels or an airplane with a propeller. And it may be easy enough to rotate that propeller, but then if you also want to move the airplane while the propeller's rotating, it gets a little trickier. And we can handle that very easily in Three.js using complex objects, or using an object that contains multiple other objects. And we can do this in Three.js using the object 3D class. And an object 3D object is basically just a generic 3D object that other 3D objects, such as our shapes and things like that, inherit from. So let's take a look at this new scene, and you can find the URL for this scene in your course notes for this lesson. And once you open that up, I'm gonna click on Fork to create a new copy, and all of the changes we make in this lesson will be saved in this new copy. So we have our scene, we have our camera and our renderer. You'll notice I've got a different set of colors here, so we're gonna be working with different colors. In our CSS we've got a background color for our scene. And you'll notice I've already set up a variable called numBoxes, so I'm gonna be creating 200 boxes. And what I'm gonna do is I'm gonna give them all random rotations. I'm gonna keep them all in the same place, but I'm gonna give them all random rotations, and then I'm gonna animate all of them. But then as they're all rotating around on their own, the entire object as a whole is also gonna be rotating around. So we're gonna have two levels of rotation. We're gonna have a parent or containing object that's gonna be rotating in a circle. And then that parent object is gonna be made of a bunch of boxes that are each gonna be rotating on their own. And you can use this same type of setup to create something like a bicycle or a plane or something like that. So I’ve created this variable called numBoxes. You’ll notice I’ve also created a variable called boxes, which is just an empty array right now. And this is just gonna make it easier to access all of these boxes later on when we need to. So when we create all of our boxes, we’re gonna store them in this array. Now, all of our boxes are gonna be created using this BoxBufferGeometry. And it's got a width, height and depth of 5, and it's stored in a variable called boxGeom. And then we have our for loop pointing to this numBoxes variable, so this is gonna run 200 times. And inside this for loop, we're creating a random number for our color index. So this is the same setup we had before when we were giving each shape a random color. And then we have our material that's using the random color index that we selected up here. Then we're creating our mesh, storing it in a variable called box. We're setting a random rotation for all three axes. And then you'll notice I've also created this property called speedX. speedX is not a property that's associated with Three.js, it's just a random property that I added to our boxes here. So you can add any properties you want to these, I'm just calling them speedX, speedY, and speedZ. These values are going to determine how quickly and in what direction these boxes are going to be rotating on their X, Y and Z axes. So they're each gonna be a random number between -0.01 and + 0.01. So if it's negative it'll be rotating one direction, if it's positive it'll be rotating another direction. So we've done that, we've also added a couple of properties to these boxes. We've given them the ability to cast shadows and receive shadows. And all that's gonna do is, it's gonna give our animation more of a sense of depth. And then we're gonna push our boxes as we loop through this for loop over and over again. We're gonna push each box that we create into this boxes array that we created up here. So by the time we're done looping through this for loop, we're gonna have 200 boxes in this boxes array. Now one thing we could do at this point is just add each of these boxes individually to our scene. So inside our for loop, we would just do scene.add, and then we would add that box to the scene. And we can Save that and Run it. And when it refreshes we can see what that looks like when they're all just sitting still there on the stage. And so you can get the basic idea of the effect that we're going for. Each one of these has a randomized color, but they're all the same size and they're all randomly rotated. So if you have enough of them that are randomly rotated, you're gonna get something that looks like a sphere. And what we wanna do is we want these to animate around their axes, they're gonna be all rotating in different directions at different speeds at the same time. But then we want the overall sphere to also rotate. So let's make the individual boxes rotate first. So they're all inside this boxes array. So we can come inside our animate function here, and after our requestAnimationFrame, we can create a for loop. So we're gonna create a loop, I'm gonna set i = 0, and we're gonna run this as long as i is less than the numBoxes. And then we'll increase i by 1 each time we go through the loop. So we're gonna use this variable i here to point to a certain index in our boxes array, so that we can point to each box individually. So the way we do that, is we point to our boxes array, and we're gonna point to the i element of that array. So the first time we loop through this, i is gonna be equal to 0, so we'll be looking at the first box in the array. So we're gonna point to the box, we're gonna point to its rotation property, and let's do rotation.x first. And we're gonna do +=, so we're going to increase the x rotation by the random speedX property that we applied to that box. So again, we're gonna point to boxes[i].speedX. So again this speedX property here is just a random property name that we made up ourselves, and applied to each of our boxes when we created them in this loop up here. So we're gonna do that for the x, y and z rotations. So let's just copy this one and we'll paste it twice. And we'll change the second one to speedY and rotation.y and then rotation.z. And we'll use the speedZ property that we came up with there. So this should cause each of our boxes, since we're inside this animate function here, we're gonna loop through all of our boxes every time we run this function. And we're going to increase the rotation along each of the axes accordingly. So let's save that and let's click on Run. And when we do that, you can see this really cool effect where all of our boxes are rotating in a random direction at a random speed. But here's where we wanna make it a little more interesting. Instead of having all of these separate boxes acting on their own, I wanna treat them like they're all part of one object. And I wanna take this object as a whole and I wanna rotate it around its y-axis as all of these individual boxes are rotating around their own axes. So we have two levels of animation here. And this would be same type of effect you would go for, again, if you were creating an airplane with a rotating propeller, but you also wanted to move and rotate the airplane around as well. You would have two levels of animation there. So the way we're gonna do this, is we need to go back up to our box creation, inside this original for loop that we created to add each of our boxes, we need to remove those boxes from the scene first of all. We're gonna get rid of that. And then up here towards the top, here we created our BoxBufferGeometry, but before we do that, I'm gonna create a generic 3D object. And then I'm gonna add each of these boxes that we create to that 3D object. So I'm gonna create another variable here, and I'm gonna call it container, you can give it whatever name you want. But we're gonna set this equal to new THREE.Object3D(); to end our statement. And as always, you can go to the Three.js documentation to learn more about the object 3D class, but it basically just makes a generic 3D object. And what we can do is we can add all of these boxes that we're creating to that object. And then in addition to rotating the boxes individually, we can also rotate that container object to give it a more interesting animation. So inside our for loop, we're still gonna push all of these into that boxes array, because that still makes it easier for us to rotate each of those boxes individually. But then, after we do that, instead of adding these individual boxes to the scene, we're gonna add them to our container object. So remember, we created this variable called container, which is our object 3D object, and we're gonna call the add method. So .add, and we wanna add the box to this container. So again, we're looping through this code 200 times, creating 200 boxes, and each one of these boxes we're adding to that container. So this container is basically one 3D object that contains 200 other 3D objects. And so the 3D object that we create doesn't have to have a material or a mesh, because each of the objects inside it have their own materials and meshes. So we don't have to worry about that, but we do need to add that object to the stage. So after our for loop here, I'm gonna skip a couple of lines and I'm gonna point to our scene and do a scene.add. And we're gonna add the container object to our scene. Now, at this point if we save and refresh by clicking on the Run button, we shouldn't see a difference. And sure enough, everything still looks normal. We have the same animation that we had going on before. And that's a good sign, because we now know that even though we've added all of these boxes to a container object, and we've only added that container object to the stage and not the individual boxes, we see that it's still working, so that's a good first step. But now we can see the power in this when we go into our animate function and animate what in essence is a ball now. So after our for loop here, I'm gonna point to our container. And let's just do it's y rotation. So container.rotation.y, let's say we wanna do + = .02. So now this ball should be rotating around its y-axis, as all of the individual objects are rotating themselves. So let's save that again, once again click on Run, and let's see what that looks like. And there we go, so now we have this complex animation that is basically one animation nested inside another. We have all of these individual boxes that are animating themselves, but they're all part of a larger object that has its own animation going on at the same time. So thank you for watching, and I'll see you in the next video.

Back to the top