Away3D BezierPatch

image warp

I’ve been playing around the BezierPatch primitive in away3D recently. It works in a similar way to the bezier surface i created. Its quite easy to create some very interesting effects. The source for this is on wonder.fl so fork it and make it your own.

BezierPatch away3D – wonderfl build flash online


Warping Bitmaps with a Bezier Surface

image warp

If you have read my previous posts on drawTriangles, you will see that I love warping images. I decided to take this a bit further by using a Bezier surface. A bezier surface or bezier patch can warp a grid by using a set of control points. The control points in this example are the red circles, the grid can be seen by clicking the show grid checkbox. Try dragging the controls points to create your own warp or just sit back and watch the show.
There is also a method for doing this using away3d plus checkout this 3d surface built using nurbs.

This movie requires Flash Player 10

Update:
You can view the bezier surface in action on this client project I worked on recently. The surface was used to create chewing mouth animations from user’s facebook photos.


Flash 10 drawTriangles

image warp

Adobe introduced some new functions in the flash 10 drawing api for 3d support. One of them is drawTriangles. This enables bitmaps to be drawn to a 3d mesh. But it can also be used in 2d for skewing and warp effects. In a nutshell it allows you to define a shape and then map points of a bitmap to this shape. Click on the examples below to see the points of the rectangle warp to new positions. Here I’m defining the five points which make up the triangles and tweening the outside corners. The number of triangles and possibilities are infinite. This is great alternative to the infamous flash ide shape tween.
You can find some even better examples on wonder.fl. Just try searching for drawTriangles. Two of my favs are wonderwall and genie effect.

Random Warp

Bezier Minimise

This movie requires Flash Player 10

source for random warp

var _vertices:Vector.<Number >  = new Vector.<Number >   ;
var _indices:Vector.<int >  = new Vector.<int >   ;
var _uvtData:Vector.<Number >  = new Vector.<Number >   ;
var _image:BitmapData = new Foxy();
var border:Number = 0;
var _width:Number = stage.stageWidth;
var _height:Number = stage.stageHeight;
//define the triangles
_vertices.push(0, 0);
_vertices.push(_width, 0);
_vertices.push(_width/2, _height/2);
_vertices.push(0, _height);
_vertices.push(_width, _height);
_indices.push(1, 0, 2);
_indices.push(0, 2, 3);
_indices.push(1, 2, 4);
_indices.push(2, 3, 4);

//define the bitmap mapping to triangle points
_uvtData.push(0, 0);
_uvtData.push(1, 0);
_uvtData.push(0.5, 0.5);
_uvtData.push(0, 1);
_uvtData.push(1, 1);

stage.addEventListener(MouseEvent.CLICK, onClick);
function onClick(e=null):void
{

	var endVertices:Vector.<Number >  = new Vector.<Number >   ;
	endVertices.push(randNum, randNum);
	endVertices.push(_width-randNum, randNum);
	endVertices.push(stage.stageWidth/2, stage.stageHeight/2);
	endVertices.push(randNum, _height-randNum);
	endVertices.push(_width-randNum, _height-randNum);
	TweenMax.to(_vertices, 0.5, {endVector:endVertices, ease:Expo.easeOut, onUpdate:update});
}
function update():void
{
	graphics.clear();
	graphics.beginBitmapFill(_image);
	graphics.drawTriangles(_vertices, _indices, _uvtData);
	graphics.endFill();
}


source for bezier minimise

var _timeLine: TimelineMax;
var _vertices:Vector.<Number >  = new Vector.<Number >;
var _indices:Vector.<int >  = new Vector.<int >;
var _uvtData:Vector.<Number >  = new Vector.<Number >;
var _image:BitmapData = new Foxy();
var _width:Number = stage.stageWidth;
var _height:Number = stage.stageHeight;
//define the triangles
_vertices.push(startLT.x, startLT.y);
_vertices.push(startRT.x, startRT.y);
_vertices.push(startC.x, startC.y);
_vertices.push(startLB.x, startLB.y);
_vertices.push(startRB.x, startRB.y);
_indices.push(1, 0, 2);
_indices.push(0, 2, 3);
_indices.push(1, 2, 4);
_indices.push(2, 3, 4);

//define the bitmap mapping to triangle points
_uvtData.push(0, 0);
_uvtData.push(1, 0);
_uvtData.push(0.5, 0.5);
_uvtData.push(0, 1);
_uvtData.push(1, 1);

update();
function update():void
{
	_vertices[0]=startLT.x;_vertices[1]=startLT.y;
	_vertices[2]=startRT.x;_vertices[3]=startRT.y;
	_vertices[4]=startC.x;_vertices[5]=startC.y;
	_vertices[6]=startLB.x;_vertices[7]=startLB.y;
	_vertices[8]=startRB.x;_vertices[9]=startRB.y;

	graphics.clear();
	graphics.lineStyle(1, 0xFFFFFF);
	graphics.beginBitmapFill(_image);
	graphics.drawTriangles(_vertices, _indices, _uvtData);
	graphics.endFill();

}

stage.addEventListener(MouseEvent.CLICK, onClick);

function onClick(e=null):void
{

	if(_timeLine == null){
		var time:Number = 0.7;
		var ease:Function = Expo.easeInOut
		_timeLine = new TimelineMax({onUpdate:update});
		_timeLine.appendMultiple([
		TweenMax.to(startLT, time, {delay:0, bezierThrough:[{x:curveLT.x, y:curveLT.y}, { x:endLT.x, y:endLT.y}], ease:ease}),
		TweenMax.to(startRT, time, {delay:0, bezierThrough:[{x:curveRT.x, y:curveRT.y}, { x:endRT.x, y:endRT.y}], ease:ease}),
		TweenMax.to(startC, time, {delay:0, x:endC.x, y:endC.y, ease:ease}),
		TweenMax.to(startRB, time, {bezierThrough:[{x:curveRB.x, y:curveRB.y}, { x:endRB.x, y:endRB.y}], ease:ease}),
		TweenMax.to(startLB, time, {bezierThrough:[{x:curveLB.x, y:curveLB.y}, { x:endLB.x, y:endLB.y}], ease:ease})
		]);
	}else{
		if(_timeLine.reversed)
		_timeLine.play();
		else
		_timeLine.reverse();
	}

}