Add texture to a spatial at specific coordinates

Hello guys,



This is my first post on this forum, so I take the opportunity to thank you for this excellent 3d gaming engine.



I have the following problem to solve. I have a spatial (the hi-res character) with its own material. I need to “select” an “mark” (i.e. With a different color) a part of the body (such as an arm or a leg) using the mouse pointer. For example, I want to click on a point on the arm of the character, and get the character’s skin change it’s color where I clicked with the mouse.



Assumed that I can catch the specific coordinates on the spatial corresponding to the mouse pointer via ray casting, my question is: how to actually color that spotted area?



I tried many solutions, but I couldn’t get it to work.


  1. First of all, I tried to assign a texture to the character’s spatial, and position it to the raycasted coordinates. However, I don’t see how to actually specify the coords of the texture on the spatial. I think that this is a problem similar to add a “hit” mark (such as a blood stain texture) on a shot enemy when hit. How could it be solved?


  2. Second, I tried with a PaintableTexture (see the plugins area), which is a texture that can be painted manually, pixel by pixel. I can easily paint the spotted areas on the texture and then I can apply it to the spatial, However, after applying the texture to the spatial, it’hard to predict its exact position (and the origin) that the texture will be painted over the spatial: therefore, the painted area won’t correspond to the selected area after applying the texture. I think the best way would be an UV texture generated programmatically.



    Any advice?

Maybe if you got the closest vertex in the spatial to your ray.

Then find the position of that vertex in uv.

Then you must go outside of jme and edit the image then replace the previous image with the new edited image.



Im not sure, but when you say blood stain texture, it got me thinking of splat textures and heightmap textures.

Dunno why (mainly because I dont even know what splat textures are), but Im just throwing ideas that may be at any value to someone…

1 Like

Hello,



And thank you for your prompt reply :slight_smile:



How exactly do you suggest to “find the position of that vertex in UV” ?



Can you provide an example?



I don’t see any way to get that coords in JME starting from the closest vertex.



Thank you!

I am also interested in this, if you solve it please tell me. Here is the general idea :

  1. bloodPosition = find supposed position the blood should be.
  2. minBloodPosition = find nearest vertex to the bloodPosition : and its Index (BloodIndex).
  3. BloodIndex, BloodIndex+1, BloodIndex+2 forms a triangle, so you will put the texture in the triangle.
  4. change the uv’s add an alpha texture with blood there.
  5. warning if u change the uv’s it will mess with your existing texture which u dont want. Use Type.TexCoord2 ?
  6. complete



    Mini code on how to get vertex positions / indexes :

    [java]



    public static void paintBlood(Mesh mesh, Vector3f bloodPosition)

    VertexBuffer vertex = mesh.getBuffer(Type.Position);

    float[] vertexArray = BufferUtils.getFloatArray((FloatBuffer) vertex.getData());



    VertexBuffer index = mesh.getBuffer(Type.Index);

    short[] indexArray = Utilities.getShortArray((ShortBuffer) index.getData());



    VertexBuffer normal = mesh.getBuffer(Type.Normal);

    float[] normalArray = BufferUtils.getFloatArray((FloatBuffer) normal.getData());



    VertexBuffer uv = mesh.getBuffer(Type.TexCoord);

    float[] uvArray = BufferUtils.getFloatArray((FloatBuffer) uv.getData());



    float minDistanceFromBloodPosition = 999999 ;

    Vector3f minBloodPosition ;



    for (int i = 0; i < indexArray.length; i += 3)

    {

    short index1 = indexArray;

    short index2 = indexArray;

    short index3 = indexArray;



    Vector3f p1 = new Vector3f(vertexArray[index1 * 3], vertexArray[index1 * 3 + 1], vertexArray[index1 * 3 + 2]);

    Vector3f p2 = new Vector3f(vertexArray[index2 * 3], vertexArray[index2 * 3 + 1], vertexArray[index2 * 3 + 2]);

    Vector3f p3 = new Vector3f(vertexArray[index3 * 3], vertexArray[index3 * 3 + 1], vertexArray[index3 * 3 + 2]);



    //Find closest position to bloodPosition

    //…



    }//for i

    }

    [/java]

The easiest way would be to use two textures. One texture is the basic skin texture and the second texture would be an overlay with the specific part selected, so one texture where the arm is green, the other where the leg is green etc. and depending on what you click you can determine from the nearest vertex whether you clicked an arm or leg. If you have only some body parts that would be done fairly easy and fast.

Hello,



and thank you for your code snippet. Good about coordinates, but the point here is: how to assign the texture to the spatial at the wanted position without repetition?



I read on wikipedia (http://en.wikipedia.org/wiki/Clamping_(graphics) ) that (maybe?) the technique to achieve this is called texture clamping .



Wikipedia says: " One of the many uses of clamping in computer graphics is the placing of a detail inside a polygon—for example, a bullethole on a wall. It can also be used with wrapping to create a variety of effects."



Does JME3 support clamping? How to position the texture at specific coordinates and avoid repetition?



Thank you.

Dodikles said:
The easiest way would be to use two textures. One texture is the basic skin texture and the second texture would be an overlay with the specific part selected, so one texture where the arm is green, the other where the leg is green etc. and depending on what you click you can determine from the nearest vertex whether you clicked an arm or leg. If you have only some body parts that would be done fairly easy and fast.


Thank you for your suggestion.

This is a good and quick solution, but it requires to pre-determine the "hot areas" which are selectable (i.e. the leg, the arm, etc..). However, this approach becomes quickly hard to use when we need a more precise selection (i.e. a specific part of the arm, where the "bullet impacts", for example).
how to assign the texture to the spatial at the wanted position without repetition?

Choose the specific triangle the bullet impacted. Add the texture there.

Yea, tralalas method seems perfect for this.

given the mesh and the closestCollision().getWorldTranslation().substract(mesh.getWorldTranslation()

should give the closest triangle.

Then you can use maybe Graphics2D to repaint the image.

Having a overlapping image would require special materials I think…

tralala said:
Choose the specific triangle the bullet impacted. Add the texture there.

The Triangle class has no method to assign the texture directly. I can get the coordinates, but I can only add the texture to a material, and then the material to the spatial. No way to add the texture to that specific triangle,

Any advice?

@parsifino1:



I really think that you want to mention a “decal system” which display bullet holes or blood in a geometry. They are still not exist in JME yet and you definitely can be the creator :stuck_out_tongue:



Take a look a here please :



http://www.unitymagic.com/shop/en/unity-decal-framework/ ← Decal system in Unity Engine

How to project decals - Wolfire Games Blog ← Decal system in Wolfire Engine



P/s: If you just want to “point and paste” one bullet hole or may be one texture in a geometry… I think you will find it in the @tralala 's answer, please read it carefully ( Or you misunderstood something… The method really there) :stuck_out_tongue: .



What you need is definitely a “shader” which can deal with the additional texture in the TexCoord2 , draw the texture in the surface onetime only and then blend the edge with the current (diffuse, normal) texture.



<= I don’t really know is this true : “If we have more TexCoord (16 or as many as we wish) for a geometry, we can do like they did in Wolfire”??? Or other method is avaiable ?

Can i simple attach/stick image to some object(spatial)?

I have sing/billboard with animations simulating wind effect. So i wanna that he(billboard) show my score > this i creted by NiftyToMesh BUT i can’t simple setmaterial to model because my it would look like scribble (at difrent model than box it look really aweful) + i don’t need see gui at all side. Animation defend me construct simple picture before model if i wanna have animation in my game.