MeshDrawer "linkSegment": Unexpected UV Mapping

I’m attempting to use MeshDrawer, and in particular the “linkSegment”/“linkSegmentEnd” functions, to depict an object that can be considered more-or-less as a long, narrow strip.

In terms of geometry, this seems to work well.

Things become problematic, however, when I attempt to apply a texture to that geometry.

Specifically, the uv-coordinates (as specified via the “frame” parameter) don’t seem to work as I’d expect: (0, 0, uSize, 1) doesn’t seem to produce a mapping that starts at the horizontal edge of the texture, and (0.875, 0, 0.125, 1) seems to produce a mapping that goes past the horizontal edge of the texture. :/

To illustrate what I mean, consider the simple texture below:
numbers

When I attempt to map this to a link-segment strip, I get the following:
Screenshot from 2023-10-26 11-46-53

Note that the numbers are rendered from left to right, as expected–but that “1” appears after “4”.

I can rectify this be starting with a frame that has a negative x-value–but that makes no sense to me. :/

Here below is the simple test-program that I used to produce the above:
(Where “numbers.png” is the texture embedded above.)

from direct.showbase.ShowBase import ShowBase

from panda3d.core import MeshDrawer, OmniBoundingVolume, SamplerState, Vec4, Vec3

class Game(ShowBase):
    def __init__(self):
        ShowBase.__init__(self)

        self.meshDrawer = MeshDrawer()
        self.meshDrawer.setBudget(256)

        self.meshDrawerNP = self.meshDrawer.getRoot()
        self.meshDrawerNP.reparentTo(self.render)
        self.meshDrawerNP.setY(20)

        self.tex = loader.loadTexture("numbers.png")
        self.meshDrawerNP.setTexture(self.tex)

        self.meshDrawer.begin(self.cam, self.render)

        frame = Vec4(0, 0, 1/8, 1)
        thickness = 1
        colour = Vec4(1, 1, 1, 1)
        pos = Vec3(-4, 1, 0)

        for i in range(8):
            print ("segment", frame)
            self.meshDrawer.linkSegment(pos, frame, thickness, colour)
            frame.addX(1/8)
            pos.addX(1)

        print ("end", frame)
        self.meshDrawer.linkSegmentEnd(frame, colour)

        self.meshDrawer.end()


app = Game()
app.run()

Does anyone see where I might be going wrong…? Or is this perhaps an issue in MeshDrawer…?

As there have been no suggestions thus far, I’m guessing that this is a bug, and have reported it–see the link below:

Update: I’ve done some investigating within MeshDrawer’s code, and I think that I’ve found the source of this unexpected behaviour:

From what I saw there, it looks like at time of writing the “linkSegment” method ignores–by design–the first two frames given to it; it starts using its given frames from the third call to “linkSegment”/“linkSegmentEnd”.

Here follows a working version of the test-program that I gave above:

from direct.showbase.ShowBase import ShowBase

from panda3d.core import MeshDrawer, OmniBoundingVolume, SamplerState, Vec4, Vec3

class Game(ShowBase):
    def __init__(self):
        ShowBase.__init__(self)

        self.meshDrawer = MeshDrawer()
        self.meshDrawer.setBudget(256)

        self.meshDrawerNP = self.meshDrawer.getRoot()
        self.meshDrawerNP.reparentTo(self.render)
        self.meshDrawerNP.setY(20)

        self.tex = loader.loadTexture("numbers.png")
        self.meshDrawerNP.setTexture(self.tex)

        self.meshDrawer.begin(self.cam, self.render)

        frame = Vec4(0, 0, 1/7, 1)
        thickness = 1
        colour = Vec4(1, 1, 1, 1)
        pos = Vec3(-4, 1, 0)

        for i in range(8):
            print ("segment", frame)
            self.meshDrawer.linkSegment(pos, frame, thickness, colour)
            if i != 0 and i != 1: # SKIP THE FIRST TWO FRAME-UPDATES!
                frame.addX(1/7)
            pos.addX(1)

        print ("end", frame)
        self.meshDrawer.linkSegmentEnd(frame, colour)

        self.meshDrawer.end()


app = Game()
app.run()

(I also adjusted the U-extent used in that program’s frames, such that it now makes use of the entire texture.)

I am still having a bit of a struggle with the use of the frame parameter in my current project, but that’s due I believe to an application-specific complication, for which I might make a separate thread…