SOLOD(3iv)

πŸ’– SoLOD β€” bestie, it's the distance-based level-of-detail switching group node πŸ’–

manual page: SoLOD(3IV) β€” yes that's the whole vibe, section 3IV, we're in Inventor territory now πŸ¦‹


🌸 INHERITS FROM 🌸

SoBase > SoFieldContainer > SoNode > SoGroup > SoLOD

so it's a whole family tree situation β€” everything SoGroup can do, this baby can do too, plus its own lil LOD magic ✨


πŸŽ€ SYNOPSIS πŸŽ€

#include <Inventor/nodes/SoLOD.h>

Fields from class SoLOD πŸ’…

SoMFFloat           range
SoSFVec3f           center

Methods from class SoLOD 🌈

                     SoLOD()
static SoType        getClassTypeId()

Methods from class SoGroup 🫢

void                 addChild(SoNode *child)
void                 insertChild(SoNode *child, int newChildIndex)
SoNode *             getChild(int index) const
int                  findChild(const SoNode *child) const
int                  getNumChildren() const
void                 removeChild(int index)
void                 removeChild(SoNode *child)
void                 removeAllChildren()
void                 replaceChild(int index, SoNode *newChild)
void                 replaceChild(SoNode *oldChild, SoNode *newChild)

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 picture this: you've got one object, but you have multiple versions of it at different detail levels, and you want the app to just… pick the right one automatically based on how far away the camera is. That's literally what this group node is for. πŸ’…

The children of this node typically represent the same object or objects at varying levels of detail, from highest detail to lowest. Then the node computes the distance from the world-space eye point to the transformed center of the LOD</>, and draws one child, based on the values in the ranges field. Obsessed, honestly.

More precisely β€” and bestie, this is the part you actually need β€” if the distance from the world-space eyepoint to the transformed center is D and the ranges array contains LAST_RANGE+1 values (numbered 0...LAST_RANGE), then:

if D < ranges[0]                    : Child 0 is drawn
else if ranges[i-1] < D < ranges[i] : Child i is drawn
else if D > ranges[LAST_RANGE]      : Child LAST_RANGE+1 is drawn

So the math is mathing: N ranges and N+1 children should be specified. πŸ‘‘

And if you mess up the ratio (no judgement, we've all been there):

  • If you specify too few children, the last child will be used for the extra ranges.
  • If you specify too few ranges, the extra children will never be used.
🚨 not me warning you: getting the counts wrong doesn't error out, it just silently does the thing above. So count your children, bestie.

Two lil tricks that are genuinely iconic:

  • It's often useful to define the lowest detail child to be an SoInfo node. That makes the object completely disappear if it's far enough away from the eyepoint.
  • Defining the highest detail child to be an SoInfo node can also be useful if you want the object to disappear if it gets too close to the eyepoint.

🌈 FIELDS 🌈

  • SoMFFloat range β€” the world-space distances you're using as your switching criteria. this is the whole decision-maker fr fr.
  • SoSFVec3f center β€” the object-space center of the model. 🎯

πŸ’œ METHODS πŸ’œ

  • SoLOD() β€” creates a distance-based level-of-detail node with default settings. baby's first LOD, slay. ✨
  • static SoType getClassTypeId() β€” returns the type identifier for this class. iykyk. πŸ’…

πŸ”₯ ACTION BEHAVIOR πŸ”₯

SoGLRenderAction, SoRayPickAction, SoCallbackAction

Only the child with the appropriate level of detail is traversed. That's the whole point, and it ate. πŸ’…

others

All implemented as for SoGroup. no extra drama, it just does what the parent class does. 🫢


πŸŽ€ FILE FORMAT/DEFAULTS πŸŽ€

LOD {
   center  0 0 0
   range   [  ]
}

πŸ¦‹ SEE ALSO πŸ¦‹

  • SoSwitch
  • SoGroup

and that's the page!! signed off at the bottom as SoLOD(3IV)() β€” that's your manual name, section and all, sitting pretty in the footer with no date and no extra source info, so don't go looking for a version string that isn't there bestie πŸ˜­πŸ’– stay detailed, stay culled, periodt ✨