SceneObjectParticle
Extends: SceneObject
Draws an entire DrawableParticles emitter's live particles with a single SceneObject
- not one SceneObject per particle. See specs/2026-08-18-particle-system-design.md ("Why one SceneObjectParticle per emitter, not per particle") for why: per-particle SceneObjects would call Renderer.addSceneObject/removeSceneObject every frame during continuous emission, permanently defeating the depth-sort skip-optimization for the whole renderer.
Properties
drawable(DrawableParticles)
Constructor
new SceneObjectParticle(
name: string,
drawableObj: DrawableParticles,
): SceneObjectParticleParameters
name(string)drawableObj(DrawableParticles)
Instance Methods
participatesInOverlapDetection(): boolean
A multi-particle emitter can't pass the narrow-phase hull-validity check as a single object, and clustering doesn't add anything here since particles already draw as one batched unit - skip broad-phase candidacy entirely.
Returns
boolean
objMovedInRelationToCamera(cameraObj: Camera): boolean
The base class only re-checks the frustum when the emitter's own transform/camera moved (see SceneObject.objMovedInRelationToCamera) - wrong here, since a stationary emitter's particles still move every frame on their own. Forcing a re-check whenever particles are alive fixes issue #114 (a stationary off-screen emitter's particles drifting into view would otherwise stay culled forever). No cost once the emitter is idle (zero live particles) - same cheap cached-answer path as any other SceneObject.
Parameters
cameraObj(Camera)
Returns
boolean
getPositionsForFrustumCheck(
drawMode: SceneObjectDrawMode,
): dynamic
The base default checks only the emitter's own anchor (m.worldPosition), which is wrong for an emitter whose particles have spread away from it. Checking the bounding box of every live particle's position (plus the anchor) instead of every individual particle keeps this a cheap 2-point frustum check regardless of live particle count - consistent with how every other multi-point SceneObject (e.g. SceneObjectBillboard) already checks corner/bounding points rather than a precise shape test. See #114.
Parameters
drawMode(SceneObjectDrawMode)
Returns
dynamic
performDraw(
rendererObj: BGE.Renderer,
drawMode: SceneObjectDrawMode,
): boolean
Parameters
rendererObj(BGE.Renderer)drawMode(SceneObjectDrawMode)
Returns
boolean