SODIRECTIONALLIGHTMANIP(3iv)

πŸ’– SoDirectionalLightManip(3IV) πŸ’– β€” it's giving "directional light but make it touchable" ✨

okay so bestie, buckle up, because this page is literally about a light you can grab 🫢


πŸŽ€ NAME πŸŽ€

SoDirectionalLightManip β€” a directional light node with a built-in 3D interface for editing its direction. yes, you read that right, you can drag the light. πŸ’…


🌸 INHERITS FROM 🌸

SoBase > SoFieldContainer > SoNode > SoLight > SoDirectionalLight > SoDirectionalLightManip

πŸ¦‹ SYNOPSIS πŸ¦‹

#include <Inventor/manips/SoDirectionalLightManip.h>

✨ Fields from class SoDirectionalLight ✨

SoSFVec3f           direction

✨ Fields from class SoLight ✨

SoSFBool            on
SoSFFloat           intensity
SoSFColor           color

✨ Methods from class SoDirectionalLightManip ✨

                     SoDirectionalLightManip()
SoDragger *          getDragger()
SbBool               replaceNode(SoPath *p )
SbBool               replaceManip(SoPath *p, SoDirectionalLight *newOne )
                          const
static SoType        getClassTypeId()

✨ Methods from class SoNode ✨

void                setOverride(SbBool state)
SbBool              isOverride() const
SoNode *            copy(SbBool copyConnections = FALSE) const
virtual SbBool      affectsState() const
static SoNode *     getByName(const SbName &name)
static int          getByName(const SbName &name, SoNodeList &list)

✨ Methods from class SoFieldContainer ✨

void                setToDefaults()
SbBool              hasDefaultValues() const
SbBool              fieldsAreEqual(const SoFieldContainer *fc) const
void                copyFieldValues(const SoFieldContainer *fc, SbBool
                         copyConnections = FALSE)
SbBool              set(const char *fieldDataString)
void                get(SbString &fieldDataString)
virtual int         getFields(SoFieldList &resultList) const
virtual SoField *   getField(const SbName &fieldName) const
SbBool              getFieldName(const SoField *field, SbName &fieldName)
                         const
SbBool              isNotifyEnabled() const
SbBool              enableNotify(SbBool flag)

✨ Methods from class SoBase ✨

void                ref()
void                unref() const
void                unrefNoDelete() const
void                touch()
virtual SoType      getTypeId() const
SbBool              isOfType(SoType type) const
virtual void        setName(const SbName &name)
virtual SbName      getName() const

πŸ’œ DESCRIPTION πŸ’œ

okay so SoDirectionalLightManip is the base class for all the SoDirectionalLight nodes that come with a built-in 3D user interface β€” and fun fact, it's the only such class the Inventor toolkit ships with. main character behavior, honestly. πŸ‘‘

since it's derived from SoDirectionalLight, any lil change to its fields makes the lighting change for every node that comes after it in the scene graph. and the part the interface actually edits? that's the direction field. also, the color of the manipulator's geometry will reflect the color of the light β€” but heads up, you cannot edit the color using this manipulator. πŸ™ˆ

typically you'll want to swap a regular SoDirectionalLight out for an SoDirectionalLightManip (like when the user selects a light to edit), or the other way around (when the user's done moving the light and the interface should just ✨vanish✨). use the replaceNode() method to insert a manipulator into a scene graph, and the replaceManip() method to take it back out when you're done. clean.

the SoDirectionalLightManip uses an SoDirectionalLightDragger to give you that 3D interface. but bestie, the manipulator is not the same as the dragger β€” it lights other objects in the scene, because as an SoDirectionalLight it alters the state. the dragger's field values and movement, meanwhile, only affect the dragger itself. to learn more about how the interface works and what each part does, go read the reference page for SoDirectionalLightDragger. the interfaces of the dragger and the manipulator are identical, so it's giving "same energy". πŸ’«

so how does the manipulator use its dragger? it adds it as a hidden child. when an action gets applied to the manipulator β€” rendering, handling events, whatever β€” the manipulator first traverses the dragger, and then adds its lighting parameters to the state. and when you click-drag-release over the manipulator, it passes those events down to the dragger, which moves as a result ("I can't help it, I'm a dragger!"). 😭 iconic. it literally said what it said.

the manipulator keeps consistency between the fields of the dragger and its own fields. say you use the mouse to rotate the dragger β€” callbacks make sure the direction field of the manipulator changes by the same amount, which changes the lighting of the nodes that follow in the scene graph. and same thing in reverse: if you set the direction field of the SoDirectionalLightManip, the manipulator will orient the dragger accordingly. mutual support, we love to see it. 🫢

and because the dragger is a hidden child: you can see it on screen and interact with it, but it does not show up when you write the manipulator to file. also, any SoPath will end at the manipulator. (go check the Actions section of this reference page for the full tea on when the dragger is traversed).

if you want a pointer to the dragger, you can get it from the manipulator using the getDragger() method. and you'll need to do this if you want to change the geometry of a manipulator, because the geometry actually belongs to the dragger. yeah. plot twist. πŸŒ€


πŸ’… METHODS πŸ’…

  • SoDirectionalLightManip() β€” constructor. that's it, that's the whole vibe. ✨
  • SoDragger * getDragger() β€” returns a pointer to the dragger this manipulator is using. with that pointer you can customize the dragger just like any other dragger. you can change geometry using the setPart() method, or add callbacks using the methods over in the SoDragger reference page. go wild. 🎨
  • SbBool replaceNode(SoPath *p ) β€” replaces the tail of the path with this manipulator. the tail of the path must be an SoDirectionalLight node (or a subclass of it). if the path has a nodekit, this will try to use setPart() to insert the manipulator. otherwise, the manipulator requires that the next to last node in the path chain be a group.

the field values from the directional light node will be copied to this manipulator, and the light node will be replaced.

🚨 important: the manipulator will not call ref() on the node it is replacing. the old node will disappear if it has no references other than from the input path p and its parent, since this manipulator will be replacing it in both of those places. nor will the manipulator make any changes to field connections of the old node. the calling process is thus responsible for keeping track of its own nodes and field connections. you've been warned, bestie. πŸ’€
  • SbBool replaceManip(SoPath *p, SoDirectionalLight *newOne ) const β€” replaces the tail of the path β€” which must be this manipulator β€” with the given SoDirectionalLight node. if the path has a nodekit, this will try to use setPart() to insert the new node. otherwise, the manipulator requires that the next to last node in the path chain be a group.

the field values from the manipulator will be copied to the directional light node, and the manipulator will be replaced.

🚨 same energy: the manipulator will not call ref() or unref() on the node which is replacing it, nor will it make any changes to field connections. the calling process is thus responsible for keeping track of its own nodes and field connections. 🫠
  • static SoType getClassTypeId() β€” returns the type identifier for this class. you know, for type-checking your faves. πŸͺͺ

🌈 ACTION BEHAVIOR 🌈

SoGLRenderAction, SoCallbackAction, SoGetBoundingBoxAction, SoGetMatrixAction, SoHandleEventAction, SoRayPickAction

first, it traverses the dragger the way an SoGroup would. all draggers place themselves in space, but they leave the current transformation unchanged when they're finished. then the SoDirectionalLightManip adds a directional light to the state, just like its base class, SoDirectionalLight. teamwork, periodt. πŸ’«

SoSearchAction

searches just like an SoDirectionalLight. it does not search the dragger, because the dragger is a hidden child. sneaky. 🀫

SoWriteAction

writes out just like an SoDirectionalLight. it does not write the dragger, because the dragger is a hidden child. but if you really need to write valuable information about the dragger β€” like customized geometry β€” you can retrieve the dragger with the getDragger() method and then write it out separately. problem solved, slay. πŸ’…


πŸ“ FILE FORMAT/DEFAULTS πŸ“

DirectionalLightManip {
    on         TRUE
    intensity  1
    color      1 1 1
    direction  0 0 -1
}

πŸ‘‘ SEE ALSO πŸ‘‘

  • SoDragger
  • SoDirectionalLight
  • SoDirectionalLightDragger
  • SoPointLightManip
  • SoSpotLightManip

and that's a wrap on the SoDirectionalLightManip(3IV)() page, bestie πŸ¦‹πŸ’– go forth and drag your lights around, you're gonna eat, no cap ✨🌸