3D dragging not working at all

Hi!
I’m currently working on how to drag a Spatial with the mouse.
Most of the code I’m using is from here

One declares the axis, the object shall be moved on before dragging.
E.g. the Y-Axis is chosen:
[java]
CollisionResults results = new CollisionResults();
Vector2f click2d = inputManager.getCursorPosition();
Vector3f click3d = cam.getWorldCoordinates(
new Vector2f(click2d.x, click2d.y), 0).clone();
Vector3f dir = cam.getWorldCoordinates(
new Vector2f(click2d.x, click2d.y), 1f).subtractLocal(click3d).normalizeLocal();
Ray ray = new Ray(click3d, dir);
rootNode.collideWith(ray, results);
CollisionResult closest = results.getClosestCollision();
selectedSpatial.setLocalTranslation(
selectedSpatial.getLocalTranslation().getX(),
closest.getContactPoint().getY(),
selectedSpatial.getLocalTranslation().getZ());
[/java]
It works basicly, but sometimes, the spatial “jumps” aways from the cursor.
This video shows moving a torus (which works quite fine) and a very flat box (which doesn’t work on the Y-Axis).
[video]http://www.youtube.com/watch?v=bHGPWpuAj34&feature=youtu.be[/video]

PS: I’m an absolutly bungler in math, so if there is an embarrassing bobvious mistake: please don’t kill me :slight_smile:
PS 2: Link not working any more, sry

You are only dragging while the mouse is over the object, so if you move the mouse more than the size of the object (very easy in the example given) then you lose the drag. That probably explains why the other drag is a bit jumpy too.

Instead when they first click “lock” that object as being dragged and create a (mathematical only, no model) plane for the drag area. Record the intersection of the click ray with that new plane, the object being dragged, and the current location of the dragged object.

Now for as long as they hold the key down work out the intersection with that plane and then move the object to originalLocation + (newIntersection - originalClickIntersection).

Thank you for answering.
Maybe I got you wrong but how can I create a ray that casts the mathematical plane which is not attached to the root node and not able to collide.

You should be able to find something useful in the maths ray api:
http://hub.jmonkeyengine.org/javadoc/com/jme3/math/Ray.html

1 Like

Is your “plane” parallel to the screen or arbitrary?

(probably similar to what zarch has already said)

Create an actionlistener which creates the ray, and checks for a collision (i would also suggest hiding the mouse at this point). Then if a collision is successful, store what spatial had collided, and record a boolean if you are allowed to drag it. Then in your analogListener, do your dragging logic if the mouse is held down. I’ve done a similar technique so much in the last few weeks.

Generally, this sort of thing is so much easier to do with a raw input listener since you get the whole event and access to the deltas, etc… or at least the raw screen coordinates. Going from a 2D mapping to a 3D is always easier when you have the 2D mapping to begin with. :slight_smile:

But the basic event logic is the same either way and that’s covered by zarch’s post, too. I generally opt for:
button down → store current mouse location
drag → get delta from start location, project into 3D space
button up → clear mouse location

The projection is not so bad… easier if you are parallel to the screen or don’t care about proper foreshortening of distances. You can take the screen-based 2D x,y values and simply multiply them by some direction vectors and add them to the object’s original location.

Thank you for those many answers! :slight_smile:

Create an actionlistener which creates the ray, and checks for a collision (i would also suggest hiding the mouse at this point). Then if a collision is successful, store what spatial had collided, and record a boolean if you are allowed to drag it. Then in your analogListener, do your dragging logic if the mouse is held down
Yup, this is basicly how I'm doing it too, at the moment.
You should be able to find something useful in the maths ray api
I guess you refered to the "intersectsWherePlane" method? Thanks for that, I should have found that before. Even though, should the plane fill the whole screen so I can capture the click intersections? My english isn't that good but I guess your idea is to prevent the "mouse no longer over spatial" - effect by using a Plane which is big enough. But how should I arrange that? ------ By the way, by replacing [java] rootNode.collideWith(ray, results); [/java] with [java] selectedSpatial.collideWith(ray, results); [/java] one can stop that "jumping", it still doesn't move when the mouse isn't over the spatial.

The easiest way to prevent the “mouse no longer over spatial” problem is to no longer require intersection with the spatial once it is “captured”.

You can avoid doing collisions at all after the spatial is captured. Just use the 2D coordinates of the mouse to calculate a delta and project it along the plane. The math is about as simple as vector math gets, actually.

Edit: note, the same approach is possible intersecting with a plane… you just have to go through a few extra steps. It is more likely to keep the mouse looking like it’s over the spatial though. A direct 2D to 3D mapping (where the plane is not parallel to the screen) gets tricky if you require the mouse to visually stay hooked to the spatial.

1 Like

The plane is your drag plane. So it will extend from the point of the first click and then be on either the X, Y or Z plane depending on what you are dragging on. Create a mathemetical plane extending to infinity from that point in the correct direction.

Once you know you are inside the drag (so basically everything after the first click until the release):
Create your ray from the screen click
Intersect your ray with the mathematical plane.
Use the distance between the current and original click locations on the plane to move the spatial to its original location + the distance you just found.

Now you aren’t colliding with the original spatial at all so it doesn’t matter how much or how fast you drag, you always get smooth movement. The projection from screen etc co-ordinates is all handled for you too, you just need to move the spatial by the amount the collision has moved.

1 Like

Oh, and don’t forget that rays can “miss” the plane if they are looking the wrong way so make sure your code checks for that :slight_smile:

Thank you all for helping!

I’m sorry that I didn’t respond for so long, I’m currently too busy to follow, but I’m optimistic to solve it when I have the time :slight_smile:

It is indeed my enjoyment to watch from the effective software basic tips. Which can be superb to pay attention to all the records at this site.Very good writeup. Ideally this valuable room or space business people may bring american result-oriented specifics later.Through a light put out from June, the actual chairman inside the Across the world Group of Room Business men is starting to arrive at hard after angel seasoned traders enthusiastic about finance open area venturesSound much like a remarkable endeavor this IASE! for sure a superbly developed write-up! To by working with glen7565, enterprisers need to be prompted If you don’t they may give up hope.specifically what on earth would you indicate that bring back?unquestionably impressive Practice. I seemed to be a touch disappointed to determine the connect to IASE homepage had been impaired. Eventually this approach group continues to be energetic! I have discovered looking at this unique characteristic, this is now enlightening. now i am presented by using Open area Entrepreneurship Staff Sends BatonReally excellent send undoubtedly!There really is monitoring the idea option that should be good capability.

Hi
welcome to everyone
i’m newly in this forum.


www.homesecurityproducts.eu