Rotation about one axis (object space)


#1

I’m looking a right solution for rotation (in object space) about one axis (in this case X-Axis)?
Rotation of planes are controlled by “percent” value of “Master” helper.
Considering the problem that is described in this thread
http://forums.cgsociety.org/showthread.php?f=98&t=1032312&highlight=benchmark
it is difficult to decide which method (or combinations of methods) is best suited for this.
(script controller , param wire , expression , constraint , expose tm).
By the way, in the next example i used only 3 planes only for test, but there be more.

(
  -- example creation code 
  	delete objects
  	local p1 = Plane name:"RedPlane" pos:[0,0,0] wirecolor:red length:10 width:10
  	local p2 = Plane name:"OrangePlane" pos:[0,10,0] wirecolor:orange length:10 width:10
  	local p3 = Plane name:"YellowPlane" pos:[0,20,0] wirecolor:yellow length:10 width:10
  	local master = point name:"Master_helper" axistripod:on cross:off box:on size:10 wirecolor:blue
  	local planeArr = #(p1,p2,p3)
  	local meshArr = for p in planeArr collect (snapshotasmesh p)
  	local testCA = attributes limitRot
  	(
  		parameters PRM rollout:roll
  		(
  			rotPercent type:#float ui:spn_percent default:0.0
  			maxAngle type:#float ui:spn_maxAngle default:120.0
  			nodes type:#MaxObjectTab tabSize:0 tabSizeVariable:on
  		)
  		rollout roll "Parameters"
  		(
  			spinner spn_percent "Percent [%]: " fieldwidth:60 Height:16 Align:#Left Type:#float Range:[0,100,0]
  			spinner spn_maxAngle "maxAngle [°]:" fieldwidth:60 Height:16 Align:#Left Type:#float Range:[0,360,120]
  		)
  	)
  	caMod = EmptyModifier name:"TestMod"
  	custAttributes.add caMod testCA
  	seed 123
  	for i = 1 to planeArr.count do
  	(
  		planeArr[i].objectOffsetPos.y += 5
  		append caMod.nodes (NodeTransformMonitor node:planeArr[i])
  		in planeArr[i] (point name:(planeArr[i].name+"_helper") wirecolor:green axistripod:on cross:off box:off centermarker:on size:8 transform:(planeArr[i].transform))
  		planeArr[i].pos = [random -30 30, random -30 30, random 0 50] 
  		planeArr[i].dir = [random -1.0 1.0, random -1.0 1.0, random -1.0 1.0] 	
  	)
  	addmodifier master caMod
  	planeArr.parent = master
  )

The illustrations below shows what i what I want to accomplish.
#1

#2


#2

do you want to have percent and maxAngle properties animatable?


#3

Yes, of course.
I had a problem when you rotate the Master helper and try to change percent value rotation of the planes is wrong.
I forget to add

rotPercent type:#float ui:spn_percent default:0.0 animatable:on 
 maxAngle type:#float ui:spn_maxAngle default:120.0 animatable:on

Thanks Denis for reply.


#4

here is how i would do it:


 delete objects
 set redraw off 
 	
 master = point name:"Master_helper" axistripod:on cross:off box:on size:10 wirecolor:blue isselected:on
 limitRot = attributes limitRot
 (
 	parameters params rollout:params
 	(
 		percent type:#float ui:ui_percent default:0.0 
 		limit type:#float ui:ui_limit default:120.0
 	)
 	rollout params "Parameters"
 	(
 		spinner ui_percent "Percent (%): " fieldwidth:46 type:#float range:[0,100,0]
 		spinner ui_limit "Maximum Angle: " fieldwidth:46 type:#float range:[0,360,120]
 	)
 )
 custAttributes.add master limitRot baseobject:on
 master.percent.controller = bezier_float()
 master.limit.controller = bezier_float()
 
 in master 
 (
 	p1 = Plane name:"p1" wirecolor:red length:10 width:10 lengthsegs:1 widthsegs:1
 	p2 = Plane name:"p2" wirecolor:orange length:10 width:10 lengthsegs:1 widthsegs:1
 	p3 = Plane name:"p3" wirecolor:yellow length:10 width:10 lengthsegs:1 widthsegs:1
 )
 p1.pivot.y = p1.min.y
 p2.pivot.y = p2.min.y
 p3.pivot.y = p3.min.y
 
 s = float_script()
 s.addtarget "percent" master.percent.controller
 s.addtarget "limit" master.limit.controller
 s.setexpression "percent*(degtorad limit)*0.01"
 
 for p in #(p1,p2,p3) do
 (
 	p.pos = random [-30,-30,0] [30,30,50] 
 	p.dir = random [-1,-1,-1] [1,1,1] 
 
 	c = p.rotation.controller = rotation_list()
 	f = c.available.controller = createinstance euler_xyz
 	c.active = 2
 	f[1].controller = s
 )
 
 set redraw on
 

so i would use float_script


#5

I try your code and is really cool.
But maximum angle is a limit. Planes need stop to rotate when rich 120° e.i
whent first rich 120° then the other one start to rotate etc.

What about memory leak if i use about a hundred planes or more.
Is it possible to perform all this without using script controller.
I mean only using some funcions that will be stored inside CA or scripted plugin, and plane transforms and other info stored inside ParamBlock.


#6

what does percent do?


#7

i try something like this but without luck.
On #2 illustration i wrote for what is percent.
delete objects
set redraw off

master = point name:“Master_helper” axistripod:on cross:off box:on size:10 wirecolor:blue isselected:on
limitRot = attributes limitRot
(
parameters params rollout:params
(
percent type:#float ui:ui_percent default:0.0
limit type:#float ui:ui_limit default:120.0
)
rollout params “Parameters”
(
spinner ui_percent "Percent (%): " fieldwidth:46 type:#float range:[0,100,0]
spinner ui_limit "Maximum Angle: " fieldwidth:46 type:#float range:[0,360,120]
)
)
custAttributes.add master limitRot baseobject:on
master.percent.controller = bezier_float()
master.limit.controller = bezier_float()

in master
(
p1 = Plane name:“p1” wirecolor:red length:10 width:10 lengthsegs:1 widthsegs:1
p2 = Plane name:“p2” wirecolor:orange length:10 width:10 lengthsegs:1 widthsegs:1
p3 = Plane name:“p3” wirecolor:yellow length:10 width:10 lengthsegs:1 widthsegs:1
)
p1.pivot.y = p1.min.y
p2.pivot.y = p2.min.y
p3.pivot.y = p3.min.y

fn addCtrl p =
(
local s = float_script()
s.addtarget “percent” master.percent.controller
s.addtarget “limit” master.limit.controller
expStr = “koef = .03*limit
"
expStr += “case of (
"
expStr += “(percent == 0): 0
"
expStr += “(percent > (”+(p-1) as string+”/3)*100 and percent <= (”+p as string+”/3)100): degtorad (percentkoef)
"
expStr += “(percent > (”+p as string+"/3)100): degtorad limit
)"
s.setexpression expStr --"percent
(degtorad limit)"
s
)
plnArr = #(p1,p2,p3)
for p = 1 to plnArr.count do
(
plnArr[p].pos = random [-30,-30,0] [30,30,50]
plnArr[p].dir = random [-1,-1,-1] [1,1,1]

c = plnArr[p].rotation.controller = rotation_list()
f = c.available.controller = createinstance euler_xyz
c.active = 2
f[1].controller = (addCtrl p)

)

set redraw on


#8

let’s do it with by everything forgotten float_expression controller. it has to be fast enough, and it doesn’t leak as script controllers


 delete objects
set redraw off 
(	
	master = point name:"master" axistripod:on cross:off box:on size:10 wirecolor:blue isselected:on
	limitRot = attributes limitRot
	(
		parameters params rollout:params
		(
			spin type:#float ui:ui_spin default:0.0 
			limit type:#float ui:ui_limit default:60.0
		)
		rollout params "Parameters"
		(
			spinner ui_spin "Spin: " fieldwidth:54 type:#integer range:[0,1e9,0]
			spinner ui_limit "Maximum Angle: " fieldwidth:54 type:#integer range:[0,360,60]
		)
	)
	custAttributes.add master limitRot baseobject:on
	master.spin.controller = bezier_float()
	master.limit.controller = bezier_float()

	for k=1 to 100 do
	(
		in master (p = rectangle name:("p" + (formattedprint k format:"03d")) wirecolor:yellow length:5 width:5)
		p.pivot.y = p.min.y
		p.pos = [0,(k-1)*0.1,0]

		c = p.rotation.controller = rotation_list()
		f = c.available.controller = createinstance euler_xyz
		c.active = 2
		
		s = f[1].controller = float_expression()
		s.addscalarconstant "id" (k-1)
		s.addscalartarget "spin" master.spin.controller
		s.addscalartarget "limit" master.limit.controller
		s.setexpression "(min(limit,max(0,spin - (limit*id))))*pi/180."
		s
	)
)
set redraw on
 

it’s an old school is not it? :wink:


#9

it’s an old school is not it? :wink:

This is it “(min(limit,max(0,spin - (limit*id))))*pi/180.” :beer:
Secret ingredient. Amazing!!!
And for all old school guys, again:beer:.
Denis, thanks a lot.


#10

This thread has been automatically closed as it remained inactive for 12 months. If you wish to continue the discussion, please create a new thread in the appropriate forum.