satguru

BabylonJS EditControl

Recommended Posts

Documentation: https://ssatguru.github.io/BabylonJS-EditControl/

Demo: https://ssatguru.github.io/BabylonJS-EditControl/demo

Source and Download: https://github.com/ssatguru/BabylonJS-EditControl/releases

Release 3.1.0 (01/22/2018)

* planar guides always rotate to face camera. makes it easier to pick them
* mesh with parents or childs are properly supported. see https://ssatguru.github.io/BabylonJS-EditControl/demo-parenting.html
* constructor now has an additional optional parameter called "pickWidth". This determines how close the pointers need to get to an axis before the axis can be picked up. The default is 0.02
* constructor "scale" parameter has been made optional. Default is 1.
* code refactored. private properties are prefixed with underscore "_". This warns JavaScript coders from using those as  JavaScript does not honor TypeScript's "private" keyword. Underscore also helps with property name mangling and thus reducing the minified size.
* added additional demo file (demo-parenting.html). The long term intention being to use these  for tests.

Release 3.0.0 (12/31/2017)

major change to rotation UI
    now uses the more common "spherical" guides
new methods
    getPosition()
    getRotationQuaternion()
    hide()
    show()
    isHidden()
    setVisibility()
few properties and methods which were private were exposed by mistake. They are now hidden
code refactoring.

Release 2.5.0 (12/03/2017)

added translation and scaling bounds.
client can limit translation and scaling between a minimum and maximum value
contributed by @focomoso

Release 2.4.5 (09/04/2017)

see https://github.com/ssatguru/BabylonJS-EditControl/releases  for details

with this release the edit control is now also available from the NPM repository

Release 2.3.0 (06/05/2017)

Changes

  • migrated from Java to TypeScript
  • rewrote picking process to make the control snappier
  • added transforms in planes
  • added scale snap
  • changed UI - hopefully more intuitive now

 

Release 1.0.0 (03/22/2016)

Of late I had been working on a small in-world kind of 3D editor similar to what you find in open sim or second life kind of virtual worlds.

As I worked on it I realized that the part used for controlling translation, rotation or scaling of objects can be re-written as a reusable component.

So that' what I did :)

I created, what I call a "BabylonJS EditControl".

You can use this in your editor, if you like, to handle translation, rotation or scaling of meshes.

For a simple demo see https://ssatguru.github.io/BabylonJS-EditControl/demo

For source code and explanation on how to use it from your code see

https://github.com/ssatguru/BabylonJS-EditControl

The initial version was written using Java and JSweet. ( don't think I could have done this without JSweet :))

Newer versions from 2.3.0 have been written using TypeScript.

Please try and provide some feedback.

Regards

 

Share this post


Link to post
Share on other sites

Small Hotfix scene.pick in case you use several camera

//function EditControl
this.mainCamera = this.scene.activeCameras[0] || this.scene.activeCamera;


// function PointerDown and onPointerOver
this.scene.pick(this.scene.pointerX, this.scene.pointerY, function (mesh) {
                            if ((_this.transEnabled)) {
                                if (((mesh == _this.tX) || (mesh == _this.tY) || (mesh == _this.tZ)))
                                    return true;
                            }
                            else if ((_this.rotEnabled)) {
                                if (((mesh == _this.rX) || (mesh == _this.rY) || (mesh == _this.rZ)))
                                    return true;
                            }
                            else if ((_this.scaleEnabled)) {
                                if (((mesh == _this.sX) || (mesh == _this.sY) || (mesh == _this.sZ) || (mesh == _this.sAll)))
                                    return true;
                            }
                            return false;
                        }, null, this.mainCamera);

//function getPosOnPickPlane
this.scene.pick(this.scene.pointerX, this.scene.pointerY, function (mesh) {
                            return mesh == _this.pickPlane;
                        }, null, this.mainCamera);

I add  , null, this.mainCamera

Share this post


Link to post
Share on other sites

Hi Dad72,

Thanks for checking this out.

Regarding Active camera , good point. I will put that fix in.

Regarding,

2 hours ago, Dad72 said:

By cons when active rotate, translation is not off.

 

By design if you go from one mode to another mode the previous mode should turn off - so switching from translation to rotation should switch translation off. The demo should work that way.

(I was wondering if I should leave that to the developer. Maybe they might want to see both translation and rotation at the same time. )

Anyway where do you see that behavior?  if you have code snippet then let me know I will check it out

Regards

 

Share this post


Link to post
Share on other sites

Maybe this is normal. but when the active rotation mode is inside the circles you can see what appears to translation axis. but maybe I'm wrong.

I integrate it into my editor and it works well. except that I have a problem to convert Quaternion => Euler and Euler => Quaternion

Share this post


Link to post
Share on other sites
2 minutes ago, Dad72 said:

Maybe this is normal. but when the active rotation mode is inside the circles o can see what appears to translation axis. but maybe I'm wrong.

 

Yes that is normal.I think it helps user figure out the orientation. In fact I am thinking of extending the axis in negative direction too during rotation.

4 minutes ago, Dad72 said:

I integrate it into my editor and it works well. except that I have a problem to convert Quaternion => Euler and Euler => Quaternion

Nice

and yes Quaternions Eulers are pain. Let me know if anything in the control can help

Share this post


Link to post
Share on other sites

Found a bug when using in IE

After dragging control and  releasing IE, it seems, still sends pointer down event to Camera and  turns this  into free look :(

In Chrome drag changes pointer to edit caret during pointer down.

Works fine in Firefox.

I bet something to do with event propagation and default behavior.

Will be looking into it.

Hopefully should have a fix soon.

Regards

Share this post


Link to post
Share on other sites

On my old control system I use "mousedown, up, move" rather than "pointerdown , up, move". And it worked well

canvas.addEventListener("mousedown", function (evt) { return that.onPointerDown(evt); }, false);
canvas.addEventListener("mouseup", function (evt) { return that.onPointerUp(evt); }, false);
canvas.addEventListener("mousemove", function (evt) { return that.onPointerMove(evt); }, false);

Maybe this can help

And for convert Quaternion <=> Euler:

mesh.rotationQuaternion.toEulerAngles() // quaternion to euler

var quaternion = BABYLON.Quaternion.RotationYawPitchRoll(mesh.rotation.y, mesh.rotation.x, mesh.rotation.z); 
mesh.rotationQuaternion = quaternion; // euler to quaternion

 

Share this post


Link to post
Share on other sites

That looks really cool and is very intuitive to use. I think I can really use that for my little editor project, too! I'll give it a try as soon as I have time. Thanks a lot already! :)

 

EDIT: Just playing around a bit for now, two things i noticed so far:

  1. there is a typo in the documentation: editControl.swicthTo(Mesh mesh);
  2. I had to re-add the event listeners with "mouseX" instead of "pointerX" because it wouldn't work for me otherwise. I think dad72 already mentioned this.
  3. and I think I might have the same problem with the rotation as dad72, it seems to overwrite my euler values

here is my first try with your editcontrol: http://p215008.mittwaldserver.info/mapEditor2.0/MapEditor/

Share this post


Link to post
Share on other sites

@iiceman, thanks for taking the time to check this out and btw nice angular app :)

Regarding mouse vs pointer  - could you add the the hand.js file and see if that solves the issue

<script src="https://cdn.jsdelivr.net/handjs/1.3.8/hand.min.js"></script>

Regarding euler . That is peculiar!. The Mesh.rotate() function does that. It resets the euler values to zero. Maybe somebody in the forum can throw some light on this?. Let me open a topic on this.

I also have a new version out with following fixes and changes

1) Fix for issue when multiple cameras are used.
@Dad72  thanks for the solution. The user has to now provide the camera in the constructor. This way the active camera can be other than "scene.activeCameras[0]" or "scene.activeCamera "

2) Fix for IE issue.
It was related to http://www.html5gamedevs.com/topic/20122-playground-drag-and-drop-example-question/

3) Fix for Chrome issue .
This, as I suspected, was related to mouse drag default behavior . An "event.preventDefault()" fixed that.

4) The TypeScript code is nicely formatted. There was a JSweet option for that.

Regards

 

Share this post


Link to post
Share on other sites
On 26/1/2016 at 11:40 AM, iiceman said:

and I think I might have the same problem with the rotation as dad72, it seems to overwrite my euler values

You must use quaternion rotations with the EditControl .

but if you need to recover the values Euler, I did like this:

//Here one gets a value from a Euler quaternion
var myvector3 = mesh.rotationQuaternion.toEulerAngles() // quaternion to euler

At inversse if you have Euiler value and want to receive rotation quaternion value, I actually like this

// Here the values are RotationYawPitchRoll Euler
mesh.rotationQuaternion = BABYLON.Quaternion.RotationYawPitchRoll(1.0, 0, 0); // euler to quaternion

when quaternion is used, it disables somehow mesh.rotation. mesh.rotationQuaternion uses the mesh in the place.

And thanks for fix satguru

I made a correction to this function works better now:

EditControl.prototype.getPosOnPickPlane = function () {
       var pickinfo = this.scene.pick(this.scene.pointerX, this.scene.pointerY, null, null, this.mainCamera);
       if ((pickinfo.hit)) {
              return pickinfo.pickedPoint;
       } else {
              return null;
       }
};

 

Share this post


Link to post
Share on other sites

@Dad72, EditControl uses ".rotate()" method so it uses quaternion.

I will put in a change to update the euler rotation value using "toEulerAngles()"

Let me check on the getPosOnPickPlane.  You have removed the predicate which checks for pickplane and without that I might get hits on other objects.That will create problem for me.

 

Share this post


Link to post
Share on other sites
18 minutes ago, satguru said:

Let me check on the getPosOnPickPlane.  You have removed the predicate which checks for pickplane and without that I might get hits on other objects.That will create problem for me.

At home, the problem was that I get a null value after moving the mouse when I was just an object behind.

Share this post


Link to post
Share on other sites

The problem is solved with the changes I made on the function getPosOnPickPlane.

This is that before, 'pickinfo.hit' is not working if I had a mesh just behind the gizmo.

In image:

red circle in the first, the model is right behind. I could not move the models ( getPosOnPickPlane  return null)

gizmo1.thumb.jpg.8e95c6e3a1514bce5c5e33c

Now in the red circle, there is nothing behind the gizmo and it worked ( getPosOnPickPlane  return vector3)

gizmo2.thumb.jpg.0f0aff90f12bba6a667f392

But to this problem disappeared with the changes I made on the function getPosOnPickPlane.

sorry for my bad english, I use a translator.

Share this post


Link to post
Share on other sites

@Dad72, 

pas de problème :)

I think I know why that is happening.

Try this

change  getPosOnPickPlane  back to what it was.

Increase the pickplane size here

private createPickPlane()  {
            this.pickPlane = Mesh.CreatePlane("axisPlane", 20, this.scene);

change that from 20 to say 200.

Let me know if that solves your problem

Regards

 

Share this post


Link to post
Share on other sites

Sorry to hear that.

Unfortunatelly I haven't been  able to reproduce your issue.

It should not matter if the object with the widget is completely covered by or behind another object.

 

Anyway I have a new version out.

This fixes the euler issue. I now set the value of rotation before returning. Thanks again for suggesting the fix.

Also few UI changes. Hopefully makes it more easier to use.

Try this out and let me know if you still have the problem

If yes lets look at your code. If you don't mind maybe you can open an issue on my github site and load some files there?

Regards

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.