In the below playground, I tried to paint on a sphere, the place where I clicked and dragged using mouse was not painted. But for plane it is painted correctly. Why?. Where am I going wrong?
It does work for me as expected, apart from where the texture meets the edge of the uv coordinates.
Think about this texture as a plane texture, mapped to a sphere. Eventually you will get to a point where at least two edges need to touch one another. When the mouse moves between the two areas, you need to compensate for that, otherwise your lastPoint and currentPoint will be 1 unit away from each other (and this is why you sometimes get a ring around the sphere instead of a point). I hope it makes sense…
Also, I am not too sure why the math looked like it, but this is a simpler version: Painting | Babylon.js Playground (babylonjs.com)
I’ve done a quick draft to explain visually :
When you hit a stroke with the mouse from A to B on the sphere, it actually paints the stroke on the texture from A to B, with matching UVs
Now, problem arrives when you paint a stroke accross the vertical limit of the UV :
- A to B on the sphere : Little line accross the limit (in red for sake of clarity)
- A to B on the texture : Crosses the full frame from right to left.
Non only it creates a ring, but the actual path from A to B on the sphere is not even painted
Here is a fix :
- You detect that there is a jump (distance from two points which use to be a few pixels, is suddently about 512 …
- You sort the points along X
- You create the middle points a the limits : A2 and B2
- You paint the 2 new strokes, in Green :
var pts = [lastPoint, currentPoint];
pts.sort((a,b) => {
return b.x-a.x;
})
var ptA1 = pts[0];
var ptA2 = {x:512, y:0.5*(pts[0].y+pts[1].y)}
var ptB2 = {x:0, y:0.5*(pts[0].y+pts[1].y)}
var ptB1 = pts[1];
paint(ptA1, ptA2);
paint(ptB2, ptB1);
Here you go : Playground
++
Tricotou
Thanks for the reply. This works. For this sphere this is ok, but what if I have a glb model and it has a texture wrapped around it and what will be the dynamic calculation?. Can we arrive at a generic calculation to paint on a any resolution of a texture? @Tricotou
@Raviraja the trick with the middle points between A & B is indeed valid in the context where the UV structure is known.
If you deal with an unknown texture with a complex UV wrap, best is to only calculate the distance, and avoid drawing a stroke in the event of a “jump”.
This Playground would work on any mesh. Only stuff to adapt is my threshold if(dist<100)
which should be adapted to the texture size. (for example textureResolution/5
or textureResolution/10
etc… It depends on how fast you want to be able to paint)
++
Tricotou
Hi @Tricotou
I have a model like this and its texture size is 4096*4096. But I cannot paint in that correctly. When I paint in its leg it will paint in its face because of the texture wrapped around. How to calculate the correct UV and draw smoothly for all models like this
Refer this PG for reference and load your GLB model and its texture in the placeholder