[SOLVED] Cylindrical UV Mapping

Started by
2 comments, last by Zakwayda 17 years, 3 months ago
Advertisement
Endurion
Author
5,545
June 21, 2006 05:02 AM
Hi, i'm working on my model editor (don't ask :) ), and i'm trying to implement cylindrical UV mapping. For this kind of mapping i'm providing an axis which is supposed to be the center of the mapping. I get the vertical texture coordinates just fine but i'm seriously stuck with the horizontal coordinates. I tried using the acos of the dot product, but that to only gets me the relative angle between the current position in regards to a default "starting" position. Next i tried without the acos and simply mapping the dot product directly on the horizontal texture coordinates. This kind of worked, but it basically mapped the horizontal coordinates on the front and the back (the texture was mapped two times, one time mirrored). So i figured i'd need an absolute angle value but this is where i struggle right now. I was thinking along the lines of projecting the two 3d vectors onto a plane perpendicular to the cylinders axis. That's where i'm pretty much stuck. Let the yellow box be one of the vertices. The red line is the vector to the closest point on the axis. The green line is my default vector. I need the angle from the red line to the green line in the full range from 0 to 360. The absolute distance will not suffice. The axis can show in any direction; it isn't necessarily one of the unit axis (e.g. not 0,0,1, but also 2,3,2). I have: The virtual axis of the cylinder (two points forming a line). I pick the distance from the first vertex to the closest point on the axis as my "start" direction vector for the horizontal mapping. For every vertex i calculate the closest point on the axis. From this i get a vector. Using the closest point i do a simple calculation to get the vertical texture coordinates (factor equals where on the axis lies this closest point). How can i get the absolute (or relative) angle to my default "start" vector? I need the angle only in one direction (CW or CCW doesn't matter), the angle distance is not enough. I'm thankful for every hint i can get! PS: Please go easy on the algebra, i'm not too fluent with it. [Edited by - Endurion on June 21, 2006 9:16:52 AM]

Fruny: Ftagn! Ia! Ia! std::time_put_byname! Mglui naflftagn std::codecvt eY'ha-nthlei!,char,mbstate_t>

Zakwayda
June 21, 2006 07:40 AM
In 3D you need a frame of reference to determine the signed angle; in your case the reference is the central axis.

The first step is to find the unsigned angle. You can use acos() for this, but if you have atan2() available I'd use that instead, like this:
angle = atan2(length(cross(v,default)),dot(v,default));
Where 'v' is your red vector and 'default' is your green vector. The sign of the angle can then be determined from the direction of the cross product:
if (triple_product(axis,v,default) < 0.0) angle = -angle;
In case you're not familiar with it, the triple product of three vectors a, b and c can be computed as dot(a,cross(b,c)).

The resulting angle will be in the range [-pi,pi], which you can adjust if you need it in a different range.
Endurion
Author
5,545
June 21, 2006 09:16 AM
Awesome, works like a charm!

Only tiny problem, i get wrap-around on the seam, but that i was aware of before. I can deal with that (*hackahacka*).

Thanks, you saved my day! Rating++

Fruny: Ftagn! Ia! Ia! std::time_put_byname! Mglui naflftagn std::codecvt eY'ha-nthlei!,char,mbstate_t>

Zakwayda
June 21, 2006 05:25 PM
Quote:Original post by Endurion
Only tiny problem, i get wrap-around on the seam...
Yup, indeed. One solution is to mirror the texture for the second half, i.e. s goes from 0 to 1 for the first half around, and then from 1 to 0 for the second half (i think maybe this is what you were doing before). Also, if the texture is tiled it seems you could detach the cylinder surface (duplicate the vertices) where it wraps around to get the proper results (haven't tried this myself, but it seems like it should work).

This topic is closed to new replies.

Advertisement