Sign in to follow this  
indexunknown

Texture coordinates at a point on triangle

Recommended Posts

Hi, i seem to have trouble figuring out texture mapping coordinates on a random point that is on a 3D triangle. i know the texture coordinates on the corners and i know where the point is on triangle, but it seems complicated to find out what the texture coordinates are for the random point. i tried the barycentric coordinates but i couldn't get them to work cause i didn't understand that much. Can anybody point some directions? EDIT:SOLVED from http://www.blackpawn.com/texts/pointinpoly/default.html given a triangle with corners p1,p2,p3 ,UVs: uv1,uv2,uv3 and a point on triangle called newp then the uv coordinates are:
    // Compute vectors 
    cml::vector3f v0 = p3 - p1;
    cml::vector3f v1 = p2 - p1;
    cml::vector3f v2 = newp - p1;

    // Compute dot products
    float dot00 = cml::dot(v0, v0);
    float dot01 = cml::dot(v0, v1);
    float dot02 = cml::dot(v0, v2);
    float dot11 = cml::dot(v1, v1);
    float dot12 = cml::dot(v1, v2);

    // Compute barycentric coordinates
    float invDenom = 1 / (dot00 * dot11 - dot01 * dot01);
    float u = (dot11 * dot02 - dot01 * dot12) * invDenom;
    float v = (dot00 * dot12 - dot01 * dot02) * invDenom;
						
    cml::vector2f t2 = uv2-uv1;
    cml::vector2f t1 = uv3-uv1;

    cml::vector2f newuv = uv1 + t1*u + t2*v;


[Edited by - indexunknown on April 28, 2010 1:37:41 PM]

Share this post


Link to post
Share on other sites
Some C++ code aswell :

[CODE]

// 2 random numbers
float s = randgen.rand();
float t = randgen.rand();

// From Graphic Gems 1
float a = 1 - (float)sqrt(t);
float b = (1-s) * (float)sqrt(t);
float c = s * (float)sqrt(t);

// texcoord : pt0 texcoords of the edge0 of the triangle, etc..
vec2 sampletcoord = pt0*a + pt1*b + pt2*c;

[/CODE]

Enjoy !

Share this post


Link to post
Share on other sites
thanks szecs, i tried your code from the second link where you make the triangle coordinate systems, but i seem to have big errors.

example output for 1 new point:
new point = (5.72205e-006, 20.4426, 46.072)
p1 = (5.19205, 20.4426, 46.072) , p2 = (-4.7633, 20.4426, 46.072) , p3 = (-4.76329, 11.026, 46.072)
uv1 = (1, 1) , uv2 = (0, 1) , uv3 = (0, 0)
e1 = (-9.95535, 1.90735e-006, 0) , e2 = (-9.95535, -9.41661, -3.8147e-006), n = (-1, 3.6736e-007, 0)
x_a = (-1, 1.9159e-007, 0) , y_a = (-1.9159e-007, -1, -4.05103e-007)
(x_a1,y_a1) = (9.95535, 2.27374e-013) , (x_a2,y_a2) = (9.95535, 9.41661)
m_a = (x_am,y_am) = (1, -1.75769e-007) , mb = (x_bm,y_bm) = (1, -1.75769e-007)
m_b_mod = (x_m_mod,y_m_mod) = (0.100449, -1.86659e-008)
t1 = ( -1 0), t2 = ( -1 -1)
newUV = ( -6.26493e-008 1)

left-original , on the right with new points on the side
uvmess

Share this post


Link to post
Share on other sites
I don't understand this:
"left-original , on the right with new points on the side"

Is it a ray-tracer?
Or do you just insert a new vertex into a triangle?

Please clarify what you want to do.
A wire-frame image would be useful too.

Ant which/where is the new point? Sorry, those numbers are hard to follow for me.

Share this post


Link to post
Share on other sites
its a cube with a texture, on the left of image is a side of it having 2 triangles, on the right, it has been split up into an octree so the 2 triangles are divided into like 8 small ones so the new triangles need uvs for their corners. i know such splitting is bad but i just need to do it now.new point is one corner of one new triangle, i don't know which of them this one is but the triangles are all correct.

mspaint auto generated some wires:


[Edited by - indexunknown on April 28, 2010 10:40:12 AM]

Share this post


Link to post
Share on other sites

for(unsigned int i = 0; i< tris.size();i++){
std::vector<cml::vector3f> tri = tris.at(i);
std::vector<cml::vector2f> uvs;
for(unsigned int j = 0; j<3 ;j++){

cml::vector3f newp = tri[j];
if(newp == p1){
uvs.push_back(uv1);
continue;
}else if(newp == p2){
uvs.push_back(uv2);
continue;
}else if(newp == p3){
uvs.push_back(uv3);
continue;
}

cml::vector3f e1 = p2 - p1;
cml::vector3f e2 = p3 - p1;
cml::vector3f n = cml::normalize(newp - p1);

cml::vector3f x_a = cml::normalize(e1);
cml::vector3f y_a = cml::normalize(cml::cross(cml::cross(e1,e2),e1));

float x_a1 = cml::dot(e1,x_a);
float y_a1 = cml::dot(e1,y_a);
float x_a2 = cml::dot(e2,x_a);
float y_a2 = cml::dot(e2,y_a);

float x_am = cml::dot(n,x_a);
float y_am = cml::dot(n,y_a);
cml::vector2f m_a =cml::vector2f(x_am,y_am);

float x_bm = x_am - ( x_a2/y_a2 )*y_am;
float y_bm = y_am;
cml::vector2f m_b =cml::vector2f(x_bm,y_bm);

float x_m_mod=x_bm/x_a1;
float y_m_mod=y_bm/y_a2;
cml::vector2f m_b_mod =cml::vector2f(x_m_mod,y_m_mod);

cml::vector2f t1 = uv2 - uv1;
cml::vector2f t2 = uv3 - uv1;

cml::vector2f newuvs = uv1 + t1*x_bm + t2*y_bm;

uvs.push_back(newuvs);
}

this->nodeMesh.push_back(NodeTriangle());
this->nodeMesh.back().material = o.material;
this->nodeMesh.back().material.diffuseColor[0] = rand()%60 *0.01f;
this->nodeMesh.back().material.diffuseColor[1] = rand()%60 *0.01f;
this->nodeMesh.back().material.diffuseColor[2] = rand()%60 *0.01f;
this->nodeMesh.back().material.diffuseColor[3] = 1.0f;
this->nodeMesh.back().normal = o.normals[index];
this->nodeMesh.back().p1 = tri[0];
this->nodeMesh.back().uv1 = uvs[0];
this->nodeMesh.back().p2 = tri[1];
this->nodeMesh.back().uv2 = uvs[1];
this->nodeMesh.back().p3 = tri[2];
this->nodeMesh.back().uv3 = uvs[2];
}

Share this post


Link to post
Share on other sites
if n = newp - p1, then i got lots of small images of the texture on every triangle.
if i then did
newuvs[0] = 260*newuvs[0]; texture size
newuvs[1] = 256*newuvs[1];
then i got a grey square and if after this i did
newuvs = cml::normalize(newuvs);
then its just random stretched mess.

Share this post


Link to post
Share on other sites
always post pictures please.

You don't have to multiply the result with the image sizes. Think a bit. Your original UVs are in 0...1.

This way you will get 0...2xx. Of course it's screwed.

Share this post


Link to post
Share on other sites
1)left picture: n = newp - p1;

2) middle picture:
n = newp - p1;
and
newuvs[0] = 260*newuvs[0]; texture size
newuvs[1] = 256*newuvs[1];
3) right picture:
n = newp - p1;
...
newuvs[0] = 260*newuvs[0]; texture size
newuvs[1] = 256*newuvs[1];
newuvs = cml::normalize(newuvs);

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this