SceneObjectSkybox
Extends: SceneObject
Properties
drawable(DrawableSkybox)
Constructor
new SceneObjectSkybox(
name: string,
drawableObj: DrawableSkybox,
): SceneObjectSkyboxParameters
name(string)drawableObj(DrawableSkybox)
Instance Methods
participatesInOverlapDetection(): boolean
A skybox is always fully behind everything and has no meaningful bounding hull - never a candidate for overlap-cluster interleaving (mirrors SceneObjectPlane/ SceneObjectLine's own exclusion for the same reason).
Returns
boolean
isPotentiallyOnScreen(cameraObj: Camera): boolean
Only a Camera3d has yaw/pitch to map a cylindrical panorama against - a 2D room simply never draws this. See specs/2026-08-23-skybox-and-terrain-world-design.md's Camera2d follow-up note.
Parameters
cameraObj(Camera)
Returns
boolean
updateWorldPosition(drawMode: SceneObjectDrawMode): boolean
A skybox has no meaningful world position (it's always drawn as if centered on the camera) - skip the base class's default, which computes one from m.drawable.getWorldPosition() for no benefit here.
Parameters
drawMode(SceneObjectDrawMode)
Returns
boolean
arcsinDegrees(sinValue: float): float
BrighterScript/BrightScript has no native arcsine - asin(x) = atan2(x, sqrt(1-x^2)) for x in [-1, 1] is the standard identity, reusing the engine's existing atan2. Exposed (not private) so its correctness can be tested directly, matching SceneObjectPlane.getRollCanvasSize()'s precedent for pure-math helpers.
Parameters
sinValue(float) — the sine of an angle, clamped to [-1, 1]
Returns
float— the angle in degrees whose sine is sinValue
computeVisibleBand(
camera: Camera3d,
destWidth: float,
destHeight: float,
): object
Camera3d.orientation itself is unaffected by roll (rolling spins the camera around its own forward axis, which doesn't change that axis's direction) - so yaw and pitch can be read directly off orientation with no roll-aware "level" variant needed, unlike SceneObjectPlane's horizon math. Roll is applied separately, as a final image rotation (see the roll path in performDraw, Task 3).
Parameters
camera(Camera3d)destWidth(float) — the destination surface's width in pixelsdestHeight(float) — the destination surface's height in pixels
Returns
object— {leftX, topY, cropHeight, scaleX, scaleY, textureWidth, textureHeight}
findCanvasPosition(
rendererObj: Renderer,
drawMode: SceneObjectDrawMode,
): boolean
Re-checked here, not just in isPotentiallyOnScreen() - the base draw()'s enteredDrawPath is also true whenever the draw mode changed (lastDrawMode starts at -1, so this is true on an object's very first draw regardless of camera type), which would otherwise let performDraw() reach its Camera3d cast on a Camera2d's first frame and crash on rollDegrees, a field Camera2d doesn't have.
Parameters
rendererObj(Renderer)drawMode(SceneObjectDrawMode)
Returns
boolean
getRollCanvasSize(frameSize: BGE.Math.Vector): float
Sized to at least the camera frame's diagonal, so a composite rendered into a canvasSize x canvasSize square can be rotated by any angle without exposing an empty corner once it's cropped back down to the real frame - mirrors SceneObjectPlane.getRollCanvasSize() exactly (same underlying geometry problem).
Parameters
frameSize(BGE.Math.Vector)
Returns
float
performDraw(
rendererObj: BGE.Renderer,
drawMode: SceneObjectDrawMode,
): boolean
Parameters
rendererObj(BGE.Renderer)drawMode(SceneObjectDrawMode)
Returns
boolean
renderNow(rendererObj: BGE.Renderer): boolean
Draws this skybox against rendererObj's current camera right now, bypassing the base SceneObject update()/draw() pipeline entirely. That pipeline's update() unconditionally calls m.drawable.movedLastFrame(true), which dereferences the drawable's owner - fine for a DrawableSkybox added to a real Room/GameEntity (the normal path, via Renderer.drawScene()), but not an option for a caller with no owning entity at all. renderNow() is that owner-independent entry point: used by the rendererTest SkyboxTest demo (Task 5), which deliberately has no Game/Room, and by this class's own unit tests for the same reason. It applies the same Camera2d/Camera3d gate isPotentiallyOnScreen() would.
Parameters
rendererObj(BGE.Renderer)
Returns
boolean— true if the skybox was actually drawn