Notifications
Clear all

[Closed] Rotation Script – Background worker?

I have a project where we are visualizing a possible installation by Ned Kahn and one of his wind walls. I have “only” 14,000 panels, each with a scripted controller in a single (x) axis. Each panel finds the nearest point on a proxy surface, finds the barycentric coordinates, then UV, then the pixel grey scale value of the bitmap in the material to determine the rotation. I feed video of time lapse clouds and ripples on water into the bitmap and all the panels do their thing beautifully. The proxy surface is a cylinder but i’ve made it only 8 polygons which sped things up quite a bit.

I’m sure there are some inefficiencies in my script. I pieced it together from Bobo’s PFlow scripted operator. Maybe that is my clue right there; I should be doing this with PFlow. but now I’m a little stuck with this system and would like to make it work.

My questions are:

  1. How can I make the script more efficient?
  2. Could something like this use the BackgroundWorker to find rotations in parallel? None of the panels are interrelated or dependent on each other.

The variables are:
Me = the panel node. (self)
rotFactor = custom atrib on the proxy surface that sets the maximum rotation.
TargetSurface = the proxy surface with the animation/video playing.

theDistances = #()
  theBaryCoords = #()
  theFacesHit = #()
  thePositions = #()
  enabledState = me.modifiers[#Enabler].Custom_Attributes.Enabled
  
  if enabledState then 
  	(
  	for f = 1 to TargetSurface.numfaces do
  	(
  		theRay = Ray Me.pos -(getFaceNormal TargetSurface f)
  		theInt = IntersectRayEx TargetSurface theRay
  		if theInt != undefined then
  		(
  			append theDistances (distance Me.pos theInt[1].pos)
  			append theBaryCoords theInt[3]
  			append theFacesHit theInt[2]
  			append thePositions theInt[1].pos
  		)
  	)
  	if theDistances.count > 0 then
  	(
  		theMinDist = amin theDistances 
  		theIndex = findItem theDistances theMinDist
  		theBary = theBaryCoords[theIndex]
  		theUV = meshop.getMapFace TargetSurface 1 theFacesHit[theIndex]
  		theMapV1 = meshop.getMapVert TargetSurface 1 theUV.x
  		theMapV2 = meshop.getMapVert TargetSurface 1 theUV.y
  		theMapV3 = meshop.getMapVert TargetSurface 1 theUV.z
  		thePointUV = theMapV1 *theBary.x +  theMapV2 *theBary.y + theMapV3 *theBary.z
  		theMap = (TargetSurface.material.diffusemap.bitmap)
  		theColor = (getPixels theMap [theMap.width*(mod thePointUV.x 1), theMap.height - theMap.height*(mod thePointUV.y 1)] 1)[1]
  		theAngle = (
  				if theColor != undefined then
  				(theColor.r + theColor.g + theColor.b)/3/255.0 * rotFactor
  				else 0
  			)
  		--format "Angle: %
" theAngle
  		degtorad theAngle
  	)
  	else 0
  )
  else 0