I Can Use Some Clarification on This....

This has always bewildered me…

Lets say you have a Light node path stored in the variable self.Lv5rtLT_FNP.

Now lets say you want to change the color of self.Lv5rtLT_FNP.

Why do you have to include the .node() in order to change that color, like:

self.Lv5rtLT_FNP.node().setColor(VBase4(0.4, 0.3, 0.1, 1));

Why can’t it be:

self.Lv5rtLT_FNP.setColor(VBase4(0.4, 0.3, 0.1, 1));

I always thought the .node() was retrieving a node path, but it can’t be if the variable already has it stored. or the self.Lv5rtLT_FNP is not storing a node path.

self.Lv5rtLT_FNP = self.GPlvWing5.attachNewNode(self.Lv5_HallB_LT_F);

:question:

.node() gets the “node” that is attached to a “node path”. The “node path” is always the class NodePath, while the “node” is the type of data attached to that NodePath, such as a GeomNode.
So with a piece of geometry, if you want to move it or hide it you do that on the NodePath. If you want to manipulate data specific to the geometry, you would do that on the GeomNode.

So in your example here, you are passing a node (not a node path) to the attachNewNode function, and getting a node path in return. Since you already have your light node stored in a variable you can use that without the .node() function.

self.Lv5rtLT_FNP = self.GPlvWing5.attachNewNode(self.Lv5_HallB_LT_F)
self.Lv5_HallB_LT_F.setColor(VBase4(0.4, 0.3, 0.1, 1))

It’s understandable, but the node class part is still fuzzy to me.

When you type “class”, I start thinking this:

class SomeClass():
	def __init__(self):

Or what ever programming language you use. You mentioned that when you hide an object you do that on the class, so by typing “class”… You’re really like saying… “Instance of and Object class?”

And if you’re hiding the instance of an object class, that’s like taking that class out of the render graph, which would also remove any geometry.
:question:

The Light class is the particular kind of node that is reference by the NodePath.

You can call NodePath.setColor(), but that only changes the generic color attribute, which is what color the object would be if it were rendered. It’s like changing the color of the light object itself, if you could see the light object.

Instead, you want to change the properties of the light that is emitted by the light object. That’s a special property of light objects, that’s not shared by any other types of nodes. So it has a special method for this purpose.

Because this is a special Light method, you have to get to the actual Light instance, not just the generic node interface that NodePath provides.

It would be less confusing if the Light method were called setLightColor() or something like that. But it’s not, it’s called setColor(), which happens to be the same name as the generic method on NodePath, even though it’s a completely unrelated thing.

David

That reminds me of Blender’s Data setup. In that program, you have Data Blocks that are tied to objects; but you can set the same data Block to a different object and that different object would take on what every values are passed to it from the data Block.

Should I look at “NodePath” and “Node” the same way? or should I look at it as “Class” and “Geometry” under that class?

I guess I shouldn’t worry about it too much as long as I can use it, but clearly seeing the reasoning behind typed Panda API driven code is the best.

It’s been a while since I’ve used Blender, so I couldn’t say for sure. Really it is a class connected to another class. If you were to show it visually it would look something like this:

render (instance of NodePath)
 |
 |--light (instance of NodePath)
 |   \--light_node (instance of SpotLight)
 |
 |--mesh (instance of NodePath)
 |   \--mesh_node (instance of GeomNode)
 |
 \--trees (instance of NodePath)
     |--tree1 (instance of NodePath)
     |   \--tree1_node (instance of GeomNode)
     |
     \--tree2 (instance of NodePath)
         \--tree2_node (instance of GeomNode)

This way you can also see why settings on a NodePath will pass down to its children, but settings on a “node” will not.

This may be bad analogy, but try to think of NodePath as filesystem directory, and node() as file itself. Each file needs to have it’s parent directory. And if you want for example to edit one (text) file, even if that file is one and only file inside its parent directory, you cant rightclick on directory and click edit, you have to do it on file.

And under each directory you can have different files, like text, video, audio, image.

I hope that you understand it a bit better now and that i did not confuse you even more.