Snouto

Orbiting a mesh from a set initial position

Recommended Posts

Alright errybody

This is a question more about maths than anything else, and i'm terrible at maths so I'm hoping someone (maybe @Wingnut) can help me here.

My scene is loaded from a blender export, which in itself is partially an imported FBX from C4D (still waiting on that C4D exporter boys!).

I have a mesh within the scene that has a set position, and I want to allow it to orbit in a circle when clicked or tapped by the user. Fundamentally this is fine and I have most of the logic in place, but I'm struggling to figure out how to make it animate from it's initial position. All of the example code I've seen make the object jump to a calculated first position and then animate, which is not what I want. Has anyone got some sweet ninja code that I can borrow steal that will do what I need?

Additionally is there a convenient technique or built in method to add easing to the beginAnimation call, or to the calculated keyframes?

Cheers!

Here's my current code:

var onMeshPicked = function(bjsEvent) {
    myPickedMesh = bjsEvent.source;

	var frames = 90; // number of points

    var parent = myPickedMesh.parent;
    parent.indexPoint = 0;
    var p=0;

    var points = [];

    var radius = 2;
	for (var i = 0; i < frames; i++) {
        // calculate the keyframes
	    points.push( new BABYLON.Vector3((radius + Math.sin(i*Math.PI/frames))* Math.cos(2*i*Math.PI/frames), parent.position.y, ( radius + Math.sin(i*Math.PI/frames)) * Math.sin(2*i*Math.PI/frames)));
	}

	parent.points=points;
	var path3d = new BABYLON.Path3D(points);
    var tangents = path3d.getTangents();  //array of tangents to the curve
    var normals = path3d.getNormals(); //array of normals to the curve
    var binormals = path3d.getBinormals(); //array of binormals to curve

	parent.animationPosition = new BABYLON.Animation("animPos", "position", 30, BABYLON.Animation.ANIMATIONTYPE_VECTOR3, BABYLON.Animation.ANIMATIONLOOPMODE_CYCLE);
	parent.animationRotation = new BABYLON.Animation("animRot", "rotationQuaternion", 30, BABYLON.Animation.ANIMATIONTYPE_QUATERNION, BABYLON.Animation.ANIMATIONLOOPMODE_CYCLE);	

    var keysPosition = []; 
    var keysRotation = [];

    for(i = 0,p=frames; i < p; i++) {
        keysPosition.push({
            frame: i,
            value: parent.points[i]
        });

        keysRotation.push({
            frame: i,
            value: BABYLON.Quaternion.RotationQuaternionFromAxis(normals[i], binormals[i], tangents[i])
        });
    }

    parent.animationPosition.setKeys(keysPosition);
    parent.animationRotation.setKeys(keysRotation);
	
    scene.beginDirectAnimation(parent, [parent.animationPosition,parent.animationRotation],  0, frames, false, 0.25,null);

};

 

Share this post


Link to post
Share on other sites
2 hours ago, Snouto said:

Additionally is there a convenient technique or built in method to add easing to the beginAnimation call, or to the calculated keyframes?

Yes, see how the easing function is attached to the animation.

I don't know if it qualifies as ninja code, but you can chain the animations.  So, first move the mesh using an easing function and once it's in the position you want (onAnimationEnd function is called) then you can run the second animation.
https://www.babylonjs-playground.com/#8BYZ34

Share this post


Link to post
Share on other sites
14 minutes ago, brianzinn said:

Yes, see how the easing function is attached to the animation.

I don't know if it qualifies as ninja code, but you can chain the animations.  So, first move the mesh using an easing function and once it's in the position you want (onAnimationEnd function is called) then you can run the second animation.
https://www.babylonjs-playground.com/#8BYZ34

Thanks dude, that easing code is exactly what I was looking for. And now that I've seen it I realise I've used it before in one of my other hundred test scripts 🙄

Following on from my test code I've been searching around more and found an article on pivot points. My code now looks like this:

var onMeshPicked = function(bjsEvent) {
	myPickedMesh = bjsEvent.source;
	if(!myPickedMesh.isPickable) return;

	var frames = 90; // number of points

	if( parent===null ){
	    parent = myPickedMesh.parent;
	    var CoR_At = new BABYLON.Vector3(0, parent.position.y, 0);
			var axis = BABYLON.Vector3.Up();
			var pilotStart = new BABYLON.Vector3(parent.position.x,parent.position.y,parent.position.z);
			pivot = new BABYLON.TransformNode("root");
		  pivot.position = CoR_At; 
		  parent.parent = pivot;
			parent.position.y = 1.7657999992370605;
		  var angle = 0.01;
	
		parent.yRot = new BABYLON.Animation("yRot", "rotation.y", 30, BABYLON.Animation.ANIMATIONTYPE_FLOAT, BABYLON.Animation.ANIMATIONLOOPMODE_CYCLE);

		var keyFramesR = []; 

		keyFramesR.push({
		   frame: 0,
		   value: 0
		});

		keyFramesR.push({
		   frame: 2 * frames,
		   value: 2 * Math.PI
		});

		parent.yRot.setKeys(keyFramesR);
		var easingFunction = new BABYLON.QuarticEase();
		easingFunction.setEasingMode(BABYLON.EasingFunction.EASINGMODE_EASEINOUT);
		parent.yRot.setEasingFunction(easingFunction);
	}

	scene.beginDirectAnimation(pivot, [parent.yRot],  0, 2*frames, false);
}

That line: parent.position.y = 1.7657999992370605; is my wacky attempt to adjust the position of the mesh once it is parented to the pivot, because as soon as that happens the mesh position changes. It may well be due to the parent mesh being over sized in the blender model due to wanting to avoid recalculating the baked animation (which was done before being parented), but I've struggled to figure out what that Y figure should be since there doesn't appear to be an obvious correlation to the new position that I can see.

Share this post


Link to post
Share on other sites
2 hours ago, Snouto said:

That line: parent.position.y = 1.7657999992370605; is my wacky attempt to adjust the position of the mesh once it is parented to the pivot,

I can't see your code running, but I would imagine that parent.setParent(pivot) might end up fixing your issue (instead of parent.parent  = pivot).  Otherwise probably best to break this into a Playground?

Share this post


Link to post
Share on other sites
7 minutes ago, brianzinn said:

I can't see your code running, but I would imagine that parent.setParent(pivot) might end up fixing your issue (instead of parent.parent  = pivot).  Otherwise probably best to break this into a Playground?

Ding ding ding ding we have a winner! That fixed the problem immediately. That's both super satisfying and incredible perplexing and frustrating at the same time. Just when you think you're getting a handle on BJS something like this occupies half your day!

Well I appreciate your help there @brianzinn you managed to solve two big issues for me and now the animation works as planned. Cheers!

Share this post


Link to post
Share on other sites
On 7/4/2018 at 2:38 AM, Snouto said:

something like this occupies half your day

hehe.  I once had a scene issue... occupy 5 months!  (but some of that time was spent in Tibet, learning how to meditate in 3D from Buddhist monks).  ;)

I needed a vector3 direction, based upon the rotationQuaternion of a mesh.  Spacecraft... roll it a few degrees around z-axis with physics-based rotation thrusters (quaternion)... then stop.  Now get the direction needed to thrust (applyImpulse) the spacecraft perfectly sideways (localSpace, ie.  When sitting in pilot's seat.)  erf. 

It took a matrix transformToNormal thing.  The most difficult part was... describing it in a way that others understood what I wished-for.  I didn't have the terminology mastered enough... to know how to ask.  Weird phenomena.  :) It took 3 lines of code.

Needless to say, a significant party happened when the issue was solved... thx to Deltakosh  (It was the 4th time I tried to explain to forum-folk... what I needed). 

DK did just like BrianZinn did to you, Snouto.  "It sounds like you need this" ... <something><something><something>

That was it.  A few playground and docs searches later... my physics-active spacecraft started acting perfect.  The angels rejoiced.  The sun came out.  The flowers bloomed.  And my dog jumped up on my lap and started licking my face.  Everyone and everything sensed... something wonderful had happened.  :)

I gold-plated those 3 lines of code and they are hanging on the wall here in my puter room.  :D

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

  • Recently Browsing   0 members

    No registered users viewing this page.