Issue with hemisphere part with textures


Issue with hemisphere part with textures
#1
This affects the textured parts 61287p01.dat,  61287p02.dat,  61287p03.dat,  61287p04.dat: "Cylinder Hemisphere  2 x  2 with Cutout" with textures

The textures for these parts show Mercator-like maps. The Mercator projection is an example of a CYLINDRICAL projection (See https://en.wikipedia.org/wiki/Mercator_projection, which references https://archive.org/details/Snyder1987Ma...1/mode/2up).

But the part has defined a SPHERICAL texture map. This makes the lines of latitude curved instead of straight.

The fix is a one line change in each file, like so:

0 !TEXMAP START CYLINDRICAL 0 0 0 0 -46 0 -26 0 0 180 61287p01rb.png

replacing with the appropriate png file in each case.
Reply
RE: Issue with hemisphere part with textures
#2
I can't get that code to work.
The image is upside down, and the equator misplaced.
Reply
RE: Issue with hemisphere part with textures
#3
(2024-01-15, 20:26)Magnus Forsberg Wrote: I can't get that code to work.
The image is upside down, and the equator misplaced.

My apologies, I've fixed the equator (the bottom of the hemisphere is truncated which I had not taken into account):
0 !TEXMAP START CYLINDRICAL 0 6 0 0 -46 0 -26 6 0 180 61287p01rb.png

But I think the image ought to be the right way up, given this definition. The first three numbers are the centre point of the base of the cylinder, and the next three are the top centre of the cylinder. With LDraw's coordinate system having -Y up, that should be the right way up.

I see the image appears upside down in LDView. I wonder if that could be a bug in LDView?
Reply
RE: Issue with hemisphere part with textures
#4
(2024-01-15, 21:17)Toby Nelson Wrote: I see the image appears upside down in LDView. I wonder if that could be a bug in LDView?

This is what I see:

   

Your code is placing the image upside down
Reply
RE: Issue with hemisphere part with textures
#5
(2024-01-15, 21:17)Toby Nelson Wrote: My apologies, I've fixed the equator (the bottom of the hemisphere is truncated which I had not taken into account):
0 !TEXMAP START CYLINDRICAL 0 6 0 0 -46 0 -26 6 0 180 61287p01rb.png

But I think the image ought to be the right way up, given this definition. The first three numbers are the centre point of the base of the cylinder, and the next three are the top centre of the cylinder. With LDraw's coordinate system having -Y up, that should be the right way up.

I see the image appears upside down in LDView. I wonder if that could be a bug in LDView?

I believe that you are correct regarding LDView displaying cylindrical textures upside down. Can you confirm that LDCad displays them the other way around?

However, regarding the part being wrong to use SPHERICIAL, I think that you are wrong about that. The texture is definitely not designed to be used as a Mercator projection. Switching to CYLINDRICAL squishes everything vertically. And while I don't exactly understand why, the lines of latitude are correct with SPHERICAL projection in this part. (Just look at it directly from the side with the original SPHERICAL projection.) While using CYLINDRICAL with an appropriate texture would probably make more sense, the existing texture is definitely not right for that.
Reply
RE: Issue with hemisphere part with textures
#6
(2024-01-15, 22:33)Travis Cobbs Wrote: I believe that you are correct regarding LDView displaying cylindrical textures upside down. Can you confirm that LDCad displays them the other way around?

However, regarding the part being wrong to use SPHERICIAL, I think that you are wrong about that. The texture is definitely not designed to be used as a Mercator projection. Switching to CYLINDRICAL squishes everything vertically. And while I don't exactly understand why, the lines of latitude are correct with SPHERICAL projection in this part. (Just look at it directly from the side with the original SPHERICAL projection.) While using CYLINDRICAL with an appropriate texture would probably make more sense, the existing texture is definitely not right for that.

Your proposed CYLINDRICAL looks like this (after me flipping things in LDView's code):


.png   61287p01.png (Size: 22.55 KB / Downloads: 129)

The original SPHERICAL looks like this:


.png   61287p01-spherical.png (Size: 22.88 KB / Downloads: 129)

Both images were taken with LDView's FOV set to 0.1.

Notice that all three visible lines of latitude are horizontal on both images. Notice also that the spherical one has more correct aspect ratio of the map. (The cylindrical one has the continents squished vertically.)
Reply
RE: Issue with hemisphere part with textures
#7
Actually, I think that using CYLINDRICAL is good, it's just that you didn't have it extend far enough. I tweaked the parameters to be this:

0 !TEXMAP START CYLINDRICAL 0 16 0 0 -56 0 -26 6 0 180 61287p01rb.png

(10 LDU added to top and bottom.) That results in the following, which is probably most correct:


.png   61287p01-cyl2.png (Size: 23.13 KB / Downloads: 125)

Note that the lack of texturing on the top cone is due to a limitation in the way the mapping is being applied. It doesn't like the cone at the top (or more specifically it doesn't like having triangles that contain a point that is on the cylindrical axis). I don't think that there is anything I can do to fix that. The spherical mapping has different issues up there.
Reply
RE: Issue with hemisphere part with textures
#8
(2024-01-15, 22:33)Travis Cobbs Wrote: I believe that you are correct regarding LDView displaying cylindrical textures upside down. Can you confirm that LDCad displays them the other way around?

However, regarding the part being wrong to use SPHERICIAL, I think that you are wrong about that. The texture is definitely not designed to be used as a Mercator projection. Switching to CYLINDRICAL squishes everything vertically. And while I don't exactly understand why, the lines of latitude are correct with SPHERICAL projection in this part. (Just look at it directly from the side with the original SPHERICAL projection.) While using CYLINDRICAL with an appropriate texture would probably make more sense, the existing texture is definitely not right for that.

LDCad doesn't seem to be available on Mac, so I can't easily check.

A cylindrical projection is by definition one that keeps the lines of latitude parallel. So the texture is definitely designed to be used with a cylindrical projection. From the wikipedia page:
Quote:A normal cylindrical projection is any projection in which meridians are mapped to equally spaced vertical lines and circles of latitude (parallels) are mapped to horizontal lines.

LDView is I believe wrong in its decoding of the SPHERICAL type projection too.
Reply
RE: Issue with hemisphere part with textures
#9
If it's useful, this is the relevant Python code I'm using in my Blender importer:

Code:
def signed_angle(a, b, normal):
    # See https://stackoverflow.com/a/33920320
    s = a.cross(b).dot(normal)
    c = a.dot(b)
    return math.degrees(math.atan2(s, c))



pt1 = mathutils.Vector( (textureMap.x1, textureMap.y1, textureMap.z1) )
pt2 = mathutils.Vector( (textureMap.x2, textureMap.y2, textureMap.z2) )
pt3 = mathutils.Vector( (textureMap.x3, textureMap.y3, textureMap.z3) )

# Pre-calculate useful values
len_p1p2 = (pt2 - pt1).length
len_p1p3 = (pt3 - pt1).length

if textureMap.projType == 'PLANAR':
    n1 = (pt2 - pt1).normalized()
    n2 = (pt3 - pt1).normalized()
elif textureMap.projType == 'CYLINDRICAL':
    n1 = (pt2 - pt1).normalized()
elif textureMap.projType == 'SPHERICAL':
    # take the cross product of the two vectors extending from pt2 to get a third vector n3 at right angles to those.
    n3 = (pt1 - pt2).cross(pt3 - pt2).normalized()
    n2 = (pt1 - pt2).cross(n3).normalized()

for i in range(len(newPoints)):
    # Get the point in question (scaling the point back to original ldraw size, just for the purposes of UV coordinate calculation)
    pt = mathutils.Vector( newPoints[i] / globalScaleFactor )

    if textureMap.projType == 'PLANAR':
        # Calculate U
        if len_p1p2 > 1e-8:
            u = math.fabs((pt1 - pt).dot(n1)) / len_p1p2
        else:
            u = 0.0

        # Calculate V
        if len_p1p3 > 1e-8:
            v = math.fabs((pt1 - pt).dot(n2)) / len_p1p3
        else:
            v = 0.0

    elif textureMap.projType == 'CYLINDRICAL':
        # Calculate U
        distanceToPlane = (pt1 - pt).dot(n1)
        ptOnPlane       = pt - distanceToPlane * n1
        u  = LDrawGeometry.signed_angle(ptOnPlane - pt1, pt3 - pt1, -n1)
        u /= textureMap.a   # U is normalised
        u += 0.5            # U is centred

        # Calculate V
        if len_p1p2 > 1e-8:
            v = distanceToPlane / len_p1p2
        else:
            v = 0.0

    elif textureMap.projType == 'SPHERICAL':
        # Calculate U
        distanceToPlane = (pt - pt1).dot(n3)
        ptOnPlane       = pt - distanceToPlane * n3

        u  = LDrawGeometry.signed_angle(ptOnPlane - pt1, pt2 - pt1, n3)
        u /= textureMap.a   # U is normalised
        u += 0.5            # U is centred

        # Calculate V
        distanceToPlane = (pt - pt1).dot(n2)
        ptOnPlane       = pt - distanceToPlane * n2

        v  = LDrawGeometry.signed_angle(ptOnPlane - pt1, pt2 - pt1, n2)
        v /= textureMap.b   # V is normalised
        v += 0.5            # V is centred

    else:
        # Unknown UV projection type
        u = 0.0
        v = 0.0
    <store uv for point>
Reply
RE: Issue with hemisphere part with textures
#10
(2024-01-15, 22:49)Travis Cobbs Wrote: Actually, I think that using CYLINDRICAL is good, it's just that you didn't have it extend far enough. I tweaked the parameters to be this:

No I don't think that's right. The top of the cylinder should be at the top of the sphere (at the north pole). And the bottom of the cylinder should be at the bottom of the sphere.
Reply
RE: Issue with hemisphere part with textures
#11
(2024-01-15, 23:05)Toby Nelson Wrote: No I don't think that's right. The top of the cylinder should be at the top of the sphere (at the north pole). And the bottom of the cylinder should be at the bottom of the sphere.

If the texture were an actual Mercator projection of the globe, then you would be correct. However, it clearly isn't, so either the texture needs to be regenerated, or the places it gets mapped to need to be adjusted. My adjustments lead to an image that (IMO) closely matches the actual part.
Reply
RE: Issue with hemisphere part with textures
#12
(2024-01-15, 23:32)Travis Cobbs Wrote: If the texture were an actual Mercator projection of the globe, then you would be correct. However, it clearly isn't, so either the texture needs to be regenerated, or the places it gets mapped to need to be adjusted. My adjustments lead to an image that (IMO) closely matches the actual part.
I think it only appears to match the part because the implementation of the cylindrical projection is incorrect in LDView. Changing the part to hide an implementation bug in LDView would not be right.

Your proposed change doesn't look right at all in my Blender importer.
Reply
RE: Issue with hemisphere part with textures
#13
(2024-01-16, 0:24)Toby Nelson Wrote: I think it only appears to match the part because the implementation of the cylindrical projection is incorrect in LDView. Changing the part to hide an implementation bug in LDView would not be right.

Your proposed change doesn't look right at all in my Blender importer.

I did some more digging, and I feel that there are probably two problems here.

First of all, a cylindrical map projection is NOT equivalent to what TEXMAP CYLINDRICAL produces. If you look at the diagrams of how cylindrical map projection works, it is done as if there is a light in the middle of the earth and everything is translucent. The cylinder that wraps around the earth then receives the projected image of the earth. When doing things this way, it's not possible to represent the north or south pole, because the cylinder would have to be infinitely tall. Also, the farther from the equator you get, the more distorted things become.

The CYLINDRICAL projection model for TEXMAP is kind of the opposite. Set up a cylinder of the given dimensions based on the TEXMAP meta, then project inward toward the axis and outward towards infinity. Any polygons in that area then received the projected texture. (Note that the problem that LDView has at the top is due to the fact that it specifies texture coordinates only for the vertices, and any vertex along the axis corresponds to every single texture coordinate at that Y value.)

Secondly, I'm pretty sure that other than being upside down, and the problem with polygons that have a vertex at the axis, there is nothing else wrong with LDView's texture projection. If you are getting results in Blender that are broken, I think there is probably something wrong with your texture projection calculations. And I also think that the textures that were created for the globe pieces were designed for spherical projection and not cylindrical projection.

If you PM me, I will send you and LDraw model I have of Earth along with a corresponding high-resolution texture. It uses spherical mapping, and you can tell visually by rotating it that if it's not correct, it's at least extremely close. Here is what it looks like when rendered by LDView:

   
Reply
RE: Issue with hemisphere part with textures
#14
(2024-01-16, 2:42)Travis Cobbs Wrote: I did some more digging, and I feel that there are probably two problems here.

First of all, a cylindrical map projection is NOT equivalent to what TEXMAP CYLINDRICAL produces. If you look at the diagrams of how cylindrical map projection works, it is done as if there is a light in the middle of the earth and everything is translucent. The cylinder that wraps around the earth then receives the projected image of the earth. When doing things this way, it's not possible to represent the north or south pole, because the cylinder would have to be infinitely tall. Also, the farther from the equator you get, the more distorted things become.

The CYLINDRICAL projection model for TEXMAP is kind of the opposite. Set up a cylinder of the given dimensions based on the TEXMAP meta, then project inward toward the axis and outward towards infinity. Any polygons in that area then received the projected texture. (Note that the problem that LDView has at the top is due to the fact that it specifies texture coordinates only for the vertices, and any vertex along the axis corresponds to every single texture coordinate at that Y value.)

Secondly, I'm pretty sure that other than being upside down, and the problem with polygons that have a vertex at the axis, there is nothing else wrong with LDView's texture projection. If you are getting results in Blender that are broken, I think there is probably something wrong with your texture projection calculations. And I also think that the textures that were created for the globe pieces were designed for spherical projection and not cylindrical projection.

If you PM me, I will send you and LDraw model I have of Earth along with a corresponding high-resolution texture. It uses spherical mapping, and you can tell visually by rotating it that if it's not correct, it's at least extremely close. Here is what it looks like when rendered by LDView:
Your first point about how cylindrical projection is different from ldraw's CYLINDRICAL is correct.

There are two problems with the extended cylinder fix you suggest. The first is that the third point is not in the base of the cylinder, which is where the spec says it should be:

Quote:The third point represents a location on the outer edge of the cylinder bottom where the center-bottom of the texture would touch.

Having fixed this, i.e.:

0 !TEXMAP START CYLINDRICAL 0 16 0 0 -56 0 -26 16 0 180 61287p01rb.png

the result looks more plausible, and I think we now mostly agree on how the cylinder projection should look (yay!). The exception is the north pole. Lines of longitude should of course in theory meet at the north pole. But I agree that without more geometry around the north pole that this is never going to look perfect. In practice the lines don't and won't meet at the north pole. But the problem I get with this taller cylinder is I now get land at the north pole, which doesn't seem authentic to the original part.

I'm going to think some more about SPHERICAL mapping next.
Reply
RE: Issue with hemisphere part with textures
#15
In particular I get that the vertex at the North pole (0 46 0) has UV value (0.5 0.13888888) which is in the middle of the land.
Reply
RE: Issue with hemisphere part with textures
#16
Here's my thoughts on SPHERICAL mapping:

The spec for SPHERICAL says:

"V is given by the angle between the vector formed by points 1 and 2 and the vector formed by point 1 and a world point that has been projected to the plane P2."

Note that P2 is the plane that goes through the north and south poles and through the line of longitude in the centre of the image.

I want to take an example world point and see how it maps to UV, given this definition.

Take a world point just above the equator at the edge of the hemisphere. It will be projected onto P2 just above the centre of the sphere, giving a vertical vector from point 1, which is at right angles to the vector formed by points 1 and 2. 

In this way all points around the rim of the hemisphere have V=0 (above the equator) or V=1 (below the equator), according to the specs.

This makes the SPHERICAL mapping unsuitable for a full globe, which is unfortunate, but that seems to be what the specs say.
SPHERICAL mapping would be useful for smaller patches, e.g. an image on the surface of an old CRT television that has curved edges.
Reply
RE: Issue with hemisphere part with textures
#17
(2024-01-16, 11:17)Toby Nelson Wrote: This makes the SPHERICAL mapping unsuitable for a full globe, which is unfortunate, but that seems to be what the specs say.
SPHERICAL mapping would be useful for smaller patches, e.g. an image on the surface of an old CRT television that has curved edges.
Many of these issues have been discussed before, e.g. my findings as posted here:
https://forums.ldraw.org/thread-13633-po...l#pid13635
and here
https://forums.ldraw.org/thread-4261-pos...l#pid27490

In short it is possible to do a full globe mapping but the mesh must be formatted to help it along, meaning it must have vertices at the poles and the texture meta must be oriented to match it.
Reply
RE: Issue with hemisphere part with textures
#18
(2024-01-16, 10:11)Toby Nelson Wrote: In particular I get that the vertex at the North pole (0 46 0) has UV value (0.5 0.13888888) which is in the middle of the land.

I'm not sure if you are referring to cylindrical or spherical mapping here. If the former, the UV coordinates are essentially undefined anywhere on the axis of the cylinder. (I think they have a valid V value, but their U value is effectively "all of the above".) If the latter, then I think the same thing happens at the north and south poles. When texture UV mapping is performed in advance, the U value can be calculated based on the U values of the other two vertices in the triangle that touches the pole. But for projected textures, I don't think this is possible.
Reply
RE: Issue with hemisphere part with textures
#19
(2024-01-16, 19:54)Roland Melkert Wrote: Many of these issues have been discussed before, e.g. my findings as posted here:
https://forums.ldraw.org/thread-13633-po...l#pid13635
and here
https://forums.ldraw.org/thread-4261-pos...l#pid27490

In short it is possible to do a full globe mapping but the mesh must be formatted to help it along, meaning it must have vertices at the poles and the texture meta must be oriented to match it.

Thanks, I will investigate further. At first glance it seems that no-one liked the spec so they have ignored it in favour of something else.
Reply
RE: Issue with hemisphere part with textures
#20
(2024-01-16, 22:01)Travis Cobbs Wrote: I'm not sure if you are referring to cylindrical or spherical mapping here. If the former, the UV coordinates are essentially undefined anywhere on the axis of the cylinder. (I think they have a valid V value, but their U value is effectively "all of the above".) If the latter, then I think the same thing happens at the north and south poles. When texture UV mapping is performed in advance, the U value can be calculated based on the U values of the other two vertices in the triangle that touches the pole. But for projected textures, I don't think this is possible.

I was thinking of the cylindrical coordinates. Yes, you are right. The U coordinate is undefined at the north pole (and would be at the south pole if we had one on our hemisphere). Taking the angle between one vector and a zero length vector isn't defined. However I've defined the angle as zero, since that's how the calculations fall out anyway. It helps the look of the model to give the vertex some UV coordinate (rather than be untextured?), and 0.5 is as good a U as any. An "average" of the UVs of nearby points if you like. As you say, at least the V coordinate is defined ok.
Reply
RE: Issue with hemisphere part with textures
#21
I just realized that LDView's spherical code has detection of points due north or due south (with some leeway) of the center point of the spherical projection. If it detects these, it hard codes the V coordinate to be either -PI/2 (north) or PI/2 (south), then calculates a U point that is halfway between the U points of the other two points in the triangle. This doesn't produce "correct" output, but it's quite a lot better than what happens without the special case code. It doesn't have equivalent code for cylindrical projections.
Reply
« Next Oldest | Next Newest »



Forum Jump:


Users browsing this thread: 8 Guest(s)