PDA

View Full Version : How to animate cubes orbiting joining and separating from a sphere?


ebdev
08-21-2009, 09:47 AM
Hi,

I'm trying to create a visual where cubes orbit a sphere joining and separating like a a big jigsaw puzzle. I really have no idea where to start with it and was hoping there would be a script out there to achieve it.

See this image (http://eddy.tickle.co.uk/3D/cubes.jpg) for what i want to do.

Thanks,

eb_devfile:///C:/DOCUME%7E1/ED4215%7E1.BEN/LOCALS%7E1/Temp/moz-screenshot.png

JHN
08-21-2009, 10:56 AM
Do they linearly fly in, over their local Z axis?
If so just animate all the boxes flying in the same time and then random offset the animation.

for o in selection do insertTime o.transform.controller -10 (random -50f 50f)

The random part is the min and max timeoffset
-10 is where to start putting in time, keep this below the actual keyframes or it will scale the animation.

Lookup insertTime in the helpfile.

-Johan

ebdev
08-21-2009, 11:02 AM
Hi JHN, thanks for your reply. The cubes should be rotating around the sphere in a orbiting fashion, occasionally slotting into the sphere and then coming out again and continuing their orbit.

Have you got some code which would do the moving of the cubes?

AkramParvez
08-21-2009, 01:05 PM
the image was interesting so quickly wrote this try it out and reply.
Just execute this script in a empty scene. with animation range of 300..


sph = (converttoPoly (sphere radius:100 segs:32))

for p = polyop.getNumFaces sph to 1 by -1 do polyOp.detachFaces sph #{p} delete:true asNode:true
delete sph
select objects
sel = selection as array
for i in sel do
(
RotValInv = inverse ((matrixFromNormal (polyop.getFaceNormal i 1)*i.transform) as quat)
i.pivot = i.center
in coordsys local i.rotation*=RotValInv
i.objectoffsetrot*=RotValInv
i.objectoffsetpos*=RotValInv
addmodifier i (shell innerAmount:10)
with animate on
(
at time 150 in coordsys local i.pos.z += 150
at time 300 in coordsys local i.pos.z -= 150
)
)

$.pivot = [0,0,0]
with animate on
(
at time 150 rotate $ (angleaxis 720 [0,0,1])
)

for o in sel do insertTime o.transform.controller -5 (random -299f 299f)
for o in sel do reverseTime o.transform.controller (random -299f 299f) (random -299f 299f)

ebdev
08-21-2009, 01:38 PM
wow that's exactly what i wanted, thanks and well done on a clever bit of code!

AkramParvez
08-21-2009, 04:41 PM
thanks man....

ebdev
09-02-2009, 11:22 AM
Hi sorry to bring this post back up again the project was delayed for a bit, the animation doesn't loop properly, how can I make it complete a loop (i'm using 300 for the length) ?

Thanks.

AkramParvez
09-02-2009, 12:14 PM
Hi again, there is a small work around for this. All u need to do is to set the last frame value equal to the first frame.
for o in sel do
(
at time 0 pos = o.transform
animate on (at time 300 o.transform = pos)
)

ebdev
09-02-2009, 01:16 PM
Thanks for your speedy reply, where should I put the code?

AkramParvez
09-02-2009, 03:05 PM
put that in the last line of the earlier code or select all the cubes run this:

sel = selection as array
for o in sel do
(
at time 0 pos = o.transform
animate on (at time 300 o.transform = pos)
)

ebdev
09-02-2009, 04:50 PM
ah right ok great, thanks again!

tasiek
09-02-2009, 04:59 PM
could you show us finished animation ? my approach would be in some particle system... I just wonder what U will get from scripting

peace!

JHN
09-02-2009, 05:22 PM
Well, if you run the script Akram posted, you don't have to wait for the rendering... :thumbsup:

-Johan

ebdev
09-03-2009, 08:36 AM
Yeah sure, it's not actually me that's doing the 3D work, I just came up with the concept and am supplying the script. It's to demonstrate cloud hosting for the company I am working at at the mo. I'll post a vid once it's complete.

Have to say this is a great forum, it's rare to find one so active!

ebdev
09-03-2009, 10:56 AM
Ok I've just tested it and there is still a little jump when frame 300 is hit, does this happen on your version? I need it to loop so that it never completey reforms and is continually active.

AkramParvez
09-03-2009, 11:04 AM
yes there will be a little jump in the end.

ebdev
09-08-2009, 01:12 PM
Ok I've had a good hard look at the code and believe I understand whats going on and what bits do what. I've narrowed the jumping problem down to the following two loops (i've expanded the loops so i can play around with them) they randomise the positions but they never return to the original position:


/* For all faces in selection - Randomise the keyframes */
for o in sel do (

insertTime o.transform.controller -5 (random -299f 299f)

)
/* For all faces in selection - Randomise the keyframes in reverse */
for o in sel do (

reverseTime o.transform.controller (random -299f 299f) (random -299f 299f)

)

Is there a way to record the positions from when they started and then place them back at the end of the loop?

AkramParvez
09-08-2009, 03:59 PM
sel = selection as array
for o in sel do
(
at time 0 pos = o.transform
animate on (at time 300 o.transform = pos)
)

Is there a way to record the positions from when they started and then place them back at the end of the loop?

this code does record position at 0 and places at end, but i'm getting the same jump in the end no idea why.

ebdev
09-08-2009, 04:41 PM
Yeah i noticed that, that does set the positions correctly. With you setting the face keyframe times randomly is it possible there is no room in the sequence left for faces to return to their original position? or maybe there is a conflict between the rotation of the faces and the new positions created by the random keyframe times? Like the correct position of a face is at the end of the sequence but the keyframe created by the random time changes has moved it so close that it appears to jump rather than tweening nicely?

PiXeL_MoNKeY
09-08-2009, 05:02 PM
Set your time 0-299, and keep the current animation and you should be fine. The jump is probably caused by the double up on 300 and frame 0. You should never have the same frame back to back in a looping animation. The matching frame should always be animation end +1 frame.

-Eric

ebdev
09-09-2009, 02:49 PM
Hi PiXeL_MoNKeY, thanks for the tip, unfortunately setting the time to 299 hasn't fixed the problem. Do i need to set the time to 299 in the code? Or 300 in the time settings and 299 in the code?

eek
09-09-2009, 02:56 PM
Hi PiXeL_MoNKeY, thanks for the tip, unfortunately setting the time to 299 hasn't fixed the problem. Do i need to set the time to 299 in the code? Or 300 in the time settings and 299 in the code?

I think Pixel means, run your code from 0-300, but play your animation from 0 -299.

PiXeL_MoNKeY
09-09-2009, 03:22 PM
The original problem you were having is that the code wasn't designed to loop. The modified code he provided should give you the ability to loop, have you implemented the modified code?

-Eric

ebdev
09-09-2009, 04:34 PM
Yeah I added the modifications, my code (with eeks suggestion aswell) is now as follows (comments were from me so i could work it out):


/* Create sphere and convert to poly */
sph = (converttoPoly (sphere radius:100 segs:32))

/* Detach faces of sphere */
for p = polyop.getNumFaces sph to 1 by -1 do polyOp.detachFaces sph #{p} delete:true asNode:true
delete sph
select objects
sel = selection as array

/* For each face of the sphere do... */
for i in sel do
(
/* Get inverse rotation value */
RotValInv = inverse ((matrixFromNormal (polyop.getFaceNormal i 1)*i.transform) as quat)

/* Set pivot var to center of face */
i.pivot = i.center

/* In local coord system, set rotation to inverse */
in coordsys local i.rotation*=RotValInv

/* Store inverse rotation offset */
i.objectoffsetrot*=RotValInv
i.objectoffsetpos*=RotValInv

/* Extrude */
addmodifier i (shell innerAmount:10)

with animate on
(
/* From frame 0-150 move faces +20 from the center */
at time 150 in coordsys local i.pos.z += 20

/* From frame 150-300 move faces -20 from the center to original position */
at time 299 in coordsys local i.pos.z -= 20
)

)
/* Create rotation matrix of 0 */
$.pivot = [0,0,0]

/* From frame 0-150 rotate faces 720 degress around the z axis (rotate twice) */
with animate on
(
at time 299 rotate $ (angleaxis 720 [0,0,1])
)

/* For all faces in selection (Randomise the positions) */
for o in sel do (

insertTime o.transform.controller -5 (random -299f 299f)

)
for o in sel do (

reverseTime o.transform.controller (random -299f 299f) (random -299f 299f)

)

/* Set selection as array */
sel = selection as array

/* For faces in selection do... */
for o in sel do
(
/* At frame 0 set pos to face transform */
at time 0 pos = o.transform

/* Set face transform to pos (original position) at frame 299) */
animate on (at time 299 o.transform = pos)
)


Quite possible i've missed something :)

AkramParvez
09-09-2009, 06:07 PM
You can try this, just run this code:

sph = (converttoPoly (sphere radius:100 segs:32))

for p = polyop.getNumFaces sph to 1 by -1 do polyOp.detachFaces sph #{p} delete:true asNode:true
delete sph
select objects
sel = selection as array
for i in sel do
(
RotValInv = inverse ((matrixFromNormal (polyop.getFaceNormal i 1)*i.transform) as quat)
i.pivot = i.center
in coordsys local i.rotation*=RotValInv
i.objectoffsetrot*=RotValInv
i.objectoffsetpos*=RotValInv
addmodifier i (shell innerAmount:10)
with animate on
(
at time 150 in coordsys local i.pos.z += 150
at time 300 in coordsys local i.pos.z -= 150
)
)

$.pivot = [0,0,0]
with animate on
(
at time 150 rotate $ (angleaxis 720 [0,0,1])
)

for o in sel do insertTime o.transform.controller -5 (random -299f 299f)
for o in sel do reverseTime o.transform.controller (random -299f 299f) (random -299f 299f)

then set ur animation range to -300 to 600 and then re-scale time in time configuration to 0 299 and finally run this code

sel = selection as array
for o in sel do
(
at time 0 pos = o.transform
animate on (at time 300 o.transform = pos)
)
This should loop the animation properly and the result will be little different.

ebdev
09-10-2009, 08:49 AM
Ok that's working great now thanks, I've just got to make a few tweaks to some of the frames to make the transition a little smoother but then i think we're there!

ebdev
09-10-2009, 01:16 PM
or so i thought...I've changed the distance the cubes come out to 50 and now I can't get rid of the jump *sigh*, it was less noticeable when the distance was 150.

CGTalk Moderation
09-10-2009, 01:16 PM
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.