Lighting issues, how to find the node receiving a light ?

I am trying to build a framework, which will have a generic user interface to manipulate the panda object through wxpython (but this is not a scene editor…)

One of the function is to turn on and off the lights on the scene.

On the UI side, it does not know what the application is doing and need to find out which nodepath the light is set to.

I tried to avoid finding this, by setting the light color to completely black when user wants turn off the light. I know that there may be performance penalty, but it may be the easiest way to implement. However, it does not work for point light and spotlight. There still some visible light when the color is set to (0,0,0).

Second thought is, I would like to ask, if there is a function call to get the nodepath collections from the light itself. If there is such information, I can easily clearLight on them.

The third option is, traverse the nodepath tree, and find out which nodepath has the light casted on. But the nodepath class only has the method hasLight(). There seems no function to get back the light object from the nodepath ?

The final option is, make my own application information for me to get back this information later in my UI framework. This is the last option I consider.

Can you please give me some help on this ?

You can grab lights from node’s LightAttrib.

np.getAttrib(LightAttrib.getClassType())

A better way is by recording every nodepath a light is set to.

LIGHTS={}

def newsetLight(np, lnp, pri=0):
    np.origsetLight(lnp, pri)
    if lnp in LIGHTS:
       LIGHTS[lnp].add(np)
    else:
       LIGHTS[lnp]=set([np])

NodePath.DtoolClassDict["origsetLight"]=NodePath.setLight
Dtool_funcToMethod(newsetLight,NodePath,"setLight")

That’s for setting a light on. For clearing or setting it off, I hope you know what to do.

Excellent ! It works very well.

I do not realize there are Dtool functions. Some other posts mentioned it is not publicly supported api and may be removed without notice in the future. Is it generally available and supported currently?

Removing it would be extremely stupid.
Any link about that ?

I read it here recently:
discourse.panda3d.org/viewtopic.php … a1292e24b1

It might happen if they have translated ALL extensions down to C++.
Considering the number of the extensions, I doubt it will happen anytime soon. And if eventually the ability to extend classes at runtime is decided to be taken away, it would be major loss, at least for me.

They are so eager in cutting down development time by doing it this way. So, if it happen anyway, it means they’ve shot their own foot.

Hm. Well, you’re the only one I know who has found these internal mechanisms and uses them directly. So I guess we’ll have shot your foot only. :slight_smile:

Really, the DtoolClassDict is a private, internal construct. It exists because it is needed internally, but it was never intended to be used directly by Python programmers. One day, we do want to phase out its use, and all of the so-called “extension” functions, because the need to import PandaModules instead of libpanda or libdirect is a sloppy, non-pythonic wart. We’ve been looking for a different way to implement these extension functions.

That’s not to say that we want to take away the ability to extend classes at runtime. It’s just that we didn’t intentionally add that ability in the first place.

I’m not 100% convinced that changing the behavior of NodePath.setLight() is a great idea, anyway. It makes the code hard to read and introduces mysterious bugs if it gets copied-and-pasted to other applications.

David

If it’s only ClassDict is going to be taken away, it’s no big deal. I just need to store the original function so it doesn’t get lost. Storing it in the ClassDict indeed sounds so abusive, doesn’t it ? Sure I can store it somewhere else, no problem at all, I just need to pass the instance for the first argument to the original function.