Change color on a geomnode?

Sorry for the basic question, but I’m using LineSeg to have my object trace out a line as it moves. I’d like the line to fade away after a certain amount of time, so I figured I would change the alpha value, but I can’t seem to write something that works. GeomNode doesn’t have a setColor function, and when I try to call setColor on the NodePath containing that GeomNode, nothing happens. Incidentally, when I try to call getColor on that NodePath, I get an error message “:pgraph(warning): get_color() called on render/path which has no color set.”

I tried looking deep into GeomNode and I see that it stores the color in VertexData, but a) I couldn’t get a modifiable reference to the VertexData and b) it feels way too low level to have to modify VertexData to get the color I want. Surely there’s a better way?

Would “setColorScale” (or “setAlphaScale”) work, perhaps, called on your NodePath?

I was able to get it with the following sequence of commands on my GeomNode:

c = struct.pack('BBBB', 0, 0, 255, 255) # need to import struct for this. For some reason this is BGRA
myGeomNode.modifyGeom(0).modifyVertexData().modifyArray(0).modifyHandle().setSubdata(12, 4, c)

I found 12 and 4 by examining the result of myGeomNode.modifyGeom(0).modifyVertexData().modifyArray(0) in my debugger, and also the results of .getSubData

I tried setColorScale, but it didn’t quite do the same thing. It looks like it only applied to part of the geometry or something.

The particular solution I have works for my particular case where I know the geometry and how it changes really well, but there’s got to be a more general solution.

You can use GeomVertexWriter() and GeomVertexRewriter(), see https://docs.panda3d.org/1.10/python/programming/internal-structures/other-manipulation/more-about-reader-writer-rewriter to alter the values of your vertex data object, it’s a bit more user friendly, you don’t have to use any struct or memory modification stuff.

Thanks @eldee, between this and your help on the floating point issue I ought to pay you :smiley:

@Thaumaturge it turns out that setColorScale doesn’t work because it multiplies the color in the GeomNode with the value supplied. I guess I could make the base color 1,1,1,1 and then use colorscale to set it and change it.

1 Like

Although I never use LineSegs, I do see it has a set_vertex_color method, so you could iterate over the created vertices and change their colors individually.
There is also a set_color method, but it only sets the color for vertices that will be created afterwards, not for existing vertices.

Of course, both these methods set specific vertex colors, while what you want is to set the general “scenegraph” color. The reason that calling set_color on your NodePath doesn’t work, is that the RenderState associated with the LineSegs Geom itself contains a ColorAttrib whose color type is explicitly set to vertex. You can see this by printing the RenderState:

print(lines_nodepath.node().get_geom_state(0))

The easy solution that you are looking for is to simply pass a priority value bigger than zero into the set_color call on your NodePath:

lines_nodepath.set_color(color, 1)

This will override the vertex colors when rendering your lines geometry, so you don’t even need to mess with those.

1 Like