Interview with Tatyana Suhodolska


Recently, I spoke with the talented Latvia-based designer, Tatyana Suhodolska. On Her blog ArtDesigner.lv she provides tons of fantastic free icon sets as well as tutorials on how to create them. In today’s interview, we talk a little about her design background and where she usually finds inspiration. Enjoy!

Q Hi Tanya, welcome to PSDtuts +. Tell us briefly about yourself. Where are you from and where do you live now? How did you start in digital art?

Hello! I am a Russian girl, born in Latvia. I have been an artist since childhood – drawing comics and characters. When I was 5 years old I decided I wanted to be an animator. When I purchased my first PC at the age of 14, the first app that I installed was Macromedia Flash. After that, I began teaching myself Flash. Not long after that I began drawing cartoons. Before long, I was discovered by a television studio that paid me a little to create some animations for them. I really valued this experience but eventually I began designing static graphics. Although I haven’t given up my dreams of becoming an animator.

Q I know that you are working in various areas of design. Tell us, are you self-taught or did you study digital art somewhere? Do you have basic art education?

To be honest, I am a self-taught designer through and through. I did receive traditional schooling but I do not have a formal education in the arts, as you really can’t take those types of classes in my native language.

Q Tell us what programs you prefer to work in, what kind of work do you do, and which type of work do you enjoy most.

I use Photoshop CS2 the most. For the most part, I create websites and icons, although I prefer creating icons more.

Q Tell us a little about your workflow.

I try to trust my intuition. I don’t spend a whole lot of time preparing sketches or looking for inspiration. I design the first thing that comes to mind after landing a job and do my best to satisfy my clients.

Q Do you prefer working as a freelance designer or for an organization? Do you have a heavy workload? How do you set up your schedule?

This is a tough question for me to answer. I have had mixed experiences working for organizations. I don’t mind sitting in an office and being told what to do but to be honest, I prefer working as a freelancer. For the last 2 years I have worked for a French studio from my home in Latvia. I get to work on lots of successful projects but get to do it from the comfort of my own home.

Q Where do you find inspiration before a project? Do you visit any specific websites or is it a spontaneous process? Do you imitate anyone in your creativity or you are trying to develop your own style?

More often, the process is spontaneous. I draw the first thing that pops into my head but sometimes I do find myself browsing the web. I don’t imitate anyone’s style anymore but early on, I did, when I didn’t have a whole lot of experience.

Q I know that you make some really nice Photoshop tutorials. How did the idea to share your experience come to your mind? Do you have plans to write tutorials for our Psdtuts?

Thank you very much! I really appreciate that! I mainly write tutorials for my own icons, which are already available for download. I don’t really know where I came up with the idea to share my experience with the community. I just felt that I should do my best to give back as best I could.

Q What is the most important lesson you learned while working as a designer, and how does it help you now?

Specifically, working as a designer, it’s very important to always project confidence in what you do.

Q Do you have any long-term plans? How do you see your business in 5 – 10 years?

I would really love to travel to America and work at Pixar. It’s my life’s dream. If life takes me in another direction however, I would like to open my own studio.

Q Thanks for the interview. It was nice talking to you. Do you have any advice for beginner designers and illustrators?

Practice, practice, practice! Draw every day and read as many tutorials as you can find.


Tatyana Suhodolska on Web

Introduction to QuickBox2D: Part 2

This is the second part in a three part tutorial series about QuickBox2D. It’s recommended that you read each part of this series in order. So if you haven’t read part one, you should do so now. You can check it out here.

In this tutorial we will take a look at some of the more intermediate level features of QuickBox2D. We’ll see how to create polygon rigid bodies. We’ll learn how to fine tune our simulation using additional param values such as restitution, linearDamping and angularDamping. We’ll discuss some powerful Box2D methods that are exposed by QuickBox2D and we’ll talk about FRIM (framerate independent motion).

Reminder: This should go without saying, but don’t forget to put the Box2D and QuickBox2D libraries either
next to your .fla file or in your classpath.

This tutorial will walk you through the creation of a medium sized simulation designed to touch on specific aspects of QuickBox2D and Box2D. Check out the demo and relieve a little stress..


Step 1: Setting Up Your Script

Open up Flash and paste the following code into the actions for frame one:

[SWF(width = 800, height=600, frameRate=60, backgroundColor=0x000000)];

import com.actionsnippet.qbox.*;

var sim:QuickBox2D = new QuickBox2D(this);

/**-----------------------------
  -- insert variable definitions below this comment
  ------------------------------*/

// all the code to build rigid bodies
// is contained within this function
buildSimulation();

sim.start();
sim.mouseDrag();

function buildSimulation():void {

	// set some default colors and create stage walls
	sim.setDefault({fillColor:0x113366, fillAlpha:0.5, lineColor:0x3355AA});
	sim.createStageWalls();

/**-----------------------------
   -- insert ridgid body instantiation code below this comment
   ------------------------------*/

}
 

Once you have the above code in your timeline go ahead and test your movie to make sure everything is set up properly. Not much will happen when you run this code, just make sure that you don’t have any errors before moving on.

Most of what you see in the above code should be familiar to you. There are however a few important things to note. As we add additional code to this file we’ll need to define a few variables. For organizational purposes you’ll want to add those variables underneath the comment that reads:

 /**-----------------------------
  -- insert variable definitions below this comment
  ------------------------------*/
 

For simplicity, we’ve also created a function called buildSimulation() to wrap all of our rigid body instantiation. This function is called before the start() and mouseDrag() methods of QuickBox2D. It contains some default color settings for our rigid bodies as well as a call to createStageWalls(). Most of the code we look at in this tutorial will need to be pasted directly under the comment that reads:

 /**-----------------------------
   -- insert ridgid body instantiation code below this comment
   ------------------------------*/
  

Step 2: Polygons and the Points Param

I’m assuming that you know the difference between convex, concave and complex polygons. If you don’t know or don’t remember the difference, you may want to have a glance at the wikipedia article on the subject.

QuickBox2D allows you to define polygons in two ways. The first way uses automatic polygon triangulation, which allows you to simply define the x and y coordinates for the contour of a polygon. There is no limitation on the number of points in your contour. Paste the following code into your buildSimulation() function and test your movie:

// triangle
sim.addPoly({x:3, y:17, points:[0,0,  1,1,  0,1]});

// concave poly
sim.addPoly({x:7, y:17, points:[1,0,  2,2,  1,1.2,  0, 2]});

The above code defines two polys. The first line defines a simple right triangle that gets positioned at (3,17) and the next line defines a concave polygon that gets positioned at (7,17). We make use of a param called points which is an array of x and y coordinates. One dimensional arrays of xy coordinates can be tricky, the below graphic should clear up any confusion you
might have about the code we just added:

When creating points arrays, you need to be careful not to have a contour that overlaps itself, doing so will confuse the triangulation script and cause an error.

You’ll notice that the second polygon is made up of two triangles. This is QuickBox2D’s triangulation code at work, it basically breaks your contour up into a bunch of triangles. If you don’t want to see each triangle, you use can the wireframe param. Try altering your concave poly code as follows:

// concave poly
sim.addPoly({x:7, y:17, wireframe:false, points:[1,0,  2,2,  1,1.2,  0, 2]});

If you need to create more complex polygons you should probably build yourself some kind of simple polygon editor. There is an example of such an editor on actionsnippet.com. You may want to take a look at it for a few minutes before reading on. It should help solidify your understanding of the way QuickBox2D triangulates polygons.


Step 3: Polygons and the Verts Param

There is another way to create polygons using QuickBox2D which is a bit trickier. If you’re very concerned with the performance of your simulation you might consider using this method over the previously discussed method. You may also want to use this method if you need to create a simple convex poly such as a trapazoid. Add the following code into your buildSimulation() function:

sim.addPoly({x:13, y:17, verts:[[-1,-1,  1,-1,  2, 1,  -2, 1]]});

This code draws a trapazoid. Test your movie and have a look.

There are a few differenes between the verts param and the points param. An obvious difference is that the verts array is a two dimensional array. Each nested array contains a list of xy coordinates, this array can be used to define up to eight vertices. You cannot define a concave or complex polygon by using a single nested array. Instead, you must define a series of convex polygons (again, each with a max of eight vertices). You should define each convex polygon in clockwise order, starting with the top most point and working back around. This can be tricky, but it’s easier than it sounds. Add the following code into your buildSimulation() function and test your movie:

sim.addPoly({x:18, y:15, verts:[[0,-1, 1,1, -1,1],
								[1,1,  2,1.5,  1,2],
								[1,2,  0,3,   -1,3, -1,2],
							    [-1.5,2,  -1,2.5,   -1,3, -2,3, -2,2.5]]});

This code draws a few polygons together. The result is a small group of convex polys. If you plan on using this feature, you might want to take a break at this point and try to create something with the verts param. It’s interesting to see just how sensitive this feature is, you’ll get weird results if you don’t abide by the restrictions mentioned in the previous paragraph.


Step 4: Restitution

Restitution is like the elasticity or bounciness of a rigid body. By default restitution is set somewhere between 0-1, but higher values are allowed. Let’s take a look at what can be done with restitution, copy the following code into your buildSimulation() function and test your movie:

// perpetually bouncing ball
	sim.addCircle({x:3, y:13, radius:1, restitution:1});

	// set restutution to 1.2 to create a spring board
	sim.addBox({x:24, y:15, width:3, height:0.25,
				fillColor:0xDD0000, lineAlpha:0,
				angle:0.1, restitution:1.2, density:0});

	// normal circle
	sim.addCircle({x:24, y:10, radius:0.5});

The first thing we create with this code is a circle that bounces forever. By setting the restitution param to 1 it won’t stop bouncing as long as it is left alone. The next thing we create is a red box that is slightly rotated, has a density of 0 (is static) and has a restitution of 1.2. The restitution of 1.2 makes it so that things bouncing off of it will gain some energy. To test this, we add a circle directly above it. If you watch this circle carefully you’ll notice that each time it hits the red box it bounces a little bit higher, until finally it hits the ceiling and bounces off of the red box altogether.

Restitution is really the first step to making your rigid bodies act like they are made out of different materials. A restitution of 0 would be good for a rigid body that is supposed to be made of stone; a restitution of 0.8 would be good for something made of very bouncy rubber.


Step 5: Angular and Linear Damping

If you want to prevent a rigid body from translating or rotating too fast, you can dampen its linear or angular velocity. Add this code to your buildSimuation() function and test your movie.

	// green box
    sim.addBox({x:3, y:5, width:1, height:1, angularDamping:5, fillColor:0x22CC00});

    // red box
    sim.addBox({x:8, y:5, width:1, height:1, fillColor:0xFF0000});

    // small platform
	sim.addBox({x:6, y:8, width:10, height:0.25, density:0});

Here we add a green box with an angularDamping value of 5. This will cause the gren box to stop rotating very quickly when its thrown. For comparison we add a red box and left its angularDamping value at the default of 0. Since the simulation is beginning to get a little cluttered, we’ve added a small platform underneath these two boxes so it’s easy to move them around and observe the difference between them.

Linear damping is just like angularDamping but for translation. Let’s add angularDamping to the green box:

	// green box
    sim.addBox({x:3, y:5, width:1, height:1, angularDamping:5, linearDamping:5, fillColor:0x22CC00});

If you test your movie, you’ll notice that the green box falls slower than the red box and if you throw it around a bit you’ll see that it almost appears to float. Try playing around with the values a little bit before moving on.

I find I like to have angularDamping on anything that I want to rotate realistically when thrown. By default, when you throw a box around, you’ll notice it will rotate around many many times. I find myself using linearDamping a bit less, but it’s good if you don’t want something to move around to fast. It’s also good if you want to make something appear as though its being affected by air resistance, such as a deflated balloon or a piece of styrofoam.


It’s important to note that setting the angularDamping or linearDamping params above 1 will them to become sensitive to the timeStep. This may not mean anything to you at the moment, but we will discuss it further later in this tutorial.


Step 6: Friction

In Box2D, friction generally ranges from 0-1. By default all QuickObjects have a friction of 0.5. If we decrease this value things start looking very slippery. Add the below code to your buildSimulation() function and test your movie:

    // gray box
    sim.addBox({x:3, y:9, width:1, height:1, friction:1, fillColor:0xCCCCCC});

    // light blue box
    sim.addBox({x:8, y:9, width:1, height:1, friction:0, fillColor:0xCCCCFF, fillAlpha:1});

	 // small platform

	sim.addBox({x:6, y:12, width:10, height:0.25, density:0});

In the above code we add a gray box with a friction of 1, a light blue box with a friction of 0 and another small platform to make the two boxes easy to observe. Try sliding each box along the platform. You’ll notice that the gray box doesn’t slide very much, while the light blue box seems very slippery, like an ice cube.

Messing around with friction always makes me think of ice levels from those old Nintendo sidescrollers…


Step 7: The isBullet Param (Continuous Collision Detection CCD)

Box2D has something called CCD. This is a more accurate, more cpu intensive form of collision detection. If you want to use this type of collision on a rigid body, you need to make use of the isBullet param. As the name suggests, you often use CCD for bullets and other fast moving rigid bodies. Copy the below code into your buildSimulation():

var boxes:Array = [];
	boxes[0] = sim.addBox({x:1, y:0, width:2, height:0.25});
	boxes[1] = sim.addBox({x:1, y:2, width:2, height:0.25});
	boxes[2] = sim.addBox({x:0, y:1, width:0.25, height:2.25});
	boxes[3] = sim.addBox({x:2, y:1, width:0.25, height:2.25});
	sim.addGroup({x:12, y:6, objects:boxes});

	// if isBullet is false, circles will fall out of box
	for (var i:int = 0; i<4; i++){
		sim.addCircle({x:13, y:7, radius:0.2, isBullet:true});
	}

Here we create a hollow box using a group object. We then put four small circles into the hollow box and set their isBullet property to true. This prevents the small circles from shooting out of the hollow box group object. Test this by throwing the hollow box around the simulation as fast as you can. You’ll notice that all the circles remain within the walls of the hollow box. Now try setting the isBullet param to false and do the same thing, almost immediately you’ll see the circles fly out all over the place.

It’s worth noting that CCD is automatically used on static bodies.


Step 8: The FixedRotation Param

The fixedRotation param is very easy to understand. It’s a boolean that if set to true will prevent a rigid body from rotating. This is useful for preventing the character in a game from falling over. Add this code to your buildSimulation() function and test your movie:

sim.addBox({x:19, y:3, width:1, height:2, fillColor:0xFFFFFF, fixedRotation:true});

This code creates a white box (it’s slightly gray because of the default alpha value of 0.8) with fixeRotation set to true. If you try throwing it around you’ll notice that it does not rotate. Pretty simple huh?

It’s worth noting that you can still set the angle param. Give this a try:

sim.addBox({x:19, y:3, width:1, height:2, fillColor:0xFFFFFF, fixedRotation:true, angle:1});

Step 9: The isSleeping Param

Box2D rigid bodies fall asleep by default to conserve CPU. This act of falling asleep occurs when a rigid body has come to rest. Sometimes you want to prevent a rigid body from falling asleep using the allowSleep boolean (we’ll see a good example of this later in the tutorial). Sometimes you want to start a rigid body off asleep. For these cases you use the isSleeping param. It may not be obvious, but isSleeping can be used to create breakable objects. Add this code to your buildSimulation() function and test your movie:

/*---------------------------------
	  -- Step 10: allowSleep
	 ---------------------------------*/
	// create 10 boxes in a grid formation
	for (i = 0; i<10; i++){
		sim.addBox({x:13 + (i % 2) * 0.5,
					y:3 + int(i / 2) * 0.5,
					width:0.5, height:0.5,
					lineAlpha:0,
					fillColor:0x4444FF,
					isSleeping:true});
	}

This code creates 10 boxes in a grid formation, the boxes don’t have a stroke and are colored with a saturated blue. The isSleeping param is set to true by default, causing the boxes to remain at their starting position until something else hits them and wakes them up. If you throw another rigid body at this grid of boxes you’ll notice that we’ve created the illusion of a breakable rigid body.

If you’re not familiar with the technique we’re using to arrange the boxes in a grid, you can read this tutorial about arranging DisplayObject in grid formations over at learningActionScript3.com


Step 10: The groupIndex Param

The groupIndex param can be used to give you a finer control over the way collision is handled between rigid bodies. It is an integer that is either negative or positive. If two rigid bodies have the same negative groupIndex value they won’t collide with one another, if they have the same positive groupIndex value they will collide. Add this code to your buildSimulation() function:

for (i = 0; i<4; i++){
	  sim.addBox({x:2 + i , y:2, fillColor:0xFFFF00,
				 width:0.5, height:1.5, groupIndex:-1});
	}

    // small platform
	sim.addBox({x:6, y:4, width:10, height:0.25, density:0});

This code creates four yellow rectangles with a groupIndex value of -1. It also creates another small platform to make observation of the groupIndex param easy. If you test your movie you’ll notice that these rectangles will not collide with one another.

I find myself using this groupIndex quite a bit. It’s essential when dealing with complex simulations. There are two other related params called maskBits and categoryBits. I have yet to need these very much, however you can read a bit more about them in the Box2D manual if you’re interested.


Step 11: Getting Ready for Key Controls

As mentioned in part 1 of this tutorial. Every creation method (addBox(), addPoly() etc…) returns a QuickObject. When you want to start keeping track of elements in a simulation you’ll want to store QuickObject references in variables. We’re going to begin setting up a rigid body to be controlled with the arrow keys. In order to do this we need to do a little preparation. First, add this variable definition to your code (remember to put it under the variable definition comment outside of the buildSimulation() function).

/**-----------------------------
  -- insert variable definitions below this comment
  ------------------------------*/
var character:QuickObject;

Next add the following code to your buildSimulation() function:

var charPartA:QuickObject = sim.addBox({x:0, y:0, width:2, height:0.8});
var charPartB:QuickObject = sim.addBox({x:0, y:0, width:0.8, height:2});
character = sim.addGroup({objects:[charPartA, charPartB], x:8, y:3, angularDamping:0.8, linearDamping:0.8, allowSleep:false});

This creates a small group object built up of two boxes. We set linear and angular damping properties so it won’t move too fast when we start controlling it with the keyboard. We also use a param called allowSleep to make sure that the character rigid body doesn’t fall asleep (without this key controls won’t work properly). Test your movie to make sure that the character group object has been added to the simulation properly.

WARNING: These next few steps get a little tricky, so pay close attention to each instruction. If you start to get worried that you can’t follow all the changes to the code, after the tricky part is over you may consider downloading the complete fla to compare.


Step 12: Adding Basic Key Control Code

For certain types of key control just using KeyboardEvents alone won’t cut it. Normally I will use something like this:

var key:Object = new Object();
stage.addEventListener(KeyboardEvent.KEY_DOWN,onKeyPressed);
stage.addEventListener(KeyboardEvent.KEY_UP, onKeyReleased);
function onKeyPressed(evt:KeyboardEvent):void {
	key[evt.keyCode] = true;
}
function onKeyReleased(evt:KeyboardEvent):void {
	key[evt.keyCode] = false;
}

This code creates an Object (associative array or a map) called key. When a key is pressed for the first time, a property is dynamically created on the key Object, the keyCode is used for the name of the property and since we’re on a KEY_DOWN event the property is set to true. When a KEY_UP event occurs the newly created property is set to false. You should copy and paste this code all the way down at the bottom of your script at this point.

If you’ve never seen this technique before, it may seem a little odd to you. If that’s the case, all you need to know is that this code prevents some minor issues with using KeyboardEvents alone and that if we want to respond to keyboard input, we can simply do something like this in a loop:

if (key[Keyboard.UP]){
  // make the character jump
}

Now, when using a loop in conjunction with QuickBox2D you can listen for Event.ENTER_FRAME if you like, but later versions of QuickBox2D have a special type of event called QuickBox2D.STEP. You should always use QuickBox2D.STEP in favor of Event.ENTER_FRAME, we’ll talk a little more about this when we get to FRIM. Inside your buildSimulation() function you should add a listener for this event:

 sim.addEventListener(QuickBox2D.STEP, onStep);

We’ll also need to add a listener function directly below our buildSimulation() function:

...
sim.addEventListener(QuickBox2D.STEP, onStep);
} //  end of our buildSimulation() function

// -- copy from this point on...
// our listener function
function onStep(evt:Event):void {
   // we'll add some key control stuff here soon
}

Ok, now we’re almost ready to start doing some key controlled motion…


Step 13: Key Controls, Linear Velocity and the Body Property

All QuickObjects have a property called body. This property contains a reference to a Box2D b2Body instance. By exposing this b2Body instance, QuickBox2D gives you access to a bunch of Box2D methods. We’re going to use the GetLinearVelocity() and SetLinearVelocity(). For a full list of all the b2Body methods, have a look here.

The linear velocity of a rigid body is defined by a 2D vector, the x and y values of this vector are added to the x and y position of a given rigid body. The linear velocity of a rigid body varies over time due to gravity, collisions with other objects, friction etc… Box2D has a class specifically designed for dealing with vectors called b2Vec2. The SetLinearVelocity() method takes a b2Vec2 as its first and only argument. We need to import b2Vec2, so add this line below the import statement for QuickBox2D:

// you already have this line
import com.actionsnippet.qbox.*

// add this line:
import Box2D.Common.Math.*;

b2Vec2 is contained within the Math package. Now let’s take a look at SetLinearVelocity(). We need to add some code inside of the onStep() listener function:

// you should already have this function defintion
function onStep(evt:Event):void {
   // add this conditional
   if (key[Keyboard.RIGHT]){
      character.body.SetLinearVeloctiy(new b2Vec2(10, 0));
   }
}

Try testing your movie and hitting the right key. The character rigid body should float to the right of the screen. Let’s add code for a left key, add the following code inside your onStep() function:

// add this:
 if (key[Keyboard.LEFT]){
      character.body.SetLinearVeloctiy(new b2Vec2(-10, 0));
 }

You may want to try messing around with the x and y values of the b2Vec2 to get a feel for how it works.

This is pretty nice, but the motion is pretty robotic. There are a few things we can do to make these key controls work a bit nicer. The first thing we can do is just organizational. It’s not very convenient or flexible to constantly create new b2Vec2 instances, so let’s add a variable for working with the character’s linear velocity. Add this variable definition to your code:

// you already have this
var character:QuickObject;

// add this line
var charVel:b2Vec2 = new b2Vec2();

If you don’t pass anything to the b2Vec2 constructor the x and y properties default to 0. Next, alter your onStep() function to look like this:

function onStep(evt:Event):void {
    charVel = character.body.GetLinearVelocity();

    if (key[Keyboard.RIGHT]){
		charVel.x += 0.8;
		character.body.SetLinearVelocity(charVel);
	}
	if (key[Keyboard.LEFT]){
		charVel.x -= 0.8;
		character.body.SetLinearVelocity(charVel);
	}
	if (key[Keyboard.UP]){
		 charVel.y = -10;
		 character.body.SetLinearVelocity(charVel);
	}
	if (key[Keyboard.DOWN]){
		 charVel.y = 0.8;
		 character.body.SetLinearVelocity(charVel);
	}
}

If you test your move you’ll notice that the key controls for the character have improved significantly.

At the beginning of the onStep() function we call the GetLInearVelocity() method. We do this so that we don’t force the linear velocity to change abruptly by resetting all the values. Instead, we read the linear velocity and alter according to keyboard input. When we want to move right or left we just alter the x property slightly (by 0.8 meters). When we move up, we need a little more force because of gravity so we alter the y property of charVel by -10. When we move down, gravity is working in our favor so we can just use 0.8 meters again.

At this point we need to perform a little code clean up. Let’s move the key control code into its own function:

function onStep(evt:Event):void {
    charVel = character.body.GetLinearVelocity();
    keyControls();
}

function keyControls():void{
   if (key[Keyboard.RIGHT]){
		charVel.x += 0.8;
		character.body.SetLinearVelocity(charVel);
	}
	if (key[Keyboard.LEFT]){
		charVel.x -= 0.8;
		character.body.SetLinearVelocity(charVel);
	}
	if (key[Keyboard.UP]){
		 charVel.y = -10;
		 character.body.SetLinearVelocity(charVel);
	}
	if (key[Keyboard.DOWN]){
		 charVel.y = 0.8;
		 character.body.SetLinearVelocity(charVel);
	}
}

If you are feeling organized you might wrap up the -10 and 0.8 values into variables. For the simplicity of this tutorial I’ll leave that out, but feel free to do so if you like.

As mentioned before, there are a whole bunch of other methods in the b2Body class. You may want to take a few minutes and play around with some of the other ones. They’re all pretty intuitive – some of them will be covered in part three of this tutorial series.


Step 14: QuickObject x and y Properties

It’s quite common to need to force a rigid body to jump from one place to another. You can do this using the QuickObject x and y properties. Add the below teleportCharacter() function to your code and call it continuously in your onStep() function:

...
teleportCharacter();

}// end of onStep() method

function teleportCharacter():void{
	// restrict character motion
	if (char.x < 4 && char.y > 12){
		char.x = 8;
		char.y = 3;
		// zero out the characters velocity
		charVel.SetZero();
		char.body.SetLinearVelocity(charVel);
	}
}

This code makes it so that when your character moves to the lower left hand corner of the screen, it teleports back to its original starting position of (8,3). Test your movie and work your way to the lower left corner of the screen to see it in action.

This works by continuously checking the x and y properties of our character rigid body and then resetting them if the given condition is met. We also call the SetZero() method the b2Vec2 charVel – as the name implies this sets x and y properties of charVel to 0, causing the character’s linear velocity to be set to zero.


Step 15: Adding Two Platforms

In this next step we’re going to use the x, y and angle properties of QuickObjects to create some simple floating platforms. The first thing we need to do is add some variable definitions:

// you already have these...
var character:QuickObject;
var charVel:b2Vec2 = new b2Vec2();

// add these 3 new vars
var oscillator:QuickObject;
var oscTheta:Number = 0;
var rotator:QuickObject;

First we’ll populate the oscillator variable with a static rectangle body. Add this code to your buildSimulation() function:

 oscillator = sim.addBox({x:21, y:8, width:2.5, height:0.25, fillColor:0x009965, density:0});

This is pretty straight forward so far. We want to oscillate this platform up and down – for that we’ll use Math.sin(). Add the below runOscillator() function to your code and call it continuously in your onStep() function. Test your movie.

...
runOscillator();
} // end of onStep() function

function runOscillator():void{
	oscillator.y = 8 + 4 * Math.cos(oscTheta);
	oscTheta += 0.01;
}

This code oscillates the y property of the oscillator rigid body between 4 and 16 meters. If you’re unfamiliar with sine and cosine, you may want to read up a bit on some basic trigonometry. The main point of this example is that we are able to use a simple equation to alter the y property of a rigid body.

Next we’ll add our rotator platform. Copy this code into your buildSimulation() function:

rotator = sim.addBox({x:16, y:8, width:3, height:0.3, fillColor:0x009965, density:0});

Nothing special happening here, we’ve just positioned this platform so that it doesn’t interfere with any other parts of our simulation. Now it needs to rotate – we’ll add a function called runRotator() to do just that:

...
runRotator();
} // end of onStep() function

function runRotator():void{
	rotator.angle += 0.02;
}

Go ahead and test your movie. Take a few moments to move rigid bodies on and off the platforms.

While testing you may have noticed a that rigid bodies can fall through the oscillating platform. If you didn’t notice this, take any rigid body with the exception of the character and place it on the oscillating platform. You’ll notice that after a little while it falls through the oscillating platform like this:

This occurs because the body sitting on the oscillating platform has fallen asleep and Box2D has stopped checking for collisions on it. The easy solution is to set the allowSleep param to false on any rigid body that might need to sit on the oscillating platform. This works nicely, but is not very efficient. A more elegant solution would be if we could tell if a collision were occurring on the oscillating platform and make sure that the thing it is colliding with doesn’t fall asleep. This is possible using something called contact points. We cover contact points in part 3 of this tutorial, but if you’re curious you can see a few examples of them here.


Step 16: The userData Property

In Box2D, rigid bodies have a property called userData. This is just an untyped variable intended for use with custom information about a given rigid body.

QuickBox2D populates the userData property with a DisplayObject. So, if you want to add a MouseEvent to the skin of a QuickObject, or if you want to draw some additional graphics into a QuickObject using the graphics property, you need to use the userData property. We’ll see how to do both of these things in this step. Start off by defining a variable called shootBox with all your other variables:

// you already have these:
var oscTheta:Number = 0;
var rotator:QuickObject;

// add this
var shootBox:QuickObject;

Now we’ll create shootBox and draw an X inside it. Add the following code to your buildSimulation() function and test your movie:

     shootBox = sim.addBox({x:24, y:17, width:1.5, height:1.5});

	 // draw an X into shootBox userData.graphics
	 shootBox.userData.graphics.lineStyle(0, 0xFFFFFF, 0.5);
	 shootBox.userData.graphics.moveTo(-20, -20);
	 shootBox.userData.graphics.lineTo(20, 20);
	 shootBox.userData.graphics.moveTo(20, -20);
	 shootBox.userData.graphics.lineTo(-20, 20);

This will work the same way if you’re using custom skins.

Adding MouseEvents works exactly the same way. Let’s create a simple listener function for use with a MouseEvent, add this function to your code:

function onShootBoxClick(evt:MouseEvent):void {
    var currLinearVec:b2Vec2 = shootBox.body.GetLinearVelocity();
	currLinearVec.x -= 15;
	currLinearVec.y -= 15;
	shootBox.body.SetLinearVelocity(currLinearVec);
}

We can use this listener function in conjunction with shootBox now, add this code to your buildSimulation() function:

shootBox.addEventListener(MouseEvent.CLICK, onShootBoxClick);

When you test your movie, if you click on the shootBox rigid body it’s linear velocity is reset causing it to shoot up and to the left.


Step 17: Angular Velocity

We can add one final touch to our shootBox using angular velocity. Angular velocity is the velocity of a given rigid bodies rotation. To add a little spin to the shootBox, add this line into the onShootBoxClick() listener function:

shootBox.body.SetAngularVelocity(-10);

Go ahead and test your movie.

An angular velocity of -10 will cause the shootBox to rotate counter clockwise at 10 radians per second. A positive value would cause the shootBox to rotate clockwise.


Step 18: FRIM

FRIM (frame rate independent motion) is used to attempt to keep the speed of the Box2D simulation constant no matter what frame rate your swf is running at. This is good because frame rates will vary from browser to browser and from computer to computer.

Go to line one of your code and try changing the frame rate to 20, 120, 5 etc… each time testing the swf to see how it looks.

[SWF(width = 800, height=600, frameRate=20, backgroundColor=0x000000)];

What you’ll notice as you change the frameRate value, is that the speed of the rigid bodies remains relatively constant. The difference is that a different number of frames is being used to represent the same animation. This is really important in games – if your game animated very slowly on an older computer it might become significantly easier to play.

We can toggle FRIM by altering the arguments that we pass to the QuickBox2D constructor. You should be up at the top of your script, go ahead and change the line where we instantiate QuickBox2D to look like this:

var sim:QuickBox2D = new QuickBox2D(this, {frim:false});

Test your movie a few times, each time changing the frameRate value and notice that lower frame rates now cause the simulation to run slower, while higher frame rates will speed up the simulation. When you’re done testing set FRIM back to true and set your frameRate back to 60.

Note: The second argument of the QuickBox2D constructor is an object of params related to the entire simulation.

Earlier in the tutorial we used the QuickBox2D.STEP event instead of an enterFrame. This may be obvious, but QuickBox2D.STEP gets triggered independently of frameRate. By default QuickBox2D attempts to update the simulation at 60Hz (or 60 times per second), so if a swf is only running at 30fps the QuickbBox2D.STEP event will run approximately 2 timer per frame. You can change how often QuickBox2D.STEP occurs by altering the timeStep param like this:

var sim:QuickBox2D = new QuickBox2D(this, {frim:true, timeStep:1/30.0});

The above would lower the timeStep to 30hz, causing QuickBox2D.STEP to get called every other frame at 60fps or once per frame at 30fps. You can try this if you like but I’ve found that 60hz and a frameRate of 60fps works the best most of the time.


Step 19: Gravity

We can alter the gravity in the simulation by adding additional params to the QuickBox2D params argument. Try this:

var sim:QuickBox2D = new QuickBox2D(this, {frim:true, gravityY: -20});

When you test your movie you’ll notice that gravity is now reversed. By default gravityY is 20, setting it to -20 has caused everything to fall up. You can also alter gravityX (this is good for creating wind effects):

var sim:QuickBox2D = new QuickBox2D(this, {frim:true, gravityY:-20, gravityX:10});

This is pretty funny looking:

But if you think about it for a moment, it could be very cool to have variable gravity and wind in a game. Try adding this snippet to your code, you can just add it right under the QuickBox2D instantiation code:

stage.addEventListener(MouseEvent.CLICK, onClick);
function onClick(evt:*){
	sim.gravity.x += 3;
}

Now when you click on the stage you slowly increase the x gravity. I recommend removing or commenting out these gravity alterations at this point.


What’s Next?

That wraps up part two of this series of tutorials. The third and final part of this tutorial will cover some advanced techniques. We’ll look at how QuickBox2D handles all of the different types of Box2D joints (there are lots of them). We’ll also go over contact points and special types of collisions.

I hope you enjoyed this tutorial. If you create something interesting with what you’ve learned in this tutorial feel free to post a link to it in the comments :D

Quick Tip: An Introduction to Sculptris

In this video Evan Schaible take a look at Sculptris, the robust freeware 3d sculpting application for Windows. To download this application go to : http://drpetter.se/project_sculpt.html

Video 1

Download

Note: click the ‘Monitor’ icon to view tutorial in full-screen HD.



Don’t miss more CG tutorials and guides, published daily – subscribe to Cgtuts+ by RSS.

Quick Tip: Understanding Garbage Collection in AS3

Have you ever used a flash application and noticed lag in it? Still don’t know why that cool flash game runs slowly on your computer? If you want to know more about a possible cause of it, then this article is for you.

We found this awesome author thanks to FlashGameLicense.com, the place to buy and sell Flash games!


Final Result Preview

Let’s take a look at the final result we will be working towards:


Step 1: A Quick Run Through Referencing

Before we get into the real subject, you first need to know a bit about how instantiating and referencing works in AS3. If you have already read about it, I still recommend reading this small step. That way, all the knowledge will be fresh in your head and you won’t have trouble reading the rest of this Quick Tip!

The creation and reference of instances in AS3 is different than most people think. The instantiation (or “creation”) of something happens only when the code asks to create an object. Usually, this happens through the “new” keyword, but it is also present when you use a literal syntax or define parameters for functions, for example. Examples of this are shown below:

// Instantiation through the "new" keyword
new Object();
new Array();
new int();
new String();
new Boolean();
new Date();

// Instantiation through literal syntax
{};
[];
5
"Hello world!"
true

// Instantiation through function parameters
private function tutExample(parameter1:int, parameter2:Boolean):void

After an object is created, it will remain alone until something references it. In order to do that, you generally create a variable and pass the object’s value to the variable, so that it knows which object it currently holds. However (and this is the part most people don’t know), when you pass a variable’s value to another variable, you aren’t creating a new object. You are instead creating another link to the object that both variables now hold! See the image below for clarification:

The image assumes both Variable 1 and Variable 2 can hold the smiley (i.e. they can hold the same type). In the left side, only Variable 1 exists. However, when we create and set Variable 2 to the same value of Variable 1, we are not creating a link between Variable 1 and Variable 2 (top-right part of the image), instead we are creating a link between the Smiley and Variable 2 (bottom-right part of the image).

With this knowledge, we can jump to the Garbage Collector.


Step 2: Every City Needs a Garbage Collector

It is obvious that every application needs a certain amount of memory to run, as it needs variables to hold values and use them. What isn’t clear is how the application manages the objects that aren’t needed anymore. Does it recycle them? Does it delete them? Does it leave the object in the memory until the application is closed? All three options can happen, but here we will talk specifically about the second and third ones.

Imagine a situation in which an application creates a lot of objects when it is initialized, but once this period ends more than half of the objects created remain unused. What would happen if they were left in the memory? They would certainly take a lot of space in it, thus causing what people call lag, which is a noticeable slow-down in the application. Most users wouldn’t like this, so we must avoid it. How can we code in order to make the application run more efficiently? The answer is in the Garbage Collector.

The Garbage Collector is a form of memory management. It aims to eliminate any object that is not used and is occupying space in the system’s memory. This way the application can run with mimimum memory usage. Let’s see how it works:

When your application starts to run, it asks for an amount of memory from the system which will be used by the application. The application starts then filling this memory with any information you need; every object you create goes into it. However, if the memory usage gets close to the memory requested initially, the Garbage Collector runs, seeking any object not used to empty some space in the memory. Sometimes this causes a bit of lag in the application, due to the big overhead of object searching.

In the image, you can see the memory peaks (circled in green). The peaks and the sudden drop are caused by the garbage collector, which acts when the application has reached the requested memory usage (the red line), removing all unnecessary objects.


Step 3: Starting the SWF File

Now that we know what the Garbage Collector can do for us, it’s time to learn how to code in order to get all the benefits from it. First of all, we need to know how the Garbage Collector works, in a practical view. In code, objects become eligible for Garbage Collection when they become unreachable. When an object cannot be accessed, the code understands that it won’t be used anymore, so it must be collected.

Actionscript 3 checks reachability through garbage collection roots. At the moment an object can’t be accessed through a garbage collection root, it becomes eligible for collection. Below you see a list of the principal garbage collection roots:

  • Package-level and static variables.
  • Local variables and variables in the scope of an executing method or function.
  • Instance variables from the application’s main class instance or from the display list.

In order to understand how objects are handled by the Garbage Collector, we must code and examine what is happening in the example file. I will be using FlashDevelop’s AS3 project and Flex’s compiler, but I’m assuming you can do it on any IDE you want, since we are not going to use specific things that exist only in FlashDevelop. I have built a simple file with a button and text structure. Since this isn’t the objective in this quick tip, I will quickly explain it: when a button is clicked, a function fires. At any time we want to display some text in the screen, you call a function with the text and it is displayed. There is also another text field to show a description for buttons.

The objective of our example file is to create objects, delete them and examine what happens to them after they are deleted. We will need a way to know whether the object is alive or not, so we will add an ENTER_FRAME listener to each of the objects, and make them display some text with the time they’ve been alive. So let’s code the first object!

I created a funny smiley image for the objects, in tribute to Michael James Williams’s great Avoider game tutorial, which also uses smiley images. Each object will have a number on its head, so we can identify it. Also, I named the first object TheObject1, and the second object TheObject2, so it will be easy to distinguish. Let’s go to the code:

private var _theObject1:TheObject1;

private function newObjectSimple1(e:MouseEvent):void
{
	// If there is already an object created, do nothing
	if (_theObject1)
		return;

	// Create the new object, set it to the position it should be in and add to the display list so we can see it was created
	_theObject1 = new TheObject1();
	_theObject1.x = 320;
	_theObject1.y = 280;
	_theObject1.addEventListener(Event.ENTER_FRAME, changeTextField1);

	addChild(_theObject1);
}

The second object looks almost the same. Here it is:

private var _theObject2:TheObject2;

private function newObjectSimple2(e:MouseEvent):void
{
	// If there is already an object created, do nothing
	if (_theObject2)
		return;

	// Create the new object, set it to the position it should be in and add to the display list so we can see it was created
	_theObject2 = new TheObject2();
	_theObject2.x = 400;
	_theObject2.y = 280;
	_theObject2.addEventListener(Event.ENTER_FRAME, changeTextField2);

	addChild(_theObject2);
}

In the code, newObjectSimple1() and newObjectSimple2() are functions that are fired when their corresponding button is clicked. These functions simply create an object and add it in the display screen, so we know that it was created. Additionally, it creates an ENTER_FRAME event listener in each object, which will make them display a message every second, as long as they are active. Here are the functions:

private function changeTextField1(e:Event):void
{
	// Our example is running at 30FPS, so let's add 1/30 on every frame in the count.
	_objectCount1 += 0.034;

	// Checks to see if _objectCount1 has passed one more second
	if(int(_objectCount1) > _secondCount1)
	{
		// Displays a text in the screen
		displayText("Object 1 is alive... " + int(_objectCount1));

		_secondCount1 = int(_objectCount1);
	}
}
private function changeTextField2(e:Event):void
{
	// Our example is running at 30FPS, so let's add 1/30 on every frame in the count.
	_objectCount2 += 0.034;

	// Checks to see if _objectCount2 has passed one more second
	if(int(_objectCount2) > _secondCount2)
	{
		// Displays a text in the screen
		displayText("Object 2 is alive... " + int(_objectCount2));

		_secondCount2 = int(_objectCount2);
	}
}

These functions simply display a message on the screen with the time the objects have been alive. Here is the SWF file with the current example:


Step 4: Deleting the Objects

Now that we have covered the creation of objects, let’s try something: have you ever wondered what would happen if you actually delete (remove all references) an object? Does it get garbage collected? That’s what we will test now. We are going to build two delete buttons, one for each object. Let’s make the code for them:

private function deleteObject1(e:MouseEvent):void
{
	// Check if _theObject1 really exists before removing it from the display list
	if (_theObject1 && contains(_theObject1))
		removeChild(_theObject1);

	// Removing all the references to the object (this is the only reference)
	_theObject1 = null;

	// Displays a text in the screen
	displayText("Deleted object 1 successfully!");
}
private function deleteObject2(e:MouseEvent):void
{
	// Check if _theObject2 really exists before removing it from the display list
	if (_theObject1 && contains(_theObject2))
		removeChild(_theObject2);

	// Removing all the references to the object (this is the only reference)
	_theObject2 = null;

	// Displays a text in the screen
	displayText("Deleted object 2 successfully!");
}

Let’s take a look at the SWF now. What do you think will happen?

As you can see. If you click “Create Object1″ and then “Delete Object1″, nothing really happens! We can tell the code runs, because the text appears in the screen, but why doesn’t the object get deleted? The object is still there because it wasn’t actually removed. When we cleared all references to it, we told the code to make it eligible for garbage collection, but the garbage collector never runs. Remember that the garbage collector will only run when the current memory usage gets close to the requested memory when the application started to run. It does make sense, but how are we going to test this?

I’m certainly not going to write a piece of code to fill our application with useless objects until the memory usage gets too big. Instead, we will use a function currently unsupported by Adobe, according to Grant Skinner’s article, which forces the Garbage Collector to run. That way, we can trigger this simple method and see what happens when it runs. Also, from now on, I will refer to Garbage Collector as GC, for the sake of simplicity. Here’s the function:

private function forceGC(e:MouseEvent):void
{
	try
	{
		new LocalConnection().connect('foo');
		new LocalConnection().connect('foo');
	}
	catch (e:*) { }

	// Displays a text in the screen
	displayText("----- Garbage collection triggered -----");
}

This simple function, which only creates two LocalConnection() objects, is known to force the GC to run, so we will call it when we want this to happen. I don’t recommend to use this function in a serious application. If you are doing it for test, there are no real problems, but if it’s for an application that will get distributed to people, this isn’t a good function to use, since it may incur negative effects.

What I recommend for cases like this is that you just let the GC run at its own pace. Don’t try to force it. Instead, focus on coding efficiently so that memory issues don’t happen (we will cover this in Step 6). Now, let’s take a look at our example SWF again, and click the “Collect Garbage” button after creating and deleting an object.

Have you tested the file? It worked! You can see that now, after deleting an object and triggering the GC, it removes the object! Notice that if you don’t delete the object and call the GC, nothing will happen, since there is still a reference to that object in the code. Now, what if we try to keep two references to an object and remove one of them?


Step 5: Creating another Reference

Now that we have proved that the GC works exactly as we wanted, let’s try something else: link another reference to an object (Object1) and remove the original. First, we must create a function to link and unlink a reference to our object. Let’s do it:

private function saveObject1(e:MouseEvent):void
{
	// _onSave is a Boolean to check if we should link or unlink the reference
	if (_onSave)
	{
		// If there is no object to save, do nothing
		if (!_theObject1)
		{
			// Displays a text in the screen
			displayText("There is no object 1 to save!");

			return;
		}

		// A new variable to hold another reference to Object1
		_theSavedObject = _theObject1;

		// Displays a text in the screen
		displayText("Saved object 1 successfully!");

		// On the next time this function runs, unlink it, since we just linked
		_onSave = false;
	}
	else
	{
		// Removing the reference to it
		_theSavedObject = null;

		// Displays a text in the screen
		displayText("Unsaved object 1 successfully!");

		// On the next time this function runs, link it, since we just unlinked
		_onSave = true;
	}
}

If we test our swf now, we will notice that if we create Object1, then save it, delete it and force the GC to run, nothing will happen. That is because now, even if we removed the “original” link to the object, there is still another reference to it, which keeps it from being eligible for garbage collection. This is basically all you need to know about the Garbage Collector. It isn’t a mystery, after all. but how to we apply this to our current environment? How can we use this knowledge to prevent our application from running slowly? This is what Step 6 will show us: how to apply this in real examples.


Step 6: Making Your Code Efficient

Now for the best part: making your code work with the GC efficiently! This step will provide useful information that you should keep for your entire life – save it properly! First, I’d like to introduce a new way to build your objects in your application. It is a simple, but effective way to collaborate with the GC. This way introduces two simple classes, which can be expanded to others, once you understand what it does.

The idea of this way is to implement a function – called destroy() – on every object that you create, and call it every time you finish working with an object. The function contains all the code necessary to remove all references to and from the object (excluding the reference which was used to call the function), so you make sure the object leaves your application totally isolated, and is easily recognized by the GC. The reason for this is explained in the next step. Let’s look at the general code for the function:

// Create this in every object you use
public function destroy():void
{
	// Remove event listeners
	// Remove anything in the display list
	// Clear the references to other objects, so it gets totally isolated

}

// ...
// When you want to remove the object, do this:
theObject.destroy();

// And then null the last reference to it
theObject = null;

In this function, you’ll have to clear everything from the object, so it remains isolated in the application. After doing that, it will be easier for the GC to localize and remove the object. Now let’s look at some of the situations in which most memory errors happen:

  • Objects that are used only in an interval of execution: be careful with these ones, as they can be the ones that consume a lot of memory. These objects exist only for some period of time (for example, to store values when a function runs) and they aren’t accessed very often. Remember to remove all references to them after you’re done with them, otherwise you can have many of them in your application, only taking memory space. Keep in mind that if you create a lot of references to them, you must eliminate each one through the destroy() function.
  • Objects left in the display list: always remove an object from the display list if you want to delete it. The display list is one of the garbage collection roots (remember that?) and so it is really important that you keep your objects away from it when removing them.
  • Stage, parent and root references: if you like to use a lot these properties, remember to remove them when you’re done. If a lot of your objects have a reference to these, you may be in trouble!
  • Event listeners: sometimes the reference that keeps your objects from getting collected is an event listener. Remember to remove them, or use them as weak listeners, if necessary.
  • Arrays and vectors: sometimes your arrays and vectors can have other objects, leaving references within them which you may not be aware of. Be careful with arrays and vectors!

Step 7: The Island of References

Although working with the GC is great, it isn’t perfect. You have to pay attention to what you are doing, otherwise bad things can happen with your application. I’d like to demonstrate a problem that may crop up if you don’t follow all the required steps to make your code work with the GC properly.

Sometimes, if you don’t clear all the references to and from an object, you may have this problem, especially if you link a lot of objects together in your application. Sometimes, a single reference left can be enough for this to happen: all your objects form an island of references, in which all the objects are connected to others, not allowing the GC to remove them.

When the GC runs, it performs two simple tasks to check for objects to delete. One of these tasks is counting how many references each object has. All objects with 0 references get collected at the same time. The other task is to check if there is any small bunch of objects that link to each other, but can’t be accessed, thus wasting memory. Check the image:

As you can see, the green objects can’t be reached, but their reference counting is 1. The GC performs the second task to check for this chunk of objects and removes all of them. However, when the chunk is too big, the GC “gives up” on checking and assumes the objects can be reached. Now imagine if you have something like that:

This is the island of references. It would take a lot of memory from the system, and wouldn’t be collected by the GC because of the complexity of it. It sounds pretty bad, huh? It can be easily avoided, though. Just make sure you have cleared every reference to and from an object, and then scary things like that won’t happen!


Conclusion

This is it for now. In this Quick Tip we learned that we can make our code better and more efficient in order to reduce lag and memory issues, thus making it more stable. In order to do this, we have to understand how referencing objects work in AS3, and how to benefit from them to make the GC work properly in our application. Despite the fact that we can make our application better, we have to be careful when doing it – otherwise it can get even messier and slower!

I hope you liked this simple tip. If you have any questions, drop a comment below!

The Making of Lost – Part 1

In this tutorial series, I will be covering the basic process of how I created my piece “lost.” The first part of this two part series covers the basics of creating 3D abstract pieces and how to incorporate them with photo manipulation; the second part will focus on the creation of effects in Photoshop and how to enhance and strengthen the final image.

A key to succeed in following this tutorial series is to experiment. I will be teaching the basic techniques but in order to create a strong composition and attractive shapes, you will need to alter the settings, change/redo splines and experiment with other effects. Patience and determination are mandatory skills for any artist. So let’s get started!

Let’s take a look at the image we’ll be creating for this two part series (above): Part 1 here on Cgtuts+ in today’s tutorial and Part 2 will be covered over on Psdtuts+ in the final tutorial.


Step 1

Open the image we’ll be working with in Photoshop.

s1

Step 2

Using the Pen Tool, cut out the unwanted part as shown below.

s2

Step 3

Open Cinema 4D. Use the freehand spine tool to draw three splines in the three views. This can be totally random, or you can carefully plan out the wanted shape and draw precisely according to that.

s3

Step 4

Create a loft NURBS, drag the three splines created under loft NURBS creating a three-dimensional object.

s4

Step 5

Use the twist deformer (under the deformer menu) and do adjustments to its properties as needed. The effect can also be affected by the orientation and position of the deformer.

s5

Step 6

Use the explosion effects deformer, the result of this can be affected not only by its property settings but also by its position.

s6

Step 7

Create a HyperNURBS, make the loft NURBS create its child through dragging.

s7

Step 8

Add a few lights, the position of the lights at this point depend on your model and how the most details possible can be shown.

s8

Step 9

Create a new texture using the following settings.

s9

Step 10

Create a simple white texture.

s10

Step 11

Create a simple black texture.

s11

Step 12

Create a glass texture. Apply these textures to the model; duplicating the model, altering their settings allows you to create a more complex render and apply the different textures created.

s12
s12-cont

Step 13

Jump back over to our Photoshop document. Use the Pen Tool to create a curve according to the contour of the suit.

S13

Step 14

Select the shape created, nudge the selection to the right, then down, and then delete. This creates a white edge. If you’re not satisfied with the effect, then duplicate the layer, invert the color, and nudge it to the left to give the edge depth.

S14

Step 15

Take the renders created in Steps 2-12, then place one of them behind the “man” layer and one above. Erase the unwanted parts to achieve the following.

s15

Step 16

Take another render to place below the suit.

s16

Step 17

Create a sphere by first creating the simple image below then applying it to a sphere object.

s17

Final Image

To achieve the final effect, slightly adjust the level to enhance the image.

s18

Stay Tuned for Part 2

You could end here with an illustration that mixes 3D and Photographic elements. Though if you want to add more interest to the final image with Photoshop effects, then stay tuned for Part 2, which will post over on Psdtuts+ soon.

r17

Animating with Deformers in Maya

Although animating with deformers is a commonly used technique in the VFX industry, a lot of people don?t know about it’s benefits. Well, after this tutorial that?’s going to change. We’ll be looking at how to animate complex expressions with deformers, along with why they can be extremely useful. Enjoy!

Step 1

First of all, open Maya and import your model. For this tutorial I’ll be using a version of ZBrush’s standard head model as it will help to easily show the main benefits of deformer-based animation, however this technique will apply across all models no matter how complex. Now go to the front view, duplicate your model (Ctrl+d) and rename the new copy. Be sure to use a descriptive name as this will later become the name of your blend-shape – in this case, I’ve used Male_Head_Smiling. Position both models next to each other to make things easier to work with. Now I’m going to actually deform the second mesh to make it smile!


Step 2

First we need to setup our mesh selection tools. In the top menu, go to Modify > Transformation Tools > Move Tool > Option Box. Turn on Soft Select and set the Falloff radius. This is, of course, a relative value due to the fact the every model you work with will likely be different in size. In this case I want to select an area just large enough to move the cheek a little bit to create the realistic effect I’m going for, so have chosen a value of about 0.35. Now turn on the Reflection setting, lower the Tolerance to about 0.04 and set the Reflection axis to X. This enables us to easily make the same changes to one side of the model as we do on the other, saving us time! We can now start deforming!


Step 3

Next, right-click on the model and go to Vertex mode, which will allow us to move the vertexes instead of the mesh itself. As I’m intending to make the model smile, I’m going to be affecting the vertexes around the corners of the mouth, so I start by dragging a selection from the right corner of the mouth, slightly to the right and then slightly upwards. As you can see below, both sides of the model are affected because of the Reflection setting we previously enabled. The brightly colored areas represent the extent of our falloff.


Step 4

So with our vertexes selected, and with our falloff in place, now activate the move tool. To make this model smile, I needed to move the affected verts slightly to the right and slightly up, and with a little bit of trial and error, this is my result :


Step 5

Now that we?’ve got our original model and our deformed model, we need to create the blend shape deformer itself, so first select the Animation menu-set and then in the top menu choose Create Deformers > Blend Shape > Option Box. In the background, first select the deformed model (in my case the smiling man), then shift click the original model (it’s very important to select the model you want to have the blendshapes implied to last of all.) Enter a name for our deformer in the BlendShape node box, for instance something like Smile.

Now we come to a very important setting – Origin. The default setting is Local, and although you may need to choose World for some rare circumstances, the Local deformer the most useful one. Just to cover it quickly, if you set the origin to World, all deformations are created as relative to the model, meaning that if you move the model around the scene, the won’t move with it! So, for now we’re going to stick to the Local setting. Leave the other settings as they are and then click Create.


Step 6

To use the blend shape we’?ve just created, go to Window > Animation Editors > Blend Shape. You should now have a single slider there (in my case Male_Head_Smiling) and if you move it up and down you’ll quickly start to understand the advantage of animating using deformers – if you move the slider halfway, you see a mix of both models, meaning that with a few blend shapes you can create literally thousands of expressions!


Step 7

To do a little animation test, go to the first frame, move the slider all of the way to the bottom and click Key. Now move forward a few frames, move the slider to the top, and click Key again. If you play back the animation you can actually see the mouth moving.

You can actually add as many blend shapes together as you want, so I’m going to add another one to control my model’s eyebrows.


Step 8

Start by duplicating your original mesh, moving it over to the left of the original, and renaming it, in my case to Eyebrows. Now repeat step 3 as above. This time I moved the area above the eyes downwards slightly, ensuring the eyes themselves remained untouched. Now go to Create Deformers > Blend Shape > Option Box, and select first your newly deformed mesh, and then shift-click the original. Give the blend shape a name and then click Create. On returning to the Blend Shape editor you can see we now have two sliders, in my case one for the mouth and one for the eyebrow expressions.


Step 9

To have more control we can do something else that you may have seen before – interactive controlling. Interactive controlling uses geometry ‘rig’ to control the motion of the blend shapes – something that can be very handy for facial expressions!

In the top menu go to Create > EP Curve Tool, and draw a curve something like that in the picture below – in my case, as this will be the eyebrow controller, I’ve styled it to match. Now go to Modify > Center Pivot, then duplicate your curve and move the duplicate to one side. Select both curves and group them by going to Edit > Group and give the group a clear name – in my case, Eyebrows_Controller. Finally select both of your curves and go to Modify > Freeze Transformations to reset their initial positions.


Step 10

We’?ll now setup the curves to control the blend shapes, using Maya’s Set Driven Keys. First of all ensure that all of your blend shapes are set to 0 – this is very important! Then go to Animate > Set Driven Key > Set to bring up the Set Driven Key window.

Open the Outliner and select your controller group. Then select it again in the Set Driven Key window, and click Load > Selected as Driver. Now back in the Outliner, right-click in the main section and deselect Show DAG Objects Only. This will allow us to see all of the nodes currently in our scene, as shown below :


Step 11

Locate your blendshape node in the Outliner – it will have the name we entered earlier on creation followed by a number, in my case Eyebrows1. Then in the Set Driven Key window, click Load > Selected as Driven. Now you should have something like the picture below :


Step 12

First all you want to work out the axis on which our controller is going to affect the blend shape. As I want the eyebrows to move up and down I’ll be using the Y-Axis, so I’m going to select Translate Y in the right side of the driver pane, at the top of the Set Driven Key window.

Now to create the keys themselves, we first need to setup the start states for the blendshape and our controller curve. I want the eyebrows to be lowered initially, so that moving the controller group up has the effect of raising them. So I’ll set the TranslateY value of my controller to 0 in the attribute editor, and then set the Eyebrows blend shape the value to 1 (lowered). When you’re happy with your initial setup, click the Key button at the bottom of the Set Driven Key window.


Step 13

With the first key created, we now need to set up the second. First of all I set the Eyebrows blend shape value to 0 in order to bring them back to their original position. I can then select the controller group and move them up on the Y-Axis to sit along side the newly raised eyebrows. When you’re happy with your second position, hit the Key button one last time.

With that done you can now close the Set Driven Key window, and try to move the curves around – your mesh is actually responding! I could now go on to apply this technique in exactly the same way to control the position of the mouth, eyes and any other object you can imagine.

So that’s it for today! I hope you enjoyed this tutorial and I especially hope that you?ve learned some new useful techniques you can apply to your own models. Be sure to stand out and be creative!


Don’t miss more CG tutorials and guides, published daily – subscribe to Cgtuts+ by RSS.

To Beer or Not to Beer: Do You Liquid Lunch?

The other day I went out to have a quick lunch with a good friend of mine.  Nothing fancy, just a cheap pizza place that just happened to have a few excellent beers on tap.  (I’m not 100% sure, but I think it might be illegal here in Canada to eat pizza without drinking beer.)

Since I’m self-employed, had no need to drive, and was enjoying the first nice Friday afternoon in what seemed like an eternity, I opted to have a beer with my pizza.  I tried to get my beer-loving friend to join me, but he felt that it wasn’t appropriate given that he still had to go back to his office.

It got me thinking over the past week:  When is it okay to have an adult beverage?

When I was a cable guy, driving a company vehicle – no question.  And let me say this clearly – if you are driving, there’s no acceptable time to have a drink.  But when I got into the advertising world and learned that a beer fridge in the office was not grounds for immediate termination – let’s just say I didn’t think it was that big of a deal to have a “pop” and then walk back to a communications position in an office building.

Now, there’s a world of difference between wanting a drink and needing a drink – and if you are in the latter stage on a regular basis, you might want to consider asking for help.

My question to the folks in WorkAwesome:  Is there an acceptable time to have a drink during the work day?  Do you take part in a “liquid lunch” ritual?

Are Modern Conveniences Really a Time Saver?

Real Simple recently discussed modern time savers that aren’t all the supposed “improvements” that we twenty-first century folk take for granted. You know…things like microwaves, iPhones and the DVR.

The author makes a very valid point. Many of these innovations are a good idea in theory but actually end up requiring more time, not less. Take interstate highways – they’re fabulous until you’re mired in endless miles of traffic when you could be doing something (anything!) else.

One of the so-called “conveniences” that comes to mind for me is NetFlix (the poor man’s DVR). It’s a great way to avoid the video rental store, but then you end up spending the time you saved rearranging your queue or obsessively reading other people’s movie reviews. And if I didn’t have it, I’d probably spend less time watching movies and more time reading books (all right…or surfing the web).  While trying to end up with more hours in the day, you end up with the same – or less.  That’s pretty much the opposite of what you really want in a time saver.

What about you? Can you think of other “time-saving” innovations that actually take up more of our time?

Monotasking: Focus on One Thing at a Time

No matter how much you have piled up on your desk, and regardless of how bad-ass a multitasker you are, you can only do one thing at a time. Remembering this is one sure-fire way to increase your productivity, ease your mental load and knock things off your to-do list with efficiency.

There are two schools of thought on this. One says: juggle tasks and get stuff done a little at a time. This type of incremental thinking is prone to mistakes. It’s easy to lose focus this way and while I consider myself to be pretty good at mental juggling, I’ve found that when I split mind time between a bunch of projects, they can get jumbled and this opens us up to error.

The other school of thought is a little more pure, and a lot more simple: Focus on one thing at a time, get it done and move on to the next task.

(Note: Taking a little mental or musical break in between each task doesn’t hurt either as a way of keeping focused and inspired)

Stacks Upon Stacks of Stuff

We’ve all been there—busy and seemingly without enough time in the day to get everything we’re responsible for done. Here’s where panic can set in. That little voice in your head—the really doubtful, negative one—goes from a whisper to a shout screaming:

We are soooo screwed this time!

Yet, the truth is, when we compartmentalize our thoughts, keep our focus on the moment and the project, it’s amazing how much we can accomplish.

When we get rattled by our busyness, we’re in trouble. It’s easy to let anxiety and the pressure of stacks upon stacks of stuff grind us to a productivity stand-still. All the more reason to remember the simple mantra:

Monotasking – One and Done.

Getting Into The Flow of Monotasking

Stay focused on one task and you’ll be through even the biggest pile of work in no time. In fact, when you stay completely focused, fully in the moment and deeply engaged in the project before you, it’s amazing how quickly time flies. The term for this is known as flow and it’s been written about widely by noted psychologist Mihaly Csikszentmihalyi. (See his TED talk on the topic.)

This is the productivity holy grail. Entering a state of flow puts us in the optimal “get more stuff done” zone. The catalyst for this is focus and one-pointedness of mind regarding how we work. This is often a change of course for the modern worker. With a million windows and documents open, emails constantly dinging in the inbox and an equal number of text, tweets and other information streaming in, it’s challenging to get to flow in the first place – if ever.

But I promise you’ll work better, smarter and get more done if you can:

  • disengage from the information onslaught;
  • let the other work fall into the periphery and;
  • fully immerse ourselves in the moment.

That’s not just a promise…that’s a guarantee.

11 Productivity Tools for Road Warriors and Telecommuters

I love working from home.  I don’t miss the commute or the distractions from coworkers. It’s a pretty good gig.

But at least once a week, I take this show on the road. I have a meeting in town and then need to find a place to set up shop nearby afterward to get some work done.  While I considered renting some co-working space, I decided to go to public spaces instead. You could say I was too cheap to pay rent. But the numbers didn’t work for me.

What does work for me is free public wifi. I have some options around town that give me the ability to set up a mobile office. It’s not perfect, but it works well enough. Like other road warriors and telecommuters, I keep a few key productivity tools in my arsenal to get things done:

Location

I need a place that understands people like me are going to spend more time than money. This place is comfortable and offers ample power outlets.

I know the local joints and what they have to offer. If I’m out of my area, I look for McDonalds, Panera Bread or Starbucks.

I have a Starbucks card that gives me access to two free hours of wifi daily. But come July, that won’t be necessary. They will offer free wireless Internet.

If food or socializing isn’t so important, I like the large desks and quiet of the public library. Finding a power outlet may be a challenge though.

Laptop

You may prefer a netbook or very small laptop because of price and weight. I’m sticking with my 15-inch MacBook Pro. The screen and keyboard are big enough for me to work comfortably. The speed and memory don’t hold me back when I’m surfing the web, writing in Google Documents or watching videos. To be honest, I would prefer a 17-inch model but not enough to pay  the extra money. What I have is the right tool for my work.

You may not need it. But assess what you’re going to do on the road. If you’re not going to do more than check e-mail or some lightweight websites, go with as little as you can get.

Security

My laptop and browser are locked behind different passwords. If someone were to “find” it, they can’t have access to my information. I don’t do top secret work but clients should be able to trust me.

That’s also why my laptop is not my primary computer. Any sensitive work like banking or database maintenance is done at home. That data doesn’t move out of the house.

Also, there are some services that will help you recover your laptop if it’s stolen. Basically when someone uses your laptop to connect to the Internet, these services will find it and collect enough evidence to get the police involved.

Bookmark syncing

I primarily use a desktop machine in the home office. Two computers means two browsers and sets of bookmarks.  I use Xmarks – a Firefox extension – to sync my bookmarks and passwords between the two machines. It’s seamless and fast. Whatever passwords and bookmarks I save are accessible no matter where I am.

Foursquare account

Foursquare is a social network that lets you check-in at various venues and let your friends in the network know where you are. Yes it’s a bit self-indulgent. But when I check-in at a coffee place, the message goes out to my Twitter and Facebook accounts. It’s the equivalent of hanging a sign that says “The Blogger Is In.” This way people can find me if they want to talk. It’s part of the strategy to keeping in touch with my networks.

Clouds

I use Google Apps to handle e-mail and files. I can access my work from anywhere I can access the Internet. Otherwise I know I’m going to forget the thumb drive with the files I need some day. It’s all handy in the clouds.

  • TIP: If you’re worried about security, then make your own cloud. I have my own domain, and installed a secret WordPress blog on the site. No one knows where it and it’s not linked from anywhere. I use it as a notebook. If Google Docs are down, I use my secret blog as a word processor.

The same goes for e-mail. Web-based email services store your messages where you can always get to them. You have a lot of information stored in those messages. Make sure they’re where you can find them.

Smartphone

Of course I’m always reachable by cell phone. It’s a must have for anyone who works out of the “office.” But a smartphone adds a new layer of connectivity. A lot of times it’s easier to check e-mails on a mobile device than firing up a laptop.

Productivity apps such as task managers, calendars and time trackers are handier on a mobile device.

It’s also nice to have some games for diversions.

USB drive

Yes it’s handy to have your documents in the clouds. But sometimes someone wants to give you files directly from their computer. Having them use file sharing services (Or you may need to give them files and documents) may not work so well for them.

A password protected drive will accommodate most of your file transfer needs.

Dress code

“No shirts, no shoes, no service” sets the baseline. But if you want people around you to treat you like a professional, you have to dress the part.

Manners

You’re an adult so show some consideration. Keep your work area neat. Lower your volume on your computer and your voice when talking on the phone. Don’t take up more room than you need. Or hog bandwidth. This isn’t the time to download movies with Bittorrent.

Even if you don’t care about etiquette and don’t see a problem with being self-centered, remember that you are very visible. Your boorish  behavior can hurt your professional reputation.

A bag

We’ve got a lot listed here. But it’s physically not too much to fit into a professional computer tote or messenger bag. Be sure you have room for some a pens or pencil and a notebook. Sometimes you need to take notes old school.

And pick your bag like you would pick your wardrobe. It can round out the professional look and be very functional. Your mileage may vary.

This system works pretty well for me. The biggest downsize is that it’s hard to watch what I eat. Spending a few hours so close to tempting baked goods that are on most coffeehouse menus is tough. But I’m able to be reasonably productive and connect with people.

How productive are you when working with public wifi?

The “Upgrade iPhone” Dilemma: Will You Be Getting an iPhone 4?

As the iPhone 4 prepared to hit stores today, I recall my Apple-obsessed boyfriend is trying to get me to camp out with him at the Apple store last night. I’m quite content with my Blackberry, thank you very much.

And after reading these tips from Geek Juice on Smartening Up a “Dumb Phone”, I’m starting to wonder whether I need a BlackBerry at all. Still, it seems like it would be simpler to use my smartphone’s browser than “googling” things via text message (Google and I are BFFs – I probably do several dozen searches per day).

What about you current or prospective iPhone users? Are you on the yearly “Upgrade iPhone” cycle? Will you be jumping on the faster, shinier, newer bandwagon or sticking with your current phone?

3 Perspectives on Marketing a New Business through Blogging

Blogging is the new marketing. It’s a cost effective way to grow your business by attracting new customers and communicating with your existing customer base with new marketing ideas. Three business bloggers share their advice on marketing a new business with blogs:

Why A Blog Won’t Help Your Business

Rich Brooks explains that a blog is just a tool and you need to use it properly to benefit your business. It’s a great discussion of how to develop a blog strategy.

A Simple Blogging Formula

Chris Brogan outlines some pretty simple steps to creating  consistent blog entries that attract traffic to your website.

5 Reasons Why You Should Respond to Every Comment

Pat Flynn makes the argument that you should answer every comment on your blog with a comment. It makes sense until you start to actually spend the time doing it. Are you ready to make this kind of commitment?

How do build your business by blogging?

Ars Technica Explores iOS 4 in Detail

We asked you if you are considering new iPhone 4. Whether or not you go for the new device, if you own an iPod touch or an old iPhone, you got to upgrade to the latest iPhone operating system, called the iOS 4.

Why do you need to upgrade? Well, the new OS that Apple launched along with iPhone 4 has some amazing features. Multitasking, ability to create folders, creating playlists directly on iPod/iPhone, iBooks and much more.

Tempted, already? Check out Ars Technica’s super-comprehensive iOS 4 review. Probably the best one among hundreds of such articles out there.  (If you are an iPod touch user, check out Apple’s page on what the iOS 4 update means for you.)

7 Power Tips For Productive RSS News Feed Reading

I believe RSS is one of the best inventions of the last decade. RSS news feed reading has made consuming information on the web so much easier. You can read content from hundreds of blogs and sites from a single interface. No need to visit them separately.

RSS is extremely useful without a doubt. But once you get into the feed reading mode, it can be quite addictive too. You keep checking the feeds one after the other, visiting sites, sharing articles, and, of course, losing track of time in the process.

RSS feeds are meant to keep you informed, not make you unproductive. Here are seven useful tips, which, if implemented correctly, could make sure that you stay productive even without giving your favorite website RSS feeds a miss. Check them out.

1. Use Google Reader and/or FeedDemon

This is a no-brainer. If you are using any other feed reading tool other than Google Reader (web based, offficial Google RSS reader) or FeedDemon (a desktop based RSS news aggregator), I’d say not only you are missing on some cool features, but you are also spending more time than you should reading feeds.

Both Google Reader and FeedDemon come with a great set of features like shortcuts, quick sharing, panic button(in FeedDemon) etc, that enhance your feed reading productivity . You can even sync Google Reader with FeedDemon quite well, so you could use both of them too.

2. Make use of keyboard shortcuts

I could go on and on while praising the usage of keyboard shortcuts, especially when it comes to feed reading with Google Reader or FeedDemon. Other RSS readers also provide keyboard shortcuts so don’t be worried if you are not ready yet to make the switch. But using keyboard shortcuts is a must when it comes to productive RSS feed reading.

Once you learn and use keyboard shortcuts, you won’t need to toggle between the mouse and keyboard frequently. And you can’t imagine the time it saves in the long run. Web Worker Daily has a great tutorial on Google Reader keyboard shortcuts.

3. Create a ‘ Top Feeds ‘ Folder

If you are subscribed to a hundred website feeds then it’s never a good idea to read them all everyday. Instead, it’s better to create a folder named “top feeds” or anything similar, and group the most important feeds, the ones which you can’t miss, under it.

The top feeds folder can contain main news sites, major blogs which publish daily, and blogs of friends and kins if any. Be selective while putting feeds in this folder. Only select a site which really deserves your time and attention every single day.

4. Set aside time

I think it’s important to set aside time for RSS feed reading everyday. You don’t need to read them all at one go. You could select 2-3 time intervals of 15-20 minutes each, spread evenly throughout the day. This would ensure that you stay abreast with the latest news around the world.

Setting aside time ensures that feed reading activity won’t interfere with your other tasks. You have set specific time intervals when the RSS reader gets your attention and those should be the only times when you open it. This technique is a part of batch processing tasks, which made Darren Rowse 10 times more productive.

5. Hit the panic button when required

Don’t hesitate to hit the “Mark all as read” or the panic button when you’ve got too many unread feeds and can’t decide which ones to read. This could happen when you’ve been out for some days and come back to find an overloaded RSS reader.

It’s always better to start with a clean slate instead of wasting time trying to find what you’ve missed. Don’t worry about that. The web is too dynamic and the information will find you through Twitter, Facebook and other such means. You won’t stay ignorant. So don’t worry.

6. Save some feeds for weekends

Like creating a top feeds folder is important, it’s also essential that you save some feeds for the weekend. This means you won’t touch these feeds on weekdays, no matter what. If you have spare time, do stuff like reading a book, watching a TED video or reading feeds which aren’t a part of top feeds or weekend reading.

Setting aside certain feeds only for the weekends would ensure that you aren’t tempted to read them during the week, when you need to focus on other tasks. Plus, it also helps to reduce your obsession with RSS feeds.

7. Use Reeder 2.0 for iPhone

If you read feeds on the iPhone, which I am sure many of you do, then I’ll recommend using Reeder 2.0, a nifty app for the purpose. For other mobile platforms like Android, Windows Mobile and Blackberry, I think Google Reader’s native mobile interface should work fine. If you know of any cool apps for these devices then share them in the comments. I’d love to know.

Productive Working Hours: What Are Your Best Work Times?

Although most offices operate on 9 to 5 (or 8 to 6) working hours, not all workers work best on this timetable. Night owl workers prefer to burn the midnight oil, working late into the night when there are no distracting coworkers and their brain is at its sharpest.

I, on the other hand, prefer to follow regular business hours (roughly 9-6), so I’m available for dinner or drinks when my cubicle-dwelling friends get out of work. Plus, I like that feeling of accomplishment when the clock strikes noon and I can strike a bunch of items from my to-do list and break for lunch. When I’m still tethered to my computer at 7 or 8 at night, I feel antsy and unproductive (though I’ll do it if that’s what it takes to meet a deadline).

What about your working hours? What are your best work times? Why?