Painting a triangle - VertexTexCoords
Blitz3D Forums/Blitz3D Programming/Painting a triangle - VertexTexCoords
| ||
I am creating meshes by plotting 4 points, creating the vertices and adding triangles, so basically I end up with a 4 sided poly. (I'm trying to paint different textures on the ground which is completely flat.) I want to paint this mesh with a brush without the texture getting distorted but I don't know how to calculate the vertex u and v scales. For example, in this image I want the texture on the right mesh to look identical to the one on the left and not get stretched. ![]() AddVertex(s,x[pointorder[0]],0,-y[pointorder[0]],0,0) AddVertex(s,x[pointorder[1]],0,-y[pointorder[1]],0,1) AddVertex(s,x[pointorder[2]],0,-y[pointorder[2]],1,1) AddVertex(s,x[pointorder[3]],0,-y[pointorder[3]],1,0) AddTriangle(s,0,1,2) AddTriangle(s,2,3,0) Can anyone help? |
| ||
The best way, i can think of, is to find the rightmost vertex, leftmost vertex, the top most vertex, and the bottom most vertex. From those numbers, you can use the vertexX() Y() and Z() (shouldn't need one of those, depending on which plane your flat against) and calculate your UV's For instance: Left most vertex = -1,-1,0 Right most vertex = 1,0,0 topmost = -0.5,1,0 bottommost = -1,-1,0 I've generated these vertex-cords, to roughly match your shape. Now, you must scale the width and height of your shape, to fit into 1 unit. I'd choose a scale based on either the height, or the width, so: rightmost - left most = 1 - -1 = 2 So, for every 2 units, you will span a UV co-ords unit of 1, starting at the leftmost vertex for the x axis, and the bottom-most vertex for the y axis. SO your start co-ords will be the leftmost vertex. so, for every co-ords you will be doing: leftmost vertex X + difference between leftmost vertex X and the current one. codewise that would: VertexX(leftmost) + (VertexX(Vertex you want to get UV's) - VertexX(leftmost)) I'll knock up a demo to demonstrate :) |
| ||
Ok, i got this. Based on the technique i mentioned above. Only problem is, the UV's will scale to the size of the mesh. I suppose you can scale the texture. But it gives you a start point. I've wrapped it into a function, so generate your mesh, include my globals statement containing the "upmost", "leftmost", "rightmost", and "downmost" vars, and of course my leftmost functions etc :) Press the 2 key to generate the UV's. Graphics3D 800,600 SetBuffer BackBuffer() Global camera = CreateCamera() PositionEntity camera,0,0,-10 Global mesh = CreateMesh() Global surface = CreateSurface(mesh) Global leftmost#,rightmost#,upmost#,downmost# v0 = AddVertex(surface,-1,-1,0) v1 = AddVertex(surface, 0, 1,0) v2 = AddVertex(surface, 1, 2,0) v3 = AddVertex(surface, 3,-3,0) AddTriangle(surface,v0,v1,v2) AddTriangle(surface,v0,v2,v3) UpdateNormals mesh Global texture = CreateTexture(256,256,1) SetBuffer TextureBuffer(texture) Color 255,255,255 Rect 0,0,256,256 Color 255,0,0 Rect 2,2,252,252 Color 200,0,0 Rect 10,10,236,236 Color 150,0,0 Rect 30,30,196,196 SetBuffer BackBuffer() Color 255,255,255 EntityTexture mesh,texture Global light = CreateLight() While Not KeyHit(1) If KeyHit(2) Then generate_UVs(surface) End If RenderWorld Flip Wend Function generate_UVs(surface) find_leftmost(surface) find_rightmost(surface) find_upmost(surface) find_downmost(surface) x_dif# = rightmost - leftmost y_dif# = upmost - downmost Local verts = CountVertices(surface) For loop = 0 To verts-1 VertexTexCoords(surface, loop, (VertexX(surface,loop)-leftmost)/x_dif, (VertexY(surface,loop)-downmost)/y_dif) Next End Function Function find_leftmost(surface) leftmost = 99999 Local verts = CountVertices(surface) For loop = 0 To verts-1 If VertexX(surface,loop) < leftmost Then leftmost = VertexX(surface,loop) End If Next End Function Function find_rightmost(surface) rightmost = -99999 Local verts = CountVertices(surface) For loop = 0 To verts-1 If VertexX(surface,loop) > rightmost Then rightmost = VertexX(surface,loop) End If Next End Function Function find_upmost(surface) upmost = -99999 Local verts = CountVertices(surface) For loop = 0 To verts-1 If VertexY(surface,loop) > upmost Then upmost = VertexY(surface,loop) End If Next End Function Function find_downmost(surface) downmost = 99999 Local verts = CountVertices(surface) For loop = 0 To verts-1 If VertexY(surface,loop) < downmost Then downmost = VertexY(surface,loop) End If Next End Function |
| ||
Awesome! I just needed to scale the texture as you said and it works perfectly. Thanks Ross. :) |
| ||
No worries :) |