binyan

Rotate a mesh about a given axis

Recommended Posts

What is the way to rotate a mesh about a given axis?

For example I have a triangle whose vertices are (0,0,0), (1,0,0), (0,0,-1) and I want to rotate it about the axis z = -0,5, x = 0 . How can I achieve that?

Share this post


Link to post
Share on other sites

I think there is no function to do that for now but I may be able to add it. For now, here's the trick: if your mesh doesn't have a parent you can position its pivot thanks to

 

mesh.position.z = -0.5;

mesh.position.x = 0;

 

and then set the pivot matrix to reposition your mesh where it was initially. Your pivot matrix should be the identity with m[11] and m[13] with the right values

 

With this set, you can now do mesh.rotation.y = whatever you want

Share this post


Link to post
Share on other sites

Thank you guys for your answers.

I think I'm missing something... 

gwenael, 

This:

mesh.position.z = -0.5;

mesh.position.x = 0;

Will move the mesh, and then you suggest to reposition it to its previous place. How exactly it would help? 

DK,

I've read this wiki page, but it is not explained there what is the difference between LOCAL and GLOBAL spaces. I think I have a lack of knowledge :)

Could you explain please what will happen after the first step (rotate) and after the second step (translate).

Thanks! 

Share this post


Link to post
Share on other sites

Still struggling to understand what is the difference between the local space and the world space...

Tried to play with it in playground but still got nothing. For example, this code:

 

scene.beforeRender = function () {    box.rotate(new BABYLON.Vector3(0, 1, 0) , 0.01, BABYLON.Space.LOCAL);}; 

gives me the same result as this one:

 

scene.beforeRender = function () {    box.rotate(new BABYLON.Vector3(0, 1, 0) , 0.01, BABYLON.Space.WORLD);};

So I can't get a point...

 

Lets say, for simplicity, that I'd like to get my box to rotate about one of its corners... I.e. about the same vector - (0,1,0), but with offset = boxSize/2. As vector doesn't have coordinates but just a direction it seems that I should translate the box to another point. And the point should depend on rotation... 

How exactly should I rotate and translate it to get the desired result?

 

P.S. Guys I feel that I lack some basic knowledge and my questions about rotation, translation and spaces are pretty dumb. Could you please turn me to some good source where I can read about these things?

 

P.P.S I know how to solve it with basic math (geometry and trigonometry) but I'm wondering what is a common way in 3D dev to achieve that.

Share this post


Link to post
Share on other sites

Ok, I have a little progress!

var camera = new BABYLON.ArcRotateCamera("Camera", 3 * Math.PI / 2, Math.PI / 8, 50, BABYLON.Vector3.Zero(), scene);camera.attachControl(canvas, false);var light = new BABYLON.HemisphericLight("hemi", new BABYLON.Vector3(0, 1, 0), scene);//Creation of a box//(name of the box, size, scene)var box = BABYLON.Mesh.CreateBox("box", 6.0, scene);// Creation of a torus// (name, diameter, thickness, tessellation, scene, updatable)var torus = BABYLON.Mesh.CreateTorus("torus", 5, 1, 10, scene, false);// Moving elementsbox.position = new BABYLON.Vector3(-10, 0, 0);   // Using a vectortorus.position.x = 10;var p = BABYLON.Matrix.Translation(-3,0,-3); // (x,y,z) must be expressed in parent spacebox.setPivotMatrix(p);scene.beforeRender = function () {    box.rotate(BABYLON.Axis.Y, 0.01, BABYLON.Space.Local);};

This implements the simple example I talked about in previous post. (Torus is here to just get some relative point)

It seems that it somehow related to the answer of gwenael because I used here pivot matrix... But I am still unable to get the point of his answer.. Why should I do a plenty of stuff (ok, not a plenty but a bit more) when I can just set the pivot matrix as I did it here? And I still can't understand what exactly DK suggested and how it should work, so the previous post (all the local, world, translation and rotation related topics) is still relevant.

 

And one more question... In the case that I have to rotate the object about a different axis each frame, I'll have to set the pivot matrix each frame and then rotate the object. Would it cost me in additional overhead? 

Share this post


Link to post
Share on other sites

Metalx1000, not exactly... I need to rotate a mesh about a Y axis which is placed in the center of the world space (0,0,0). The problem is that each frame this mesh has a different position. For example at frame 0 it is located at (0,0,0), at frame 1 it is located at (0,0,1). It means that each frame the mesh must be rotated about a different axis in local space. So what I'm looking for is how to do that in best way. The only way I found till now is a way I described in my previous post (with setting the pivot matrix) but I'm not sure it is a best way.

gwenael and DK have suggested other solutions but I can't understand them. In general, I'm trying to better understand the spaces and transformations, looking for some good source to learn that. 

 

P.S. in a second thought your way may also work... What happens when the parent point intersects with a mesh (i.e. resides inside a mesh)?

Share this post


Link to post
Share on other sites

Hi binyan,

 

Sorry I've been off the forum for a while. I'm trying to catch up but it can take me some times.

 

Did you figure out how to do what you wanted?

 

 

gwenael, 

This:

mesh.position.z = -0.5;

mesh.position.x = 0;

Will move the mesh, and then you suggest to reposition it to its previous place. How exactly it would help? 

 

Sorry I was not totally clear.

 

First, this may help you: http://www.html5gamedevs.com/topic/3083-spaces-world-parent-pivot-local/?p=19938

 

All points (vertices) of a mesh have positions relative to mesh center. For example, for a mesh which is a cube, one of its point may be at (1,1,1) if the mesh center is the center of the cube (intersection of its diagonales) and another point would be at (-1,-1,-1). The side of the cube would be 2 units. The positions of the points of the mesh are relative to the center position of the mesh. If the center of the cube is positioned at the center of the world (0,0,0) then the first point (I mentioned before) of the cube is positioned at (1,1,1) BUT if the center of the cube is positioned at (5,5,5) in the world then the first point is positioned at (6,6,6) in the world but still at (1,1,1) relatively to the center of its mesh. (5,5,5) is expressed in World space whereas (1,1,1) is expressed in Local space (relative to mesh center).

 

mesh.position, mesh.rotation and mesh.scaling set the pivot of the mesh relatively to the center of the parent mesh (or center of the world if the mesh doesn't have a parent). The mesh rotates relatively to its pivot.

pivot matrix sets the center of the mesh relatively to the pivot of the mesh

 

A point (1,1,1) expressed in local space has a position in parent space by combining the matrix given by mesh.position, mesh.rotation and mesh.scaling and the pivot matrix. Like for is position expressed in world space, its position expressed in parent space may be different than its position expressed in local space BUT on your screen it's still at the same place. It's something similar to: you are sitten between two people, you are at the right of the first one (your position expressed in his/her space) and the left of the second one (your position expressed in his/her space) but still you didn't move :)

 

By doing mesh.position.z = -0.5 you set the position of its pivot at z = -0.5 relatively to its parent (the world here)

same thing with mesh.position.x = 0

 

but if you don't specify a pivot matrix then by default the center of the mesh is on the pivot (on your screen your mesh has moved)

If you specify a pivot matrix then you set the center of your mesh relatively to its pivot and now you can rotate around the axis of the pivot space instead of those of the local space

 

http://www.babylonjs-playground.com/#1LVVGB

Share this post


Link to post
Share on other sites
On 6/12/2014 at 1:30 PM, Deltakosh said:

Like this:


mesh.rotate(BABYLON.Axis.X, 1.0, BABYLON.Space.LOCAL);mesh.translate(BABYLON.Axis.X, 1.0, BABYLON.Space.WORLD);

Axis is just a vector3 so you can use the axis you want

 

https://github.com/BabylonJS/Babylon.js/wiki/How-to-handle-rotations-and-translations

Stupid question, but where did the wiki go?

Share this post


Link to post
Share on other sites

Came here via google. 

I'm pretty sure that this is what Binyan was talking about: http://filmsbykris.com/scripts/Game-Basics/BabylonJS/rotation/rotate_point.html

The trick is to set a point which rotates, and set the object that you want to rotate as it's child:

 

objectToRotate.parent = pointToRotateAround

pointToRotateAround.rotation.y += 0.005

 

Share this post


Link to post
Share on other sites

hi 

it is not best solution for rotate but usefull maybe help i have 4 method for this

rotate_xy( {x,y} /*center*/ , {x,y} /* main */ , alpha /*rad*/ );

r_y( {x,y,z} , alpha /*rad*/ , {x,y,z} /*center*/ ) rotate in Y axiz

r_x( {x,y,z} , alpha /*rad*/ , {x,y,z} /*center*/ ) rotate in X axiz

r_z( {x,y,z} , alpha /*rad*/ , {x,y,z} /*center*/ ) rotate in Z axiz

http://babylonjs-playground.com/#1UR1XA#0

 

function def(a, d) {
    if (a != undefined && a != null) return (d != undefined && d != null ? a : true);
    else
        if (d != _null)
            return (d != undefined && d != null ? d : false);
    return null;
}

function rotate_xy(pr1, pr2, alpha) {
    pp2 = { x: pr2.x - pr1.x, y: pr2.y - pr1.y };

    return {
        x: pr1.x + pp2.x * Math.cos(alpha) - pp2.y * Math.sin(alpha),
        y: pr1.y + pp2.x * Math.sin(alpha) + pp2.y * Math.cos(alpha)
    };
}

function r_y(n, a, c) {

    c = def(c, { x: 0, y: 0, z: 0 });
    var c1 = { x: c.x, y: c.y, z: c.z };
    c1.x = c1.x;
    c1.y = c1.z;

    var p = rotate_xy(c1, { x: n.x, y: n.z }, a);

    n.x = p.x;
    n.z = p.y;

    return n;

}

function r_x(n, a, c) {

    c = def(c, { x: 0, y: 0, z: 0 });
    var c1 = { x: c.x, y: c.y, z: c.z };
    c1.x = c1.y;
    c1.y = c1.z;

    var p = rotate_xy(c1, { x: n.y, y: n.z }, a);

    n.y = p.x;
    n.z = p.y;

    return n;

}

function r_z(n, a, c) {

    c = def(c, { x: 0, y: 0, z: 0 });
    var c1 = { x: c.x, y: c.y, z: c.z };
    var p = rotate_xy(c1, { x: n.x, y: n.y }, a);

    n.x = p.x;
    n.y = p.y;

    return n;

}

 

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.