SceneObject

Properties

  • name (string)
  • id (string) — Unique Id
  • clusterMemberCount (integer) — How many members are in this object's overlap cluster this frame (see
  • drawable (Drawable)
  • type (SceneObjectType)
  • negDistanceFromCamera (float) — The negative distance from the camera, used for depth sorting. Measured from
  • worldPosition (dynamic)
  • depthPosition (dynamic) — This object's position as used for depth classification (BGE.BSP's dynamic-item
  • transformationMatrix (dynamic) — The Current Transformation Matrix
  • lastFrameWasCulled (boolean) — Whether the last frame's draw was skipped because the frustum rejected this object,
  • lastFrameDidDraw (boolean) — Whether the last frame's draw actually happened. Distinct from lastFrameWasCulled
  • hasValidWorldPosition (boolean)
  • hasValidCanvasPosition (boolean)
  • wasEnabledLastFrame (boolean)
  • isFirstFrameSinceEnabled (boolean)
  • isLowEndDevice (boolean)
  • lastGeometryVersion (integer) — The drawable's geometryVersion as of the last completed draw - see geometryChanged()
  • lastQualityVersion (integer) — The renderer's qualityVersion as of the last draw
  • qualityChangedThisDraw (boolean) — True during a draw whose renderer quality settings changed since this object's
  • lastDrawMode (integer) — The draw mode this object last drew in - see drawModeChanged()
  • lastProjectionVersion (integer) — The camera's projectionVersion as of the last draw - see projectionChanged()
  • depthChangedThisFrame (boolean) — True for exactly the frame this object's negDistanceFromCamera was recomputed -
  • stableSortKey (float) — What Renderer actually sorts by - negDistanceFromCamera quantized into
  • isStatic (boolean) — Set by Renderer when this object's owning entity is marked GameEntity.isStatic and
  • staticGeometryMovedThisFrame (boolean) — True for exactly the frame Renderer.updateSceneObjects() should mark the static
  • staticCheckArmed (boolean) — Whether update() has completed at least one prior frame for this object - guards
  • staticWarningLogged (boolean) — Whether the one-time misuse warning has already been logged for this object -
  • staticDrawModeWarningLogged (boolean) — Whether the one-time "static but not in an oriented draw mode" warning has
  • wasStaticEnabledState (boolean) — This object's isEnabled() as of the last checkStaticEnabledStateChanged() call -

Constructor

new SceneObject( name: string, drawableObj: Drawable, objType: SceneObjectType, ): SceneObject

Parameters


Instance Methods

setId(id: string): void

Parameters

  • id (string)

Returns

  • void

setLastSortIndex(index: integer): void

Parameters

  • index (integer)

Returns

  • void

getLastSortIndex(): integer

Returns

  • integer

update(cameraObj: Camera): void

Update the scene object for the current frame. Updates the world position and checks if the object should be drawn. Updates negDistanceFromCamera for depth sorting. Do not override this function.

Parameters

Returns

  • void

getDepthPosition(): BGE.Math.Vector

This object's cached depth-classification position - see depthPosition's own doc comment. Exposed for Renderer's static-geometry BSP path (drawStaticAndDynamicSceneObjects()), which needs the same anchor point used for depth sorting, not the raw worldPosition.

Returns

  • BGE.Math.Vector

getPositionForCameraDistance( drawMode: SceneObjectDrawMode, ): BGE.Math.Vector

Get the position of the object for the camera distance calculation Override this function in subclasses to provide specific behavior

Parameters

Returns

  • BGE.Math.Vector

isEnabled(): boolean

Check if the object is enabled

Returns

  • boolean — true if this sceneObject should be drawn or updated

updateWorldPosition(drawMode: SceneObjectDrawMode): boolean

protected

Parameters

Returns

  • boolean

draw(rendererObj: Renderer): void

Draw the object with the current renderer Calculates if the object is on screen and if it should be drawn. Do not override this function!

Parameters

Returns

  • void

drawModeChanged(drawMode: SceneObjectDrawMode): boolean

protected

Parameters

Returns

  • boolean

geometryChanged(): boolean

protected

Returns

  • boolean

projectionChanged(cameraObj: Camera): boolean

protected

Parameters

Returns

  • boolean

findCanvasPosition( rendererObj: Renderer, drawMode: SceneObjectDrawMode, ): boolean

protected

Parameters

Returns

  • boolean

performDraw( rendererObj: Renderer, drawMode: SceneObjectDrawMode, ): boolean

protected

Parameters

Returns

  • boolean

getPrimitiveCount(): integer

How many separately-orderable draw primitives this object currently has. The base-class default (1) is correct for every billboard-family SceneObject - a quad/circle/text/etc. is always drawn as one piece regardless of draw mode. SceneObjectModel overrides this to return its actual per-face count, which does vary with draw mode (backface-culled modes only count front-facing faces; the DrawBackFace variants count both).

Returns

  • integer

getPrimitiveDepth(index: integer): float

The depth to sort primitive index by, within a multi-member cluster's combined primitive list. The base-class default (this object's own overall depth) is correct for the single-primitive case.

Contract: the returned value must be on the same convention as negDistanceFromCamera - negative in front of the camera, and ascending sort = farthest-first (matching the main scene's own painter's-algorithm sort convention). Every override (e.g. SceneObjectModel's per-face depth) must convert to this same convention, or primitives from different SceneObject subtypes will sort against each other backwards within a shared cluster.

Parameters

  • index (integer)

Returns

  • float

drawPrimitive(rendererObj: Renderer, index: integer): boolean

Draws primitive index now. The base-class default delegates to this object's normal whole-object draw path (performDraw, with its normal caching behavior intact) - correct for the single-primitive case, where "draw primitive 0" and "draw the whole object" are the same operation. SceneObjectModel overrides this to draw one face directly (bypassing its whole-model temp-bitmap cache, which can't represent cross-object interleaving).

Parameters

  • rendererObj (Renderer)
  • index (integer)

Returns

  • boolean — whether this primitive actually drew something

afterDraw(): void

protected

Returns

  • void

objMovedInRelationToCamera(cameraObj: Camera): boolean

protected

Parameters

Returns

  • boolean

isPotentiallyOnScreen(cameraObj: Camera): boolean

protected

Parameters

Returns

  • boolean

getPositionsForFrustumCheck( drawMode: SceneObjectDrawMode, ): Array.<BGE.Math.Vector>

protected

Parameters

Returns

  • Array.<BGE.Math.Vector>

getBoundingPoints(cameraObj: Camera): Array.<BGE.Math.Vector>

Public wrapper around getPositionsForFrustumCheck(), for cross-object callers (e.g. BGE.DepthSort's overlap detection) that need this object's own bounding points but aren't a SceneObject subclass themselves.

Parameters

Returns

  • Array.<BGE.Math.Vector>

participatesInOverlapDetection(): boolean

Whether this object is worth including in overlap-cluster detection (BGE.DepthSort/Renderer.getOverlapClusters()) at all. The base-class default (true) is correct for anything with real area/volume, which the narrow phase (BGE.DepthSort.hullsOverlap) can actually test via a >=3-point convex hull. SceneObjectLine overrides this to false: a line's own bounding points (getPositionsForFrustumCheck) are always exactly 2 (its two endpoints), so its projected hull can never reach MIN_VALID_HULL_POINTS - hullsOverlap() already rejects it via isValidHull() unconditionally, meaning a line could never actually be unioned into a real cluster with anything, before or after this method existed. This isn't tolerating a small visual error - the scenario ("two lines clustered in the wrong order") is structurally impossible under the current hull-based narrow phase. What this method actually buys is skipping the broad-phase setup cost (screen-bounds projection, hull construction, sort/sweep entries) for objects that were always going to fail the narrow phase anyway - this matters in practice for a scene built from many line segments (e.g. examples/3d's TreesScene, each tree a bundle of DrawableLine branches), which would otherwise dominate the cluster-candidate count for zero possible benefit.

A static object (isStatic - see GameEntity.isStatic/Renderer.markStatic()) also returns false here regardless of type: the static geometry BSP tree already gives it correct draw order against every dynamic object, so clustering it too would be redundant at best - and at worst, a cluster with clusterMemberCount > 1 defers the object to Renderer.drawPendingClusterPrimitives(), which runs after the entire BSP pass and would silently discard that ordering for it.

Returns

  • boolean

isEligibleForStaticBsp(): boolean

Whether this concrete SceneObject type's geometry can be represented as a single flat quad usable by the static geometry BSP tree (see BGE.BSP and Renderer.buildStaticGeometryTree()). False by default - override true only for a type whose getWorldPoints() exactly matches its drawn fill geometry (currently SceneObjectImage and SceneObjectRectangle; not SceneObjectModel/SceneObjectCircle/ SceneObjectPolygon/SceneObjectText, whose world corners are a bounding proxy, not their actual silhouette).

Returns

  • boolean

isReadyForStaticBspBuild(cam: Camera): boolean

Whether this object should actually be included in this build of the static geometry BSP tree (see Renderer.buildStaticGeometryTree()) - combines isEligibleForStaticBsp() (concrete type support) with a runtime check that the object is actually in a draw mode that can define a plane. A static entity left in a screen-aligned draw mode (matchCamera/directToCamera/directScaled - see isScreenAlignedDrawMode()) never populates worldPoints (see SceneObjectBillboard.updateWorldPosition()'s screen-aligned branch), so getWorldPoints() would still be the constructor's all-zero CornerPoints - building a plane from that classifies every dynamic object to the same side, silently collapsing draw order. Note this is NOT simply "not isOrientedDrawMode()" - isOrientedDrawMode() is defined as not isDirectDrawMode(), which incorrectly counts directScaled as oriented even though it's screen-aligned and just as incapable of populating worldPoints as matchCamera/directToCamera (see isScreenAlignedDrawMode()'s own doc comment). Warns once (matching the staticWarningLogged misuse-detection pattern) and returns false instead, so the tree itself excludes this object - but it is NOT dropped: Renderer. drawStaticAndDynamicSceneObjects() still classifies it every frame as a dynamic item against the tree's real planes (e.g. a screen-aligned tree billboard ordered correctly against a real static wall), same as a genuinely moving object.

Parameters

Returns

  • boolean

checkStaticEnabledStateChanged(): boolean

Detects a static object's enabled/disabled transition even on a frame update() itself never runs (a disabled object never reaches update() - see Renderer.updateSceneObjects()). Called once per frame for every SceneObject (cheap; a no-op state update for a non-static object) so Renderer can mark the static geometry tree dirty exactly once per transition, in either direction, instead of drawing a disabled object from a stale tree or never re-drawing one that was disabled when the tree was last built.

Returns

  • boolean — true exactly on the frame this object's (isStatic and) enabled state changed since the last call

getWorldPoints(): BGE.Math.CornerPoints

This object's world-space quad corners, if it has any - invalid for a type that isn't built from a single flat quad. Overridden on SceneObjectBillboard (the shared base for every quad-shaped SceneObject) to return its computed worldPoints.

Returns

  • BGE.Math.CornerPoints

isDeterministicDrawFailure( rendererObj: Renderer, drawMode: SceneObjectDrawMode, ): boolean

protected

Parameters

Returns

  • boolean

isCulled(): boolean

Whether this object was culled (skipped entirely) on the last frame drawn - either by the camera frustum, or by a deterministic draw failure (see isDeterministicDrawFailure()) that's being treated the same way. Game code can use this (e.g. via GameEntity.isOnScreen()/Drawable.isOnScreen()) to skip its own expensive per-frame work for an entity that isn't currently visible - see issue #75.

Returns

  • boolean