Weighted LookAt constraint effect, with rotation limits
I've been trying to something working but I think I've reached the LIMITS of my current abilities. Ha ha.
Basically:
At a weight of zero, the target has no effect on the object, and the object can be rotated freely within its constraints. At a weight of 100, the object cannot be rotated manually, and follows the target (again, within the limits that have been set).
Here's what I've put together so far. To make it simpler to test, I've stuck a custom attribute on the target object to adjust the weight of the lookAt effect.
It gets generally the effect I am trying to accomplish, but the objects in the scene can still end up rotating beyond the desired limits. (Also, I tend to get this guy while testing out the scene: http://i.gyazo.com/350ae6bdc912780dc0421eaa9b1a7613.png
I would be really happy if someone could make this work! At the moment I can't afford a bounty, but a donation at some point in the future would not be out of the question.
----
EDIT:
Okay, I don't know why I was trying to put the script controller after the Euler XYZ controller. It's much simpler to do it this way. I've also removed the custom attribute from the target object as the "weighted" part should be relatively easy once I get the other part working. So, the test case to look at:
delete objects s = geoSphere name:"Target" radius:10 parentPoint = point pos:[50,50,0] lookObjects = for i = 1 to 5 collect ( rot = 15 pyramid width:10 depth:10 pos:[random 0 100, random 0 100, random 0 100] rotation:(eulerAngles (random rot -rot) (random rot -rot) (random rot -rot)) ) ( lookTarget = s for i = 1 to lookObjects.count do ( o = lookObjects[i] o.objectOffsetRot = eulerAngles 90 0 90 o.parent = parentPoint orc = o.rotation.controller = rotation_List() orc.setName 1 "Initial Rotation" p = point axisTripod:on box:on cross:off parent:o.parent transform:o.transform prc = p.rotation.controller = rotation_List() prc[2].controller = lookAt_Constraint lookAt_Vector_Length:0 --upNode_World:false --relative:true prc[2].controller.appendTarget lookTarget 100 prc.setActive 2 prc.weight = #(100, 50 + (i * 10)) orc = lookObjects[i].rotation.controller orc[2].controller = orientation_Constraint() orc[2].controller.appendTarget p 50 orc[3].controller = rotation_Script() orc[3].controller.addObject "lookRot" orc[2].controller ss = stringStream "" format "a = lookRot.value as eulerAngles\n" to:ss format "eulerAngles (amin (amax -15 a.x) 15) (amin (amax -30 a.y) 30) (amin (amax -45 a.z) 45)" to:ss orc[3].controller.script = ss orc[4].controller = euler_XYZ() orc.weight = #(0, 0, 100, 100) rotLimits = #(15, 30, 45) ax = #("x", "y", "z") for j = 1 to 3 do ( o[3][2][4][j].controller = float_Limit() uls = o[3][2][4][j][2][1].controller = float_Script() uls.addObject "scriptRot" orc[3] uls.script = "degToRad (" + rotLimits[j] as string + " - (scriptRot.value as eulerAngles)." + ax[j] + ")" lls = o[3][2][4][j][2][2].controller = float_Script() lls.addObject "scriptRot" orc[3] lls.script = "degToRad (-" + rotLimits[j] as string + " - (scriptRot.value as eulerAngles)." + ax[j] + ")" ) orc.setActive 4 ) )
--------
OLD VERSION:
global lookControls = attributes lookControls attribID:#(0x58ae9e8e, 0x5b3c35a0) ( parameters params rollout:RO_Look ( maxObjectTab type:#maxObjectTab tabSizeVariable:on str type:#float ui:sld_Str default:50 ) fn adjustLookWeights = ( c = this.maxObjectTab.count for i = 1 to c do ( n = this.maxObjectTab[i].node if classof n == point then ( val = (i as float / c) * this.RO_Look.sld_Str.value n.rotation.controller.weight[2] = val ) else n.rotation.controller.weight[2] = 100 - this.RO_Look.sld_Str.value ) ) rollout RO_Look "Look Controls" ( slider sld_Str "" pos:[18, 30] on sld_Str changed val do adjustLookWeights() ) ) delete objects s = geoSphere name:"Target" radius:10 parentPoint = point pos:[50,50,0] lookObjects = for i = 1 to 5 collect ( rot = 15 pyramid width:10 depth:10 pos:[random 0 100, random 0 100, random 0 100] rotation:(eulerAngles (random rot -rot) (random rot -rot) (random rot -rot)) ) ( lookTarget = s custAttributes.add lookTarget lookControls for i = 1 to lookObjects.count do ( o = lookObjects[i] o.objectOffsetRot = eulerAngles 90 0 90 o.parent = parentPoint orc = o.rotation.controller = rotation_List() orc[2].controller = euler_XYZ() for j = 1 to 3 do ( o[3][2][2][j].controller = float_Limit() o[3][2][2][j][2][1].value = degToRad 30 o[3][2][2][j][2][2].value = degToRad -30 ) orc.setName 1 "Initial Rotation" orc.setActive 2 p = point parent:o.parent transform:o.transform axisTripod:true prc = p.rotation.controller = rotation_List() prc[2].controller = lookAt_Constraint lookAt_Vector_Length:0 --upNode_World:false --relative:true prc[2].controller.appendTarget lookTarget 50 prc.setActive 2 prc.weight = #(100, 50 + (i * 10)) orc = lookObjects[i].rotation.controller orc[3].controller = orientation_Constraint() orc[3].controller.appendTarget p 50 orc[4].controller = rotation_Script() orc[4].controller.addObject "parent" o.parent orc[4].controller.addObject "initRot" orc[1].controller orc[4].controller.addObject "eulerRot" orc[2].controller orc[4].controller.addObject "lookRot" orc[3].controller orc[4].controller.addConstant "weights" orc[6] ss = stringStream "" format "a = (lookRot.value * inverse parent.transform.rotation) as eulerAngles\n" to:ss format "w2 = weights[2].value / 100\n" to:ss format "xL = radToDeg eulerRot[1].lower_Limit - (eulerRot[1].value * w2)\n" to:ss format "xU = radToDeg eulerRot[1].upper_Limit - (eulerRot[1].value * w2)\n" to:ss format "yL = radToDeg eulerRot[2].lower_Limit - (eulerRot[2].value * w2)\n" to:ss format "yU = radToDeg eulerRot[2].upper_Limit - (eulerRot[2].value * w2)\n" to:ss format "zL = radToDeg eulerRot[3].lower_Limit - (eulerRot[3].value * w2)\n" to:ss format "zU = radToDeg eulerRot[3].upper_Limit - (eulerRot[3].value * w2)\n" to:ss format "eulerAngles ((amin (amax xL a.x) xU) - initRot[1].value) ((amin (amax yL a.y) yU) - initRot[1].value) ((amin (amax zL a.z) zU) - initRot[1].value)" to:ss ss = ss as string orc[4].controller.script = ss orc.weight = #(100, 50, 0, 100) append lookTarget.maxObjectTab (nodeTransformMonitor node:o forwardTransformChangeMsgs:false) append lookTarget.maxObjectTab (nodeTransformMonitor node:p forwardTransformChangeMsgs:false) ) )
Comments
I modified the code a bit,
I modified the code a bit, getting rid of anything that's not pertinent, and hopefully making it a bit easier to work with.
----
EDIT:
In case anyone is not seeing where the trouble is coming in: when you manually rotate the pyramids, they can end up with rotation values outside the specified range.
...
I saw your thread on CGTalk. Your task I quite complex. DenisT will probably help you after all because this is his area.
I can only suggest this tutorial maybe can help you somehow
http://joleanes.com/tutorials/flippingless/flippingless_01.php
bga
Denis won't be able to help
Denis won't be able to help me because his solution is part of a proprietary script, so that leaves me looking elsewhere ><;