Recently has been studying how to transfer programmatic effects and animations from the Houdini to Touchdesigner, the previous period took the leapmotion to do development, oneself a person to entertain themselves also quickly play crazy.
Get inspired by a scene from a virtual interactive dance group in France today to design a simple, balanced-field effect that is mixed with repulsion and elasticity.
First look at what people are achieving on the stage:
Before applying, let's talk about the principles I see through this video.
The movement of the characters provides a positional information p, perhaps the motion of the group motion of the picture to extract the speed or acceleration information, here first do not do a complex discussion. Each point in the screen PT is calculated with the information position p provided above. Mainly produces two kinds of force, the first is based on the point P and PT position distance and direction, preset a certain threshold, within a radius range of the travel repulsion force, the force can be f = k * POW ((maxdistance-distance)/maxdistance, N). The closer the point P points to the Repulsion force, and by adjusting N, this repulsion can be more like the repulsion force of the magnetic field. Next is the second force, we can call it elasticity, the first record of each point pt of the original fixed position. Once the point receives the influence of the repulsion force and leaves the original point, this time the point is pulled back to the original point of the elasticity of the action, the force of the formula can directly use the elastic formula F = k * distance. The repulsion design is exponential, the elasticity still uses the linear equation, so the animation looks also more interesting.
The above analysis basically lays out the way to Houdini inside and Touchdesigner.
Let's talk about the methods implemented in Houdini.
In the Houdini can be directly in the SOP solver inside through the iteration of the frame number to achieve this effect, by creating a Vex node, respectively, read the target point location and the position of the previous frame point, the speed value to calculate the current frame each point position.
I extracted several key parameters to adjust the size of the force and the degree of elasticity of the soft and hard:
Damp-damping size, which can affect the speed of deceleration
Spring Index-Elastic index, the bigger the point, the harder it shakes.
Magnet Exponent-Used to adjust the relationship between repulsion size and distance
Magnet Scale-Adjust repulsion size
Max Distance-Position radius
Here is the Vex code for Houdini:
1 #pragmaLabel damp "damp"2 #pragmaLabel Springidx "Spring Index"3 #pragmaLabel Magexp "Magnet Exponent"4 #pragmaLabel Magnetscale "Magnet scale"5 #pragmaLabel maxDist "Max Distance"6 7 8 9 SOPTenSpringmagnet (floatDamp =0.9; One floatSpringidx =0.5; A floatMagexp =1; - floatMagnetscale =0.5; - floatMaxDist =1; the ) - { -Vector target = point (1,"P",0); -Vector rest = point (Geoself (),"Rest", ptnum); + - //get the spring force based on the rest position +Vector displace = rest-P; A atVector Springforce = displace *Springidx; - - //Get the magnet force from the target position -Vector magdist = P-Target; - floatDistance =length (magdist); - inVector Magnetforce =Set(0,0,0); - to if(Length (distance) <maxDist) { +Distance = Pow (fit (distance,0, MaxDist,1,0), magexp); -Magnetforce = Normalize (magdist) *distance; the } * $Vector MAINACC = Magnetforce * Magnetscale +Springforce;Panax Notoginseng -V + =MAINACC; thev = v *Damp; +P + =v; A}
The next is the application in Touchdesigner (TD), which is the focus:P
TD in the face of external hardware interface capability is very powerful, their own leapmotion before lent to colleagues to play, so here the first choice of the ipad above the OSC as the operating input, extracting the slider value can be adjusted in two directions.
Because my method still affects the points in the three-dimensional, and then casts the point rendering onto the plane. So the next step is to build the standard three-dimensional scene through Geo,light,camera and render.
Connect the GEO to the script sop after completion. Here, the TD is all-in-one and Python, so write the script what the direct use of Python is good. Before is Tscript, because TD and Houdini is the same origin of the development platform, many ideas and ideas are same strain, tscript like very much in the Houdini write expression feeling, but not like vex such perfect scripting language support, So it's all transferred directly to Python. The advantage is one step, what all use Python this glue to do well, at present is not very convenient place is TDU module is not particularly perfect, many vex in function can one step problem, to here need to revolve a lot of bends. In this case, I encountered the vector class normalize function How also out of the correct value, forever out of a None object, debug for a long time finally found out why or use the old way to calculate the model to get accurate norm. Perhaps the designer's idea is that we call other third-party modules in Python to solve these problems, but as a Houdini player, being Houdini really spoiled, except numpy,url,math these common modules, others are really not familiar with TvT
This part of the code is basically a train of thought in Vex, and write it again in Python. In fact, from these two functionally consistent but not the same environment code can be seen Houdini and TD difference.
1 #Me is the This DAT.2 # 3 #Scriptop is the OP which is cooking.4 5 defCook (scriptop):6 ImportMath7 8 #Use button to refresh the screen9button =op (ScriptOP.par.string2.eval ())Ten ifButton[0].eval ()! =0: One scriptop.clear () A - #get the controller data -Controlop =op (ScriptOP.par.string1.eval ()) theDamp = Float (controlop['Damp', 1]) -Springidx = Float (controlop['Spring Index', 1]) -Magexp = Float (controlop['Magnet Exponent', 1]) -Magscale = Float (controlop['Magnet Scale', 1]) +MaxDist = Float (controlop['Max Distance', 1]) - + #get the target position Atarget =op (ScriptOP.par.string0.eval ()) atTargetpos =TDU. Vector (target.points[0].x, Target.points[0].y, target.points[0].z) - - #Get the Me.points -MyPoints =scriptop.points - if notmypoints: - scriptop.copy (scriptop.inputs[0]) inMyPoints =scriptop.points - to forIinchRange (len (mypoints)): + #Get the current point position and rest position -Ptposition =TDU. Vector (mypoints[i].x, Mypoints[i].y, mypoints[i].z) theRestposition =mypoints[i].rest * $ #define the spring forcePanax NotoginsengDisplace = restposition-ptposition -Springforce = displace *Springidx the #print (Springforce) + A #define the magnet force theMagdirection =-(Targetpos-ptposition) +Magdistance =magdirection.length () -Magforce =TDU. Vector () $ ifMagdistance <maxDist: $Scaledist = 1-magdistance/maxDist -mode = MATH.SQRT (magdirection[0]*magdirection[0] + magdirection[1]*magdirection[1] + magdirection[2]*magdirection[2]) -Magdirection/=Mode theMagforce = magdirection * Scaledist *Magscale - Wuyi the #Combine all forces together -ACC = Magforce +Springforce Wu - #add to Vel and update the point position AboutMypoints[i].v[0] + =Acc[0] $MYPOINTS[I].V[1] + = acc[1] -MYPOINTS[I].V[2] + = acc[2] - -Mypoints[i].v[0] = mypoints[i].v[0] *Damp AMYPOINTS[I].V[1] = mypoints[i].v[1] *Damp +MYPOINTS[I].V[2] = mypoints[i].v[2] *Damp the -mypoints[i].x + =Mypoints[i].v[0] $Mypoints[i].y + = Mypoints[i].v[1] theMypoints[i].z + = Mypoints[i].v[2] the the return
Because TD is a platform for developing real-time interactive applications, timeliness is a key issue. A complete set of packaged into a program in 1280*720 resolution run up is basically the speed is at 30 frames a little more, the average per frame calculation time is 31.36ms, but script sop in scripts because each frame is calculated once, and the consumption of time per frame will be nearly 21ms or so, Altogether is 2/3 of the total duration. The number of points I use here is 30 * 48 = 1440. It is conceivable that the optimization of the script will greatly affect the effect of the program animation. This will have to be studied in the days to come.
Another notable point is that in this case I have shifted the speed of the movement to the chop in order to make it possible to change its color value by changing the speed of the movement. After changing the speed change value into a waveform, the conversion efficiency on this basis is very high, it is possible that this piece of built-in computational method has done a very large optimization, and later try to calculate directly in the waveform, in the Chop Channel to the point of the coordinates.
This article is here first.
Interaction between field forces and elasticity in Houdini and Touchdesigner