User137

01-11-2007, 11:07 PM

Came to thinking ways to make 3D animation smooth and came across with bezier curve. Had no experience on it before and thought it would be so overly complicated and all... However, there was nice animated gifs at wiki that explained it all to my simple mind that cannot understand the formulas :lol:

Anyway, i can already imagine so many different uses to this, maybe you do too.

http://en.wikipedia.org/wiki/B%C3%A9zier_curve

Screenshot: http://img216.imageshack.us/img216/1517/bezierxq3.jpg

To my surprise, code became very very simple and seems very fast too! No sqrt or power functions needed. Here's code that i now have on my Next3D engine:

// Define these 2 functions overloaded

type

TVector3f = record x,y,z: single; end;

PVector3f = ^TVector3f;

// delta = 0..1

function nxBezier(const a,b: PVector3f; const delta: single): TVector3f;

var d1: single;

begin

d1:=1-delta;

result.x:=a.x*d1+b.x*delta;

result.y:=a.y*d1+b.y*delta;

result.z:=a.z*d1+b.z*delta;

end;

// Always call with count >= 2

function nxBezier(p: array of TVector3f; const count: word; const delta: single): TVector3f;

var v: array of TVector3f; i: integer;

begin

if count>2 then begin

setlength(v,count-1);

for i:=0 to count-2 do

v[i]:=nxBezier(@p[i],@p[i+1],delta);

result:=nxBezier(v,count-1,delta);

end else if count=2 then

result:=nxBezier(@p[0],@p[1],delta);

end;

Enjoy!

Edit: Still, maybe for animations some other formula would fit better? Something that doesn't approximate as much to remove that much details...

Thought of another function came to mind, when 3 points in animation frame are given (previous vertex, current and next), start curve from half way between time frames. That way details remain not much changed and is possible to make faster function specially for this. But still this wouldn't reach the "top" of each keyframe.

Anyway, i can already imagine so many different uses to this, maybe you do too.

http://en.wikipedia.org/wiki/B%C3%A9zier_curve

Screenshot: http://img216.imageshack.us/img216/1517/bezierxq3.jpg

To my surprise, code became very very simple and seems very fast too! No sqrt or power functions needed. Here's code that i now have on my Next3D engine:

// Define these 2 functions overloaded

type

TVector3f = record x,y,z: single; end;

PVector3f = ^TVector3f;

// delta = 0..1

function nxBezier(const a,b: PVector3f; const delta: single): TVector3f;

var d1: single;

begin

d1:=1-delta;

result.x:=a.x*d1+b.x*delta;

result.y:=a.y*d1+b.y*delta;

result.z:=a.z*d1+b.z*delta;

end;

// Always call with count >= 2

function nxBezier(p: array of TVector3f; const count: word; const delta: single): TVector3f;

var v: array of TVector3f; i: integer;

begin

if count>2 then begin

setlength(v,count-1);

for i:=0 to count-2 do

v[i]:=nxBezier(@p[i],@p[i+1],delta);

result:=nxBezier(v,count-1,delta);

end else if count=2 then

result:=nxBezier(@p[0],@p[1],delta);

end;

Enjoy!

Edit: Still, maybe for animations some other formula would fit better? Something that doesn't approximate as much to remove that much details...

Thought of another function came to mind, when 3 points in animation frame are given (previous vertex, current and next), start curve from half way between time frames. That way details remain not much changed and is possible to make faster function specially for this. But still this wouldn't reach the "top" of each keyframe.