Jump to content

Custom pivot position


cyomu
 Share

Recommended Posts

Hello comunity.
I'm glad I found this beautiful framework. :)

I'm pretty new to this so please sory if I'm doing wrong something.
I have one component which has 2 different parts, one of them you can rotate it with right click, and the other you can dragg it.

And you can move or rotate the main component from menu.
Everything work nice with default pivots, but I want that my main component and its kids to have their pivot on bottom left corner.

And now my problems come:
1. if I rotate the main component and after that I try to move a part,
            i) this part seems to have invert axis, I men if I drag to bottom it go to top and so on

           ii)and on mouse up everything is distroyed, the pivots are wrong, the parts are wrong - this is happenning if I want to rotate this part
2. if I move the main component and after that I try to move a part, or rotate it, I got the same result, everything is wrong positioned.

PS: Yes, I read this twice, and a lot of things from here and here


I hope you understand my problem and maybe you can give me a hint on the right direction.


PS2: I did my homeworks and I know a playground is needed: http://playground.babylonjs.com/#VJMEH8

Link to comment
Share on other sites

Hi cyomu, welcome aboard... good to have you.

Some of the locals surely remember this goofy thing:  https://www.babylonjs-playground.com/#PBVEM#160  (control + k o ; . for rotate, shift + k o ; . for translate)  (control and shifted numeric keypad work, too.  Physics-active 24 applyImpulser flying machine from hell.

Not important.  But, I had a problem with this.  After I rotated the craft sideways or inverted, then translate-thrusting along X/Y/Z axes... totally went to hell.  I needed the craft to translate along its LOCAL-space axes, and not along WORLDspace.  (cyomu might have the same problem with his mouse-drag-moves on his child mesh).  After his parent/master mesh is rotated in ANY way, the drag system on the children/sub-mesh... are all in unexpected directions.  (Pryme8 wisely suggests doing a parent.bakeCurrentTransformIntoVertices() AFTER the parent rotation... but before any drag-moving of sub-parts is attempted.)

ANYWAY... lines 158-162 in that playground...

	FlyerFrameController.prototype.doTransformPerFlyerQuat = function (vec) {
		var mymatrix = new BABYLON.Matrix();
		this.flyer.rotationQuaternion.toRotationMatrix(mymatrix);
		return BABYLON.Vector3.TransformNormal(vec, mymatrix);
	};

cyomu... your master object might not have a .rotationQuaternion yet, and thus might still be using default .rotation.  But that doesn't really matter.

The important part... is that matrix transformNormals stuff.  I don't understand it, and maybe Pryme8's "bake" idea might work fine, if done at the right time.

I just wanted to point this out.  I once had troubles "adjusting" the X/Y/Z thruster directions... on a spacecraft... AFTER it had been rotated.  This might be pertinent.  Maybe not.
 

cyomu... perhaps... when you drag a child/sub mesh... try to translate it along ITS LOCALspace X/Y/Z axes.  Let's look at a translate command...

thing.translate(BABYLON.Axis.Z, someDistanceNumber, BABYLON.Space.LOCAL);

The translate command has a sister... rotate:

thing.rotate(new BABYLON.Vector3(1, 0, 0), amountInRadians, BABYLON.Space.WORLD);	

THAT kind of rotating is... "Quaternion", so your thing will have a .rotationQuaternion after that, and no longer use .rotation property.  Not important now, we'll talk later.

Important line:

thing.translate(new BABYLON.Vector3(0, 1, 0), someDistanceNumber, BABYLON.Space.LOCAL);

Translate the (child-) thing... along ITS Y axis... for the dragging... perhaps.  LocalSpace.  In localSpace, pretend you are piloting the thing, and when you say "Go +X NOW!"... it better travel exactly X-ward (from pilot perspective)... no matter if the thing is up-side-ways-down or whatever.  :)

Maybe some of this junk will help, maybe not.  ANYthing can be done... easily, usually.  The hard part is... what is the correct term to search-for, eh?  Be well.

Link to comment
Share on other sites

Holla. Many thanks. 
I understood a few things, I missunderstood others :) and now I'm haveing more questions :)
Sir @Deltakosh this function works well, thanks.
Sir @Prime8 I understood what does this function, but I'm afraid or I don't know how to use it exactly or it's not exactly what I'm looking, honestly I don't know.

And sir @Wingnut thanks for this explanation, and very nice playground :)
I did a little changes according to this. I remove the menu gui, now you can move the main component by left click drag, and rotate it by right click. This both are aplied directly to the position and rotation (no quaternion). For the kids I'm aplied a local rotation and translation

kid2.rotate(BABYLON.Axis.Y, Math.PI / 2, BABYLON.Space.LOCAL)
kid2.translate(diff, 1, BABYLON.Space.LOCAL)


But still I'm haveing some missunderstoods:
when I rotate the main component I got this
default:

image.png.3954d5bfb55fbba7020ae7b071c580ce.png
rotated:
image.png.4324e9fc86b7f5a9a3f087fe2f888919.png


The rotation on kids seems to be ok now, and it's working. The movement works well only when the kid has the pivot on bottom left:
image.png.cc0fde515b370eb6da7dd9f0d38b1aea.png
if I rotate it in any angle the directions are wrong for dragging. I thing here comes your function Wingnut, but I don't know how to use it exactly, because now I don't have quaternions on the parent, but noh if I'm using quaternions on the parent this function still don't work, or I'm using it wrong :)
And another question. If I set directly the position or the rotation on one kid, like kid.position.x = 5. Do I set kid world position/rotation or I;m setting position/rotation related to his parent?

Thank you again!

Best regards, Cyomu
 

Link to comment
Share on other sites

Hey. I didn't give up :)
@Wingnut sir, can you please explain this function doTransormPerFlyerQuat maybe a little demo, not so complex like your demo, I tried it but still didn't work, I mean still get wrong directions on dragging. Thanks
I'll keep you posting

 

Best regards, Cyomu

 

Link to comment
Share on other sites

Hi C!  Actually, I can't really explain it.  It was coded FOR me.

Right now, the playgrounds are failing... so I haven't seen the one you provided.

Have you used any of the techniques of our drag'n'drop playground demo, such as its getGroundPosition() function?

If so, I can understand why the dragging is screwed-up after an axes rotate.  That is a somewhat limited drag'n'drop system.

Dragging is not always easy, in 3D space.  It might be easier to use 3 GUI sliders that pop-up when you right click on a child mesh... one for moving the mesh along each axes.

Right click again, and the panel of 3 axes sliders... closes again.  Could that system... work for you?

CSX Heavy Freight train sim... uses something similar.  It has lots of dashboard panels... and multi-setting rotary switches and multi-position levers.  That game always pops-open a slider when you hold down mouse button over the control... and on that slider... there are multiple "nodes"... slider stopping points... one for each setting on the switch or lever.  SO, its mouse-down, slide left or right on the GUI slider to set the knob however you wish, then lift mouse button and the slider disappears again.  This is how THEY work-around the miserable task of dragging in 3D.  *shrug*

 

In your first two pictures... (default and rotated), that doesn't look good at all.  The red parent's yellow pivot point should REMAIN at its corner... after the rotate.  Not sure why it is doing that.

For now, let's avoid Quaternions and avoid that doTransform function, too.  Let's stay with .rotation instead-of .rotate, but feel free to use .position or .translate. 

Let's also avoid dragging anything at this time.  Consider using GUI buttons or sliders, if you can, temporarily.  Perhaps you or another forum helper will build a playground that looks like your demo pictures... which uses sliders/buttons to move/spin children... instead of dragging.  That way, we can separate dragging issues... from "transformations" issues.  I suspect that it is the your (after rotation) dragging techniques that are causing the problem.  We'll learn more as we test more.

So, if we build a playground that can move/spin all the mesh properly... with buttons/sliders... then we have succeeded in solving 1/2 the problem. :)

Yes, building a GUI panel with a bunch of buttons... rotate red x 90 degrees, rotate green 90 degrees, move red 20 units on localSpace X, etc etc... can take a long time and lots of work, especially for someone new to BabylonJS GUI.  Maybe we can convince a GUI pro... to help us build that testing demo.

OR... or ALSO...

We need to think-up a good testing demo for you... that moves the pivotPoint of the master object, then rotates the master object, and then needs a drag-positioning/rotation on a child of the master.

I'm thinking... an opening/closing door... with a sliding bolt lock on it.  First we will move the pivot point to the edge of the door (so it swings open/closed properly), then we'll parent the bolt lock to the door, and then we'll try to drag-slide the bolt side-to side (making sure it works no matter if the door is open, closed, or partially open).

Does that sound like a good playground test-scene, whose discoveries could give us good knowledge?  

We need to take this a step at a time, and you might need to say goodbye to direct-dragging children/submesh... that are attached to parents who are rotated.

Try not to be discouraged.  We'll grind this out... even if it kills us.  :)

On 5/3/2018 at 3:28 AM, cyomu said:

Do I set kid world position/rotation or I;m setting position/rotation related to his parent?

Related to his parent.  Parenting... causes .position, .rotation, and .scaling... to be handed-down from parent to child, where child's .position, .rotation, and .scaling is added to it... to create a final position, rotation, and scaling for the child.

Ok, more soon, I hope.  It's a real-life-busy time of the year for me... so hopefully others will also help.

Link to comment
Share on other sites

Ahh, now the playgrounds are working again, and I see you already have a nice playground with buttons.  Easy to see dragging issue on green kid 2 and right-click rotating issue on blue kid1.  I will investigate it.  Thx.  hmm.

CreateArea might be the problem.  You are calling it rather often... which re-creates the parent, right?  Might be better to create it once, and only re-scale it when needed.  Hmm.  Thinkin'.

Oops, playgrounds are 404 again.  Friday afternoon employee picnic at Internet Inc... gone awry, I suppose.  :)

Link to comment
Share on other sites

Thank you so much sir for your time. I'm going to create a playground with rotation and position only from gui.
And about CreateArea I think I'll disable it for now, and focus on it later.
I'll be back in a few hours with a new playground :)
 

Best regards, Cyomu

Link to comment
Share on other sites

:) Calling me "sir" seems weird.  My actual title is... "He who speaks volumes while having no knowledge."  :D (too long to type).

http://playground.babylonjs.com/#VJMEH8#4

I've been doing some experimenting (while watching Saturday morning cartoons).   Turned off createArea... temporarily, though it is a cool func and we need to re-visit it.  I now see that your parent was a blank mesh, which is fine.  I changed it to a plane, temporarily, then baked it flat like the ground, and showed its bbox.  (Gray plane in center)

I also aimed camera +z, and tilted it down a bit... no biggie.  I always like using a +z aimed camera.. for tests.  Now, -x is leftward,  +x rightward, -z is nearer to cam, +z moves away.

Now for the REALLY INTERESTING thing:   Kid2Pivot (a gray sphere with show-bbx set ON) is having its parent set to kid2 green box... in lines 80/81. 

Line 80 is working fine.  We can see the boundingBox of the gray sphere (kid2Pivot)... at the center of green kid2.  Perfect.

NOW... disable line 80, and activate line 81...  click RUN!   Hey, something is different!

hmm.  I thought line 80 and line 81... perform the same action.  But, maybe not.  Maybe I need to do some reading...

http://doc.babylonjs.com/api/classes/babylon.mesh#setparent

Ahh, using setParent() keeps the mesh in the same place.  Using .parent moves the mesh to the parent.pivot/origin.  Aha.

Anyway, that's all I've done, so far.  I'm probably going to remove .setParent() calls, and go with .parent.... for further testing.  Stay tuned... I'm a slow troubleshooter.  :)

Link to comment
Share on other sites

http://playground.babylonjs.com/#VJMEH8#5

Another version... now working-with right-click for rotating blue kid1.

Working around lines 60/61... pink pivot not parented to blue kid1, just doing console tests.

Repeated right clicks on blue kid1... show that its pivot point is properly set to upper left corner.

Line 60:  console.log(kid1.getAbsolutePivotPoint());  ==>  Object { x: 4.5, y: 0, z: 1 }

Z = 1 ?  That seems wrong.  That is the reason why pink pivot is not at the TRUE pivot point of blue box.  (maybe)

I guess I need to read/learn some more.  *scratch scratch*.  I used to know how to make BJS scenes, believe it or not.  :)

Link to comment
Share on other sites

Thought I would have a go by interpreting what you are trying to do and starting from the beginning. So here is a playground https://www.babylonjs-playground.com/#AMJ6KW#1

However perhaps my interpretation is wrong ( more than likely) on the other hand you can move the green box in the correct direction when the red area is rotated and rotate the blue box. As @Wingnut suggested I have gone for one red plane which I alter by scaling.

What I am not sure about is what are your fixed points for the red plane. In my version one dimension of the the plane is constrained by the fixed points given by the yellow sphere and the magenta sphere of the blue box together with the direction of the blue box. The other dimension is partially adjustable by the magenta sphere of the green box.

TL;DR

Other points to note.

My plane is constructed using createPolygon, this places it in the XZ plane without the problem of rotating the createPlane to do so.

Using scaling rather than creating the plane each time causes its own issues. The first scaling issue is if you use a sphere as parent and scale by scaling the sphere the sphere scales as well. For the area I set a pivot point to scale about and make a sphere (areaPivot yellow) in WORLD space. The name areaPivot is a bit of a misnomer since it is not really a pivot for the area. Rotating or translating the area is done about the setPivotPoint for the area and rotations and translations of the areaPivot have to be done seperately and in addition as well. What the areaPivot is, is a parent to spheres (kid?Pivot, magenta) which in turn are parents to the two boxes. So rotating and translating the areaPivot will also translate and rotate the kid?Pivots. So to be clear(?) for the area I am using a setPivotPoint as a pivot, whereas for the magenta spheres I am using a parent mesh(sphere) as a pivot and for the boxes I am using a parent mesh (sphere) as a pivot.

The second issue is that as far as I know there is no method of scaling in the WORLD space so there is a need to ensure that scaling takes place in the correct. Hence I set up a system of global axes that can be rotated and the values for scaling come from these axes which swap x and z values as they rotate. There are probably better ways built into BJS for doing this.

Setting the area based on rotating the blue box depends on the direction of the blue box and whether its length and breadth are added or ignored. Whether it is length or breadth that is added swaps as the box is rotated, hence this is done when kid1 is rotated. For adding them or not there are 4 possible rotations for the blue box, 0 x PI/2, 1 x PI/2, 2 x PI/2 and 3 x PI /2. Rotations 0 an 3 require length or breadth to be added, 1 and 2 do not. So for 0 and 3 a multiplier of 1 is needed and for 1 and 2 a multiplier of 0 is needed. Using addition modulo 4 gives the  rotation counter rotCounter, gives the 0, 1, 2, 3 rotations, taking these modulo 3 gives 0, 1, 2, 0, dividing these by 2 gives 0, 0.5, 1, 0 which when rounded gives 0, 1, 1, 0 and subtracting these values from 1 gives the needed multipliers 1, 0, 0, 1.

Are your spheres acting as markers for the pivots during development or are they a necessary part of your final project? If they're just there as markers during development replace the sphere with transformNodes and set radius to 0 ( or delete throughout) to give https://www.babylonjs-playground.com/#AMJ6KW#2

Link to comment
Share on other sites

:) Wow, John, what an analysis.  Thx for the help.

My take on it... is that blank mesh (which I made a real gray plane called parent in PG #5)... is always parent to all children.

Red plane/area... is only a fence... surrounding summed bounding boxes area... of all children of parent.

Notice that all cyomu's buttons are rotating/translating the parent, not the red plane.

This is why cyomu can call createArea(parent); often, without interfering with anything else.  CreateArea() does not affect any parenting, positions, or rotations.  In effect, createArea() ==  .showSummedBoundingBoxOfAllChildren... or... showCorralNeededForSurroundingTheseAnimals  :)

Is that the way... you are interpreting this. John?  I hope so. 

I don't think the pivotPoint mesh are meant to be permanent, so they can't be used as parents, or be permanent children of anything.  I think the pivot mesh are for temp-showing of .position for children pivot points. 

My first of many struggles...  kid1Pivot.position = kid1.getAbsolutePivotPoint();  ...doesn't seem to work.  ( line 61 http://playground.babylonjs.com/#VJMEH8#5 ). Right clicking on blue kid1 shows it is pivoting nicely around its upper left corner (that upper-left corner is z=0, I believe).  Yet kid1.getAbsolutePivotPoint(); or kid1.getPivotPoint();  ... both return z = 1;  My theory is that both methods are broken... in the framework code, but I'm often wrong.

So, whether the children of gray plane parent are rotated or dragged, createArea() ONLY places a red corral around/under the kids.

On the OTHER subject... dragging-around green kid2... of course that's going to be problem, because it is parented and because kid2.position.addInPlace(diff) in line 107 of #5 PG... diff likely needs transforming... to take parent rotation into consideration.

So, my #5 was only working-on blue kid1 right clicking... and trying to get kid1pivot mesh to be located at actual kid1 pivot point.  I'm failing at THAT supposedly-simple task.  :)

I hope your response doesn't blow cyomu's mind... but I fear it might.  :)  It blew mine. but that happens easily, with me.  :)

Link to comment
Share on other sites

Hi Yuhuu, a lot of new things to read and to understand.

@Wingnut, I just wanted to be polite 😀.
You did a lot of investigations, I realy appreciate your involvement. Let me check these playgrounds a little bit. :)


Sir @JohnK, huh. I need a little time to check and understand your playground, but I like it. This is more math than babylonjs buildin functions....And sorry if I was not clear enough. I think I created a too complicate playground for what I actually need.
 

The red area and the spheres are only for developing purpose, I just wanted too see if happen what I expected.
Actually I have too objects and they need to have pivot on left bottom. They are independent(no relationship between them or between them and other objects). But I have the option to link / unlink them. Now when they are linked I think to create a mesh (simple mesh - not transform node, because I read on other topic that I cann't determine the boundingBox of its kids, and I needed this because this parent should have the pivot on letf bottom too, not in center of bounding box determined by kids, on left bottom of this bounding box. When these objects are linked I have 2 options: 
 - act like one object (in this case I'm playing with the parent, rotate, and translate)
 - act independent, rotate and move each one separate.
When unlink I just setParent to null and set the position on each objects.

I thought this was the simplest way to achieve this. But it seems it's not so simple :(

Anyway, thank you so much for this replies. I'm trying to learn as much as possible day by day and you helped me a lot till now.

Best regards, Cyomu

Link to comment
Share on other sites

@cyomu first please do not call me sir it reminds me of the days when I was a teacher. Secondly an apology as there are errors in the documentation on how to use a parent as a set pivot down to me. I have corrected the errors but will not be seen in the documentation until it is next rebuilt (possibly days away). The documentation may have misguided you. The corrections are

## How to Use a Parent as a Set Pivot

Perhaps you would like to think about achieving the positioning of the pivot by changing the pivots position rather than the pilots position. This can be done with parenting as shown in the following example.

The sphere, representing the pivot at the center of rotation, is placed at the pivot position (CoR_At), the sphere is then made the parent of the pilot. The translation needed to move the pilot starting position to the center of rotation is found and is used to set the pivot using a matrix.  The pilot position is reset to the translation vector and the pilot rotated.

```javascript
sphere.position = CoR_At;
pilot.parent = sphere;
var pilotTranslate = pilotStart.subtract(CoR_At);
pilot.setPivotMatrix(BABYLON.Matrix.Translation(pilotTranslate.x, pilotTranslate.y, pilotTranslate.z));
pilot.position = pilotTranslate;
pilot.rotate(axis, angle, BABYLON.Space.WORLD);
```

* [Playground Example - Rotating Mesh as Pivot's Child](https://www.babylonjs-playground.com/#1JLGFP#77)

Done this way any movement of the pivot is done by moving the parent mesh representing the pivot.  
* [Playground Example - Rotating Mesh Moving Pivot's Parent along Axis](https://www.babylonjs-playground.com/#1JLGFP#78)
* [Playground Example - Rotating Mesh Moving Pivot's Parent](https://www.babylonjs-playground.com/#1JLGFP#80)

 

Link to comment
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...
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...