Aearon

04-01-2006, 07:32 AM

well, since talked to eek and mark about this stuff a while ago... i had to give it a shot myself now that i had some time ;)

this is a simple function that takes 4 helpers as input, and creates a point that is constrained to the bezier curve defined by these for helpers

note that this only works with exactly 4 points (a special case of a bezier curve which is faster to calculate than a general bezier), 4 points is what makes sense for spine setups as well as probably for curvy limbs my opinion.

here's (http://astronomy.swin.edu.au/%7Epbourke/curves/bezier/) where i got the formula from (contain's c++ code that can easily be translated into maxscript or a max expression)

hope this helps anyone out there!

to test it, select 4 objects and run the script

it's very fast already, but if anyone has an idea how to speed up the script controller itself, i'm all ears

fn

createBezierPoint

points -- array of 4 objects to define the curve (1 and 4 are the control points, 2 and 3 are control handles)

u: -- position of the point along the curve (value range 0 to 1), this can either be a float value or a float subanim

=

(

try

(

if points.count != 4 then throw ("need 4 points, got " + points.count as string)

local theP = point centerMarker:true axisTriped:false cross:false box:false size:0 constantScreenSize:false drawOnTop:false

local cnt = position_script()

theP.pos.controller = cnt

for i=1 to 4 do

(

if not isValidNode points[i] then throw ("point " + i as string + " not a valid node")

cnt.addNode ("p" + i as string) points[i]

)

case (classof u) of (

float: cnt.addConstant "mu" u

subAnim: if classof u.value == float then cnt.addTarget "mu" u else throw ("u subAnim value needs to be a float")

default: throw ("invalid value for 'u', need either float or float subanim, got " + (classof u) as string)

)

cnt.setExpression \

"p1 = p1.transform[4]

p2 = p2.transform[4]

p3 = p3.transform[4]

p4 = p4.transform[4]

mum1 = 1 - mu

mum13 = mum1^3

mu3 = mu^3

(mum13*p1 + 3*mu*mum1^2*p2 + 3*mu^2*mum1*p3 + mu3*p4)"

return theP

)catch(throw())

)

try(for i=0.0 to 1.0 by 0.1 do createBezierPoint (selection as array) u:i)catch(format "%\n" (getCurrentException()))

this is a simple function that takes 4 helpers as input, and creates a point that is constrained to the bezier curve defined by these for helpers

note that this only works with exactly 4 points (a special case of a bezier curve which is faster to calculate than a general bezier), 4 points is what makes sense for spine setups as well as probably for curvy limbs my opinion.

here's (http://astronomy.swin.edu.au/%7Epbourke/curves/bezier/) where i got the formula from (contain's c++ code that can easily be translated into maxscript or a max expression)

hope this helps anyone out there!

to test it, select 4 objects and run the script

it's very fast already, but if anyone has an idea how to speed up the script controller itself, i'm all ears

fn

createBezierPoint

points -- array of 4 objects to define the curve (1 and 4 are the control points, 2 and 3 are control handles)

u: -- position of the point along the curve (value range 0 to 1), this can either be a float value or a float subanim

=

(

try

(

if points.count != 4 then throw ("need 4 points, got " + points.count as string)

local theP = point centerMarker:true axisTriped:false cross:false box:false size:0 constantScreenSize:false drawOnTop:false

local cnt = position_script()

theP.pos.controller = cnt

for i=1 to 4 do

(

if not isValidNode points[i] then throw ("point " + i as string + " not a valid node")

cnt.addNode ("p" + i as string) points[i]

)

case (classof u) of (

float: cnt.addConstant "mu" u

subAnim: if classof u.value == float then cnt.addTarget "mu" u else throw ("u subAnim value needs to be a float")

default: throw ("invalid value for 'u', need either float or float subanim, got " + (classof u) as string)

)

cnt.setExpression \

"p1 = p1.transform[4]

p2 = p2.transform[4]

p3 = p3.transform[4]

p4 = p4.transform[4]

mum1 = 1 - mu

mum13 = mum1^3

mu3 = mu^3

(mum13*p1 + 3*mu*mum1^2*p2 + 3*mu^2*mum1*p3 + mu3*p4)"

return theP

)catch(throw())

)

try(for i=0.0 to 1.0 by 0.1 do createBezierPoint (selection as array) u:i)catch(format "%\n" (getCurrentException()))