Rotational Oscillation

Hello everyone!

I’m trying to get a mesh to oscillate on a local axis pivot. I’m just not sure how to set up the if/then statement.

The code below works if I use key events (if(map[“d”] {}), but stops working when I try to reference the pivot axis.

if (pivot.rotate.y <= Math.PI) {
angle = Math.PI/252;
pivot.rotate(BABYLON.Axis.Y, angle, BABYLON.Space.LOCAL);
}
else {
angle = **-**Math.PI/252;
pivot.rotate(BABYLON.Axis.Y, angle, BABYLON.Space.LOCAL);

How would I get the pivot to only rotate 180 degrees, stop, then rotate negative 180 degrees in a loop?

Again, I’m just not sure how to set up the if/then statements. I found an example of an oscillating disc (here), but it doesn’t seem to be done using rotation around an axis.

Thanks!

Hi A!

Here’s a playground with 3 different 180-degree “rotation oscillation” routines… tilter1, tilter2, and tilter3.

https://www.babylonjs-playground.com/#92EYG#73

Select any one of three… in lines 50-52. Currently, imprecise logarithmic tilter1 is in-use.

Line 55 shows how to STOP the animators. I have line 55 wrapped in a setTimout, so it stops after 10 secs. You may want to stop your anims… with a keypress.

You can probably determine how to START them… with a keypress, too. If not, just ask below, in this thread.

I hope I have been helpful, here. Have a fine weekend… be well.

Extra stuff: The reason your animator was being grumpy… is because the .rotate() method of rotating a mesh… uses a special property called .rotationQuaternion… which stores its values in a Quaternion-class structure (a sometimes difficult-to-understand 4-value structure). The .rotate() call/function actually ADDS/CREATES the .rotationQuaternion property on/to the mesh. (it doesn’t exist by-default.) After ,rotationQuaternion is created… the more-standard Euler 3-part .rotation property… is mostly ignored by BabylonJS systems. This is normal functionality and it has many reasons for operating in this manner.

THUS, after you use/call .rotate()… it is not-so-easy to read the VALUE of the mesh’s rotational-orientation anymore. Often, you must use mesh.rotationQuaternion.toEulerAngles() as seen in lines 43 and 45.

Tilter 1 and 2 are Euler rotation routines (using .rotation property), and tilter 3 is a Quaternion rotation routine (using .rotationQuaternion property).

Based on the PG you referenced https://www.babylonjs-playground.com/#92EYG#74

1 Like

Thanks @Wingnut and @JohnK for the examples and the explanations! I worked all day yesterday trying to figure this out with no success, so your help is most appreciated!

Hope you both have a great weekend :+1:

2 Likes
	var n = 120; //number of frames for 180 deg rotation
    var deltaTheta =  Math.PI / n; //change in angle per frame
	var deltaDistance = discRadius * deltaTheta; //distance travelled along the line in one frame
	
	var theta = 0;
	var direction = 1; //forward

	scene.registerBeforeRender(function () {
		theta += deltaTheta; //increment rotation angle
		disc.rotation.z = Math.sign(Math.sin(theta)) * theta; //set rotation to incremented angle
		
	});

Oooh, that’s a NICE one, John! Cooooool. I’m gonna steal that. Double bookmarking. :slight_smile:

See that mis-coloring at the end of line 19 (in the PG itself)… caused by the slashes? That’s sort of new, isn’t it? Something different about the editor or something.

BTW, I’m using FireFox 68.7.0esr these days, John… and the “lost flashing cursor in the forum editor” problem… seems to be gone, here. Finally!

It seems to me that you once spoke-of having the same issue.

All in all, I hope you and others are healthy/well. Thx for the nice windshield wiper motor animation formula! Party on!

As I’m learning programming, it seems that every breakthrough leads to a new challenge.

So, here’s a follow up question if you don’t mind:

As an object rotates (-Math.PI/2), how would I get a parented object to move with each degree change in the rotation? The code below works, but translation only happens once when the condition is met, which makes sense. I tried a “while” statement, but it crashed. Apparently, “while” statements don’t work well with Babylon.js?

else if (pivot.rotation.y < -Math.PI/2) {
step *= -1;
carBody.translate(BABYLON.Axis.X, 0.2, BABYLON.Space.LOCAL);
carBody.translate(BABYLON.Axis.Z, 0.2, BABYLON.Space.LOCAL);
carBody.rotate(BABYLON.Axis.Y, Math.PI/252, BABYLON.Space.WORLD);

};

A playground would be useful.

Of course, here it is:

https://www.babylonjs-playground.com/#VAVC1V

I’ve been kind of reverse engineering the car driving example to see what’s possible. If you use the “d” key, the body move correctly, but the right “arm” keeps spinning. The goal is to get things to move the way they do with the “d” key, but with the oscillation movement you helped me generate earlier (left “arm”). The arm should continuously move, but when it rotates backwards (<Math.PI/2), it should move the body and head forward. If you’re curious, I’m trying to build a digital character that uses its limbs to move around autonomously.

Also, I used the code @Wingnut provided, but I really don’t understand the difference between using that code before scene rendering (var armAnimation = scene.onBeforeRenderObservable.add(armMove);), or after scene rendering (scene.registerAfterRender(function()). It seems to work both ways.

1 Like

https://www.babylonjs-playground.com/#HH1U5#88

There are some odd animation routines at top of THAT playground.

Now go down to lines 122-138… notice how they are called in “time-sequences”… almost like an “event generator” or “scheduler”.

All those little animation functions at the top… are dependent upon… BABYLON.Animation.CreateAndStartAnimation… a fun and powerful quick-animator system.

Let’s look at one…

BABYLON.Animation.CreateAndStartAnimation('at4', this, 'rotation.' + axis, speed, 120, this.rotation[axis], this.rotation[axis]+rads, 0, ease);

Right AFTER theease parameter… you an add the name of a “whenThisAnimationEnds” function… like this…

BABYLON.Animation.CreateAndStartAnimation('at4', this, 'rotation.' + axis, speed, 120, this.rotation[axis], this.rotation[axis]+rads, 0, ease, onAnimEnded);

A function called onAnimEnded() must be declared PRIOR TO calling that animator… and then when this animation has ended… onAnimEnd() function is called.

When building sequences of animations… one after another (such as walking)… it is often important to know WHEN one animation has finished… to you know when to start another (without need to use scene timers like lines 122-138).

OnSpinToEnd(), onSpinEnd(), etc… good “hey, it’s finished its spin” helpers… which are often called “callback functions”.

The little animation functions at the top… are often called “overloads”… as they are modifying Babylon.AbstractMesh class. They could also be used to overload MESH class, or a camera class, or a light class.

Some folks say overloading is a bad idea, because it creates non-standard base-classes that cannot be trusted to operate correctly if “re-used” somewhere. Some say… use them cautiously and don’t re-use them in other projects without careful consids, and all will be fine.

Either way, its another way of animating… and it introduces us to the handy CreateAndStartAnimation (with easing power as wanted).

Just so you know, I believe there are 10 types of easing available, and can be set to just do ease-IN, or just do ease-OUT… or both, or neither. That’s some pretty beefy easing power… worth looking at.

Also notice that spin, spinto, move, moveTo, scale, scaleTo, color, colorTo… are very easily changeable… so you can send more parameters, or less… etc. You can make them more powerful, or make them dumber. You can make them run faster, slower, more/less frames, etc. CreateAndStartAnimation has LOTS of parameters allowed… it is very powerful and adjustable.

But again… you should probably read about the bad/good of overloading base classes. I am too inexperienced to know. I wrote those functions, and I have been known to program quite badly. :slight_smile:

Here’s another in the SAME series… https://www.babylonjs-playground.com/#HH1U5#80

Look around within the #HH1U5 … like #HH1U5#60 or #HH1U5#40 or lower/higher, etc.

There may be lots of playgrounds that use spinTo and similar…

https://doc.babylonjs.com/playground/?code=spinTo

Ok, again, I don’t necessarily recommend overloading Mesh or AbstractMesh classes… but… it’s some more fun… and might be handy for you. You could have ArmClass mesh and LegClass mesh and TorsoClass and HeadClass, and each of those custom subClasses of Mesh class… could have special animation funcs. Arm might have swingForward() and swingBack(). Leg has stepForward and stepBack. Head(class) has tipLeft and tipRight, etc.

See where we are going here? You make your own armClass, legClass, footClass, handClass, etc… and (over-)load them with special animation tools that are designed JUST FOR THEM. (custom anim funcs).

FUN!!! POWERFUL. Requires a gameplan, often. Maybe needs some study about JS “object oriented programming” possibilities. OOP is nice… as it allows/promotea re-usable code…which eventually leads to “rapid development”… ie. easily producing a new game/app every week. (because you have a toolbox full of re-usable custom classes). (You know all this already, right? nod)

Kbye! (long talk, sorry)

2 Likes

scene.onBeforeRenderObservable and scene.registerBeforeRender are different methods that produce the same result, as are scene.onAfterRenderObservable and scene.registerAfterRender. The observable methods were added when observers were added to the engine.

The before and after methods are different. Position, rotation and scaling, for example, of a mesh are calculated during the render part, that is the render part consists of a calculation and draw on screen. The before and after determine the order of engine code application together with you code. So consider two blue meshes travelling towards each other that you want to color red when they intersect. At the point of just intersecting so you have in psuedocode

scene.registerBeforeRender(function () {
    if (intersect) {
        color red
    }
} 

which gives

check - not intersecting so do not color red
calc - update positions, meshes now intersect
draw - blue meshes
check - intersecting so color red
calc - update positions, intersection increased
draw - red meshes

This can give the visual appearance that the coloring red appears too late.

whereas

scene.registerAfterRender(function () {
    if (intersect) {
        color red
    }
} 

gives

calc - update positions, meshes now intersect
check - intersecting so color red
draw - red meshes

2 Likes

You need to do for the other arm what you do with the first one, eg https://www.babylonjs-playground.com/#VAVC1V#1

Thank you both again for the incredibly detailed explanations and examples! There’s a lot of information here to process, so I’ll experiment with the different animation and mesh classification techniques you provided @Wingnut, and I’ll use your examples @JohnK to make sure I fully understand the before and after aspects of scene rendering. It’s surprising to learn that there are so many different programming methods to achieve the same or similar results.

Again, I really appreciate the speedy replies and the assistance! :+1:

1 Like

Hello W,

I’ve been working with your examples, and I have a few follow up questions if you don’t mind.

Let’s say I wanted an object to rotate once, then stop.

The function that makes it stop, written before the animation is called (below).

var = stopObjectRotation = function() {
???
};

Question: What else would be part of that stop function? Would that function be before, or after, create scene?

Here is the code that animates the object:

BABYLON.Animation.CreateAndStartAnimation(‘at4’, this, ‘rotation.’ + axis, speed, 120, this.rotation[axis], this.rotation[axis]+rads, 0, ease, stopObjectRotation);

Question: What part of this links it to the object? From your example, it seems that “rotation” is the part that does, but I don’t see how the rotating cylinders are linked to the animation.

Finally, when I get the rotation animation to stop, how would I get the next animation to begin? I actually want the end of an animation to start the movement of another object.

For instance, when arm mesh rotation stops, the whole parented character mesh moves forward.

Thanks again :+1:

Hi. That last param is NOT for a “stopAnimation()” function, it is for a “whenAnimationHasStopped()” function.

It runs just AFTER the animation has automatically stopped.

The animation stops… based upon… how FAR we tell the mesh to rotate… in how many frames and at what speed.

Generally speaking, you cannot stop the animation. You must wait for it to complete.

When it completes… the “callback function” can tell you it has completed… and it CAN… tell another animation to start… often from a list of animations. In others words, has the previous animation in the list of animations… finished? If so… let’s run the NEXT one in the list.

Let’s stop right there… for now. Don;t worry about what SHOULD happen when the animationHasEnded function… and don’t worry about what that function is named.

Just KNOW… that the function… runs… WHEN animation completes BY ITSELF. It is NOT a stopper. :slight_smile:

I understand how this can be confusing… I was confused by it myself, for a long time.

Ok, lets go touring a simplified playground.

https://www.babylonjs-playground.com/#HH1U5#163

Two shapes… and two “overloaded” animation functions… spin() and spinTo()

They are quite different from one another. SPIN… uses a axis that YOU must set in the first parameter… and an amount of spin IN RADIANS (a float value, such as 3.14), and HOW FAST to do it, and I’ve also added another value… HOW MANY FRAMES to use to do the spin.

How many frames to use, and how fast… are very related, aren’t they. The older versions of spin (and spinTo) sort of LOCKED the number of frames… at 120. In THIS NEW playground… you can set the number of frames AND the speed.

        (axis, radians, speed, frames)
           \       \       \      \
           "y"      \       \      \        
                  -3.14      \      \
                             125     \
                                     120
box1.spin( "y",   -3.14,     125,    120  );

-------------------------------------

Now for spinTo...

        (unused, targetRot,                            speed, frames)
             \       \                                    \      \
             null     \                                    \      \        
                    new BABYLON.Vector3(0, -Math.PI/2, 0)   \      \
                                                            125     \
                                                                    120
box1.spinTo( null,  new BABYLON.Vector3(0, -Math.PI/2, 0),  125,    120  );

Notice… that spin() uses an AXIS “y” and a radians 3.14 value… which is a FLOAT value.

Conversely… spinTo() uses NO axis (unused) and a vector 3 value… new BABYLON.Vector3(0, -Math.PI/2, 0) (which is NOT a float, it is a vector3). The vector 3 value… contains within it… WHICH axis… AND also how many radians (-Math.PI/2 or… -1.57 radians). Inside that vector 3, the -Math.PI/2 is stored in the Y segment OF the vector3. Again, the vector3 can store both WHICH AXIS, and HOW MUCH ROTATION.

The speed and the amount of frames… are used the same in both spin and spinTo. And again… previous versions of spin() and spinTo()… had no “frames” setting. It was locked at 120 frames. I allowed you/users to set it… in THESE two new versions. New power! :slight_smile:


Ok, this has surely blown your mind ALREADY.

But quickly here. you asked “how” are these animations “linked” or “associated” with the mesh.

ALL mesh… boxes, cylinders, spheres, all mesh… are sub-classes of BABYLON.AbstractMesh.

SO when we did this…

BABYLON.AbstractMesh.prototype.spin = function (axis, radians, speed, frames) {…

We actually “installed” a spin() function… on every subclass of BABYLON.AbstractMesh. In other words, we put a SPIN() function… on ALL mesh that you EVER create in your scene. Anytime you make a box, it has a SPIN() function automatically installed on it… because it was inherited from its “superClass”… BABYLON.AbstractMesh.

Don’t mistake this for parent/children. Think of it as… we changed the SPECIES. Box and cylinder automatically have a spin() on them… because we modified its bloodlines… and made it so ALL mesh (boxes, cylinders, everything) that has blood from BABYLON.AbstractMesh… now has the spin() function.

And then we did the same thing for spinTo(). We installed it on BABYLON.AbstractMesh… and so… it was handed-down to all “blood-kin”… which includes boxes and cylinders… as well as spheres, toruses, etc etc etc. ALL mesh… in your scene… have a spin() and spinTo() function… as soon as you create one or many. This… is called “overloading a class”. We didn’t modify the “parent”, we modified the “species” or “creature type”. Parenting and childing is a different thing… so don’t get THAT confused with overloading the type or species.

Heavy, huh? nod.

Notice that both spin() and spinTo() use the this keyword rather often. Every time the animation overload RUNS… this = the caller. When we called box1.spin()… this IS box1. When we call cyl1.spinTo()… this == cyl1.

And many times… for both of these animators… we asking the animator to spin FROM this.rotation (current rotation)… to some new rotation. Both of these animators… START at CURRENT rotation location… and then spin to somewhere else… at some speed and frames-rate.

So this… is the link to the mesh.

Let’s try an experiment. Let’s print “this”.name to console… each time an animation func is called/started.

We have 4 anim calls in the previous PG, with each call reporting to console… when it has finished.

This time… let’s print this.name… (the name of the mesh) at EACH anim-start time. Watch console…

https://www.babylonjs-playground.com/#HH1U5#166

I added line 5 and line 12… reporting the names of the mesh that are calling the funcs. We see that this is always the mesh that is calling the func.

I changed the “look” of the 4 animation calls… this time… too…making them less confusing-looking.

Look at lines 50, 54, 58, and 62. We are calling box1.spin and .spinTo… and cyl1.spin and spinTo… methods/functions… which do not exist on “normal” BabylonJS mesh. YOU added them to all BJS mesh (for your project only)… with line 2 and 9… the “overloads”. You reached deep into BabylonJS “core” and added a spin() and spinTo() feature… to ALL mesh in YOUR scene. You changed the species. :slight_smile:

Ok, your mind is surely completely “blown” (stirred-up crazy) and you likely have started growing a brain tumor. hehe. This might be why the experts say… “Hey, don’t use overloading… it just confuses everyone”. hehe. But it IS powerful. ALL the mesh you make in your scene… will automatically have a spin() and spinTo() method/function/feature on them. Ballsy and brave of you, isn’t it. You should feel powerful… and rightly so. You have used JavaScript Object Oriented Programming… via a special feature called prototypes. You have found a powerful wizard potion… and experimented with “first taste”. VROOOOOOOM!!!

I hope I have been helpful. You ask very wise questions… and they are NOT easy to answer… because class-overloading via prototypes… is an odd JS feature/power.

Overloaded animation functions like these… MIGHT NOT WORK for you… in the “long run”. Remember the “lists of animations” mentioned earlier? Now notice lines 34-36, and 44-46… the onThisMeshAnimEnded function for each mesh. Might be wise for you to change “on” to “upon”.

“uponThisMeshAnimEnded” … yeah I like that name better. You should change to that. :slight_smile:
Way at the end of line 6 and line 13… we see the “callbacks” being called… this.onThisMeshAnimEnded … and notice we are using the magical this keyword, again. Cool, huh?

ANYWAY… back to the lists of animations. The lists of animations need to be managed and updated… inside those onThisMeshAnimEnded functions. (or uponThisMeshAnimEnded if you rename them). It will require some special handling inside those functions… so you know WHICH animation in the list has finished, and which animation is the next one to start.

You might wish to overload cyl1 and box1… by setting… box1.lastAnimationStarted = 0; and cyl1.lastAnimationStarted = 0; … just after creating those mesh. You actually CREATE those properties by doing that. They did not exist on box1 and cyl1… before you did that.

But AFTER that… INSIDE the onThisMeshAnimEnded… you can check and increment that number.

this.lastAnimationStarted++; (increments the whichAnimation number).

I’ll stop there. But I think you can understand… that box1 and cyl1 COULD “carry with them”…which animation of a LIST of animations… was just now completed. And thus… you might know WHICH animation in some list of Anderson34-created animation calls… is the NEXT one. If cyl1 and box1 carry with them… WHICH was the previous from the list, you can determine which is the NEXT to call from the list. These lists of anims… would need to be invented by you, and would likely be an array of spin() and spinTo calls… a list… of animation “sequences”.

And it might not work as you expect… and might be a complete failure, because you might discover… that running little animation after little animation after little animation… might not give the results you wish. But maybe it will.

And maybe I need to stop talking RIGHT NOW, before my hands fall off and/or your brain explodes. Surely there are typos here, and me saying wrong things and teaching badly. I will try to “clean” this monster post over the next day or two. Be patient with me and yourself… this is some advanced stuff you are working-with, here. Again, try to find some time to study basic JS inheritence and prototyping, and please pardon the many incorrect things I could have told you. I am no pro at JS “OOP” or class prototyping…I just found it one day and made these goofy little animation utility funcs. They are probably bad idea… but they DO work and ARE handy… somehow.

Be well, my friend. Study slow… experiment a lot, and use lots of console.log reports to show yourself what is happening and help you learn. byeeeee. :slight_smile: Other helpers… feel free to clarify this mess, but don’t get brain tumors. :smiley:

Another epic and extremely helpful post :smiley: :+1:

This is definitely enough information and thorough explanation to help me eventually understand how the animation systems work. It’s clear that I jumped right into difficult programming without a solid understanding of the fundamentals, but that’s OK. It’s challenging, but fun!

Thanks again W.
I appreciate you going above and beyond the call of duty to help out!

I’m glad. Heck, I’m glad that you survived READING IT. :slight_smile:

These overloads are just an odd method to do animations. They aren’t the only way to animate, but certainly a strange/unique way. :slight_smile:

The CreateAndStartAnimation command/directive… has one VERY UNIQUE feature… that makes it much different from other animation techniques. I call this unique feature… Automatic Data Type Sensing… which we can call ADTS.

Spin() uses floating point data type or often just called “floats”. Floats are a single numeric value, sometimes with a decimal point… like 3.14 and -1.57 and -Math.PI and 6.28 and Math.PI*2 and 0.114 and similar. Those are the animated value. We told spin() to animate on a certain axis (“x”, “y”, or “z”)… and an amount of radians… as a FLOAT value. (0.707 radians, -Math.PI/4 radians, etc)
cyl1.spin("y", -1.57, 125, 120) In that example, the -1.57 is a float value that holds the amount of radians to rotate).

Now spinTo()…

SpinTo() does NOT use a float value/data-type… for its radians. It uses a vector3 data type to tell how many radians to rotate and upon which axis to spin.

box1.spinTo( null, new BABYLON.Vector3(0, 1.57, 0), 125, 120 );

new BABYLON.Vector3(0, 1.57, 0)* is a vector3 data type… and as mentioned earlier… it stores the amount of radians to rotate, AND it tells WHICH AXIS to spin… because the 1.57 is the MIDDLE value.

You could also rotate on two or three axes… all at the same time… using THIS data type…

box1.spinTo( null, **new BABYLON.Vector3(0.2, 1.57, -Math.PI/6)**, 125, 120 );

In THAT call, we are rotating on all 3 axes at the same time… and each axis is rotating… a different amount of radians than the other:

  • x-axis rotates 0.2 radians across 120 frames at a speed of 125.
  • y-axis rotates 1.57 radians across 120 frames at a speed of 125.
  • z-axis rotates -Math.PI/6 radians across 120 frames at a speed of 125.

This is important stuff, of course… but what I am trying to show… is the wonderful magic… of CreateAndStartAnimation’s ADTS. (automatic data-type sensing). ADTS is a super-handy feature, and it makes CreateAndStartAnimation… very powerful. MOST other BJS animation systems DO NOT have ADTS. They often need to be TOLD which data-type is going to be animated. But not CreateAndStartAnimation… it is a “smart animator” and it knows/senses the data-type FOR US.

This is why all those little animators… spin(), spinTo(), move(), moveTo(), scale(), scaleTo(), color(), colorTo()… look SO SIMILAR. They all take advantage-of CreateAndStartAnimation’s ADTS (auto-data-type sensing)

Let’s make a colorTo() demo…

https://www.babylonjs-playground.com/#HH1U5#167

Colors are often stored in a Color3 data type. In lines 43 and 48… we see the Color3 data type being used in the calls to our new ColorTo() animator.

At 3 seconds after scene-start, box1 animates from its current color… to the color in line 43… new BABYLON.Color3(0, 1, 1).

At 10 seconds after scene-start, cyl1 animates from its current color… to the color in line 48… new BABYLON.Color3(1, 1, 0).

Although the ColorTo() animator has different parameters in its CreateAndStartAnimation(in here)… we still DID NOT tell it… that we were NOW going to animate a Color3 data-type. It automatically “sensed” that we sent a Color3 data-type, not a Vector3 data-type, and not a Float data-type. It was smart. It KNEW… we were sending a Color3.

This ADTS… automatic data-type sensing… performed by CreateAndStartAnimation… is nice… but it can confuse folks who are accustomed-to using OTHER BJS animation systems, which REQUIRE the user to specify (tell) the data-type. No need to tell CreateAndStartAnimation… it “knows”.

Someday, a smart programmer could possibly COMBINE all my spin(), spinTo(), move(), moveTo(), scale(), scaleTo(), color(), colorTo(), etc… into ONE function… one super-powerful ANIMATE ANYTHING in ANY WAY function. WOW!

I am not ready to try that, yet, or ever. Such a super-function would need to automatically “sense” which mesh property we wished to animate… ie. color, scale, position, rotation, etc… and STILL use its wonderful auto-data-type sensing, TOO. Perhaps someday, YOU will invent this “super animator” single function overload. You would become a superstar!

BUT… you would need to write documentation for your new super-overload… teach others how to use it. As you can tell by MY teaching here… it is not easy to teach super-powerful/super-versatile things. The more powerful the function, the more examples need to be shown… telling users ABOUT all those powers.

SO, perhaps… spin(), spinTo(), move(), moveTo(), scale(), scaleTo(), color(), colorTo()… should not be functions for the “general public”. Instead… they are examples of CUSTOM FUNCTIONS for a few projects. Not everyone should use or learn them… but instead… write similar functions exactly customized for THEIR personal projects. In other words… perhaps we never teach the actual spin(), spinTo(), move(), moveTo(), scale(), scaleTo(), color(), colorTo() functions… but instead… teach users HOW to make/invent similar functions… for THEIR personal project(s).

You must admit… we are NOT really teaching about spin(), spinTo(), move(), moveTo(), scale(), scaleTo(), color(), colorTo()… here, are we? We are REALLY teaching about BABYLON.Animation.CreateAndStartAnimation(), right? nod. It is a wonderful tool… and can be used in many places. I love it.

I hope you have no deadlines to meet… so you can go slow and have lots of fun along the journey. BabylonJS IS… tons of fun. Sometimes it is Mister Wingnut that makes it difficult. hehe. I hope I have not made it difficult for you. I hope it remains fun. “Learning curves” only hurt for a short time… I promise. Soon, you will be a BabylonJS pro/superstar… I know you will. You are a very fast learner… I can tell.

Good luck. Don’t accidentally blow-up your porch or pet… with these crazy powerful experiments. lol. Be well and happy.

It’s good to know about all of these animation techniques, and the CreateAndStartAnimation function does seem easier to use than some of the other methods in the documentation. At this point, I’m not really sure what the best path to follow will be. I’m trying to create an evolution simulation involving creatures that self-animate. For instance, the limb animations determine how the parent creature moves. Eventually, I want a creature to spawn with random animation parameters that collectively determine the creature’s ability to move autonomously through the map. So, your description of creating special classes with their own animation properties seems perfect.

Currently, I still can’t seem to get the code below to work properly. Everything works perfectly except the line in bold. There should be a -1 step for every value between 0 and -90 degrees of rotation, creating continuous movement of carBody for every pivotFI rotation between 0 and -90 degrees. I tried creating an array thinking this would be a way of telling the function every value between 0 and -90, but it still behaves like it’s only registering one event (it will move once when it exceeds -90).

var step = 0.02;

var list = [ ];

for (var i = 0; i <= -Math.PI/2; i++) {
list.push(i);
}

var armMove = function() {
pivotFI.rotation.y += step;
if (pivotFI.rotation.y > Math.PI/2)
step *= -1; //invert step

else if (pivotFI.rotation.y <= list)
step *= -1; //invert step
carBody.translate(BABYLON.Axis.X, -0.02, BABYLON.Space.LOCAL);
};

var armAnimation = scene.onBeforeRenderObservable.add(armMove);

Update: Success!

I actually just got everything to work by creating a separate function like the one you provided at the beginning of this thread.

var carMove = function() {
if (pivotFI.rotation.y < 0)
carBody.translate(BABYLON.Axis.X, -0.02, BABYLON.Space.LOCAL);
};
var carAnimation = scene.onBeforeRenderObservable.add(carMove);

Thanks! :smiley: :+1:

2 Likes

hello @Wingnut , i hope that you’re fine :slight_smile:

i’m using mesh.rotation.x ti get the rotation value , but this value is in radius and i want to get rotation value in degree.

any help ?

Just multiply the value in radian by 180/Math.PI to get the value in degrees.

You also have: BABYLON.Tools.ToDegrees(radValue)

1 Like