Basic 2D drawing on top of Canvas

I’m interested in allowing users (of a 3d "editor’ I’m working on) to draw on the screen in order to make changes to the 3d mesh being “drawn” on. In the past I’ve noticed that usually the suggestion given to people interested in such a feature is to add actual 3d objects to the world in order to draw lines and such, but this isn’t going to work in my case of a very "freehand’ line. What I have in mind is what you’d see in a regular 2d image editor if you draw a freehand line:



http://i.imgur.com/F1ElA.jpg



Is there a way to do something like this? (If not, what’s the best approach I could take?)



Technically maybe I could put a Swing drawing canvas temporarily on top of the jME canvas, but then it’d lose focus and I’d lose the ability to get collision data needed to interpret what this line intersects with. So I think this’ll need to be something well integrated w/jME. Ideas?

If the line is in 2d-space, what will happen with the line if they rotate the camera? Will it still orient itself with the terrain?

Or do you mean the line is on the actual surface of the terrain?

Any camera changes (or any action after the initial mouse-drag really) would invalidate the interaction, so I’d just erase the line. It wouldn’t remain on the screen any longer than the time during which the user is doing a mouse drag. When the user ends the mouse drag, I’d remove the temporary “2d” line and perform the actual work needed to modify the mesh. In the case demonstrated above for example it’d be for ‘painting’ a river. So the 2d line is just UI feedback to the user to help out a bit.



Yeah, nothing as tough as re-drawing on new camera orientations, or anything like that. It’s more of a UI-level thing than OGL or 3d.



If this is just too out of the scope of jME, I’ll have to think of an alternative way of providing such user feedback… I’m not sure how it’d effect performance were I to actually add large numbers of temporary “line” markers.

it doesn’t sound too hard does it, a solution might be to :



while the mouse depressed :

for every game tick (simpleUpdate. Could run less frequently to boost performance at the expense of line resolution) :

• store the current mouse position (so it can be used next tick)

• add a com.jme3.scene.shape.Line to the guiNode, that starts at the mouse position from the previous tick, and ends the mouse position for this tick (mouse position in Projection Space i.e. screen x/y coords).

• repeat until mouse released

• profit?



it may be better to build a custom mesh on the fly for this, would be pretty basic geometry and wouldn’t require texturing. Also there may be a better shape to use other than Line - I have never used Line so probably shouldn’t be recommending it.



To me this sounds like a simple solution, it’s the kind of crap I used to do in Flash or HTML for drawing, but I would hazard a guess and say raping the scene graph with too many meshes like this will make it run like a dog, and is bit overkill.



eh, my 2-cents… good luck with it :slight_smile:

I see.

@thetoucher’s idea will work well for this.

Another option: you can overlay your UI with an image of the same resolution as the screen that is fully transparent. Then as the mouse is depressed and moves, update the pixels in that image. You can look at the SDK’s PaintTerrainToolAction for code on how to manipulate an image in jme.

If I overlayed the UI with a transparent image, would I still be able to get collision pick ray results as the mouse is dragged? That’s the main reason I haven’t explored such an option. But maybe if I get creative enough I can do this without ‘raping the scene graph’ (lol). Will start exploring options…

For every point drawn on the image you can translate it to a ray and save all of those to be used for intersecting the terrain when the time comes.

I think I’ll try the first approach first (easier), and see how it performs.

yep it will definitely be easier. I doubt it will slow down your app anyways.