Loads a whole 3D model from a file — a glTF scene or an OBJ mesh — and brings the recovered node tree into the scene under one transform.
Declarative element:
<sk-asset>
Global: available as sk.Asset inside a scene <script>.
The asset is a SceneNode that stands in for an externally-authored
model: it fetches its src, parses it, and expands the recovered subtree so it
renders as part of the scene. This is how you drop a model exported from a
modelling tool into a Skenra scene.
Key attributes. src is the file URL; the format is chosen by extension.
A glTF file (the default) recovers its groups and meshes as a renderable
hierarchy. Where one glTF mesh splits into several compatible per-material
primitives, they merge into a single mesh whose per-primitive face groups become
named selections; a single-primitive mesh keeps its whole-mesh base-color paint,
while a merged mesh preserves each region's base color as its selection grouping.
Only base color is imported from a glTF material — never textures or the
metallic/roughness/emissive PBR terms. An .obj file recovers a single mesh —
each o/g object group becomes a named face selection on it — and one spline
per polyline, carrying no materials of its own (assign appearance by targeting the
recovered mesh, and its object groups by name via a selection binding).
Because the loaded tree renders under this node, the asset's own transform
(x/y/z, s, rotation) moves and scales the whole model as one unit. Loading
is asynchronous, so a load event fires on success and an error event on
failure; a failed re-load leaves any prior content intact.
Normalizing. A loaded model arrives at whatever scale and position it was
exported at. normalize-scale="N" rescales it (aspect-preserving) so its largest
extent fits [-N, N], and anchor picks the reference point translated to the
origin first (anchor="center" recenters it) — so a bare scene frames the model
naturally under the default camera. The transform is applied to the loaded content
only; the asset's own transform and any nested annotations are untouched. Omit
normalize-scale to keep the authored coordinates (and fit the camera yourself in
an onload handler from the asset's computed bounds).
Related. For a single piece of imported geometry rather than a whole
hierarchy, use sk-mesh; to stamp a loaded model across many positions,
make it the content of a sk-cloner.
constructor(config?: { src?: string; normalizeScale?: number | 'none'; anchor?: AnchorValue3D; id?: string; x?: number; y?: number; z?: number; h?: number; p?: number; b?: number; quaternion?: Quaternion; sx?: number; sy?: number; sz?: number; s?: number; class?: string; style?: string })
Inherited from: SceneNode, SkenraAnimatable
— see those pages for inherited members.
| Property | Type | Default | Description | Declared by |
|---|---|---|---|---|
src |
string |
— | The source URL (as authored on <sk-asset src=…>), or null. |
Asset |
normalizeScale |
number | 'none' |
"none" |
Uniform normalization target half-size. | Asset |
anchor |
AnchorValue3D |
"content(0,0,0)" |
The 3D anchor point translated to the origin before normalization. | Asset |
idconfig-only |
string |
— | Unique identifier for the node, reflected to the host id attribute. |
SceneNodeConfig |
xanimatable |
number |
0 |
Gets the X position component. | SceneNode |
yanimatable |
number |
0 |
Gets the Y position component. | SceneNode |
zanimatable |
number |
0 |
Gets the Z position component. | SceneNode |
hanimatable |
number |
0 |
Gets the heading (Y-axis) rotation in radians. | SceneNode |
panimatable |
number |
0 |
Gets the pitch (X-axis) rotation in radians. | SceneNode |
banimatable |
number |
0 |
Gets the bank (Z-axis) rotation in radians. | SceneNode |
quaternionanimatable |
Quaternion |
— | Gets the rotation as a quaternion. | SceneNode |
sxanimatable |
number |
1 |
Gets the X-axis scale factor. | SceneNode |
syanimatable |
number |
1 |
Gets the Y-axis scale factor. | SceneNode |
szanimatable |
number |
1 |
Gets the Z-axis scale factor. | SceneNode |
sconfig-only |
number |
— | Uniform scale factor for all axes (overrides sx, sy, sz if provided) | SceneNodeConfig |
classconfig-only |
string |
— | Standard HTML class applied to the node host at construction |
SceneNodeConfig |
styleconfig-only |
string |
— | Standard inline style applied to the node host at construction |
SceneNodeConfig |
| Property | Type | Default | Description | Declared by |
|---|---|---|---|---|
hasLoadSettledread-only |
boolean |
— | Reports whether the async load lifecycle has reached a terminal state for | Asset |
hRad |
number |
0 |
Gets the heading (Y-axis) rotation in radians. | SceneNode |
pRad |
number |
0 |
Gets the pitch (X-axis) rotation in radians. | SceneNode |
bRad |
number |
0 |
Gets the bank (Z-axis) rotation in radians. | SceneNode |
hDeg |
number |
0 |
Gets the heading (Y-axis) rotation in degrees. | SceneNode |
pDeg |
number |
0 |
Gets the pitch (X-axis) rotation in degrees. | SceneNode |
bDeg |
number |
0 |
Gets the bank (Z-axis) rotation in degrees. | SceneNode |
xBasebase value |
number |
— | Gets the base (non-animated) value of X position. | SceneNode |
yBasebase value |
number |
— | Gets the base (non-animated) value of Y position. | SceneNode |
zBasebase value |
number |
— | Gets the base (non-animated) value of Z position. | SceneNode |
hBasebase value |
number |
0 |
Gets the base (non-animated) value of heading (Y-axis rotation). | SceneNode |
pBasebase value |
number |
0 |
Gets the base (non-animated) value of pitch (X-axis rotation). | SceneNode |
bBasebase value |
number |
0 |
Gets the base (non-animated) value of bank (Z-axis rotation). | SceneNode |
quaternionBasebase value |
Quaternion |
— | Gets the base (non-animated) quaternion rotation. | SceneNode |
sxBasebase value |
number |
— | Gets the base (non-animated) value of X-axis scale. | SceneNode |
syBasebase value |
number |
— | Gets the base (non-animated) value of Y-axis scale. | SceneNode |
szBasebase value |
number |
— | Gets the base (non-animated) value of Z-axis scale. | SceneNode |
draggable |
boolean |
false |
Gets whether this node can be dragged. | SceneNode |
parentread-only |
SceneNode | null |
— | The parent node in the scene graph, or null at the root. |
SceneNode |
sceneread-only |
any |
— | Gets the Scene this node belongs to, if any. | SceneNode |
posread-only |
Point3D |
— | Gets the world-space position of this node. | SceneNode |
matrixread-only |
Float32Array<ArrayBufferLike> |
— | Gets the computed 4x4 transformation matrix. | SceneNode |
animationsread-only |
SkenraAnimation[] |
— | Public getter for the animations affecting this target. | SkenraAnimatable |
| Method | Description | Declared by |
|---|---|---|
addMaterialPaint(material: Material, paintTarget: PaintTarget, options?: any): Paint |
Applies a material to this node for a specific paint target. | SceneNode |
getPaints(): ReadonlyMap<PaintTarget, Paint> |
— | SceneNode |
getOwnPaints(): readonly Paint[] |
Gets only the paints directly applied to this node (not inherited). | SceneNode |
removePaint(paint: Paint): void |
Removes a paint from this node. | SceneNode |
getWorldPosition(): number[] |
Returns this node’s origin in world space. | SceneNode |
getWorldMatrix(): Float32Array<ArrayBufferLike> |
Returns this node’s world transform — its local transform composed with all ancestor transforms. | SceneNode |
setViewportPosition(camera: AbstractCamera, x: number, y: number, z: number = 0.5): boolean |
Sets the node's local translation so that it appears at the specified viewport position. | SceneNode |
getViewportPosition(camera?: AbstractCamera): [number, number, number] | null |
Returns the node's current world position projected to viewport CSS pixel coordinates. | SceneNode |
setNDCPosition(camera: AbstractCamera, ndcX: number, ndcY: number, ndcZ: number = 0.5): boolean |
Sets the node's local translation so that it appears at the specified NDC position in the viewport. | SceneNode |
getBoundsInSpace(targetSpaceMatrix: Float32Array): { minX: number; maxX: number; minY: number; maxY: number; minZ: number; maxZ: number; } | null |
Computes the axis-aligned bounding box (AABB) of this node and its descendants | SceneNode |
animate(firstArg: TypedKeyframe<this>[] | TypedPropertyIndexedKeyframes<this> | Record<string, any> | globalThis.Keyframe[] | globalThis.PropertyIndexedKeyframes | null, secondArg?: number | KeyframeAnimationOptions | globalThis.KeyframeAnimationOptions): SkenraAnimation & Animation |
Creates a new SkenraAnimation for this target per Web Animations API. | SkenraAnimatable |
removeAnimation(animation: SkenraAnimation): boolean |
Removes a specific animation from this object. | SkenraAnimatable |
constrain(type: K, config: ConstraintConfigMap[K]): ConstraintReturnMap[K] |
Creates a constraint on this Animatable using a fluent API. | SkenraAnimatable |
import { Asset } from '/js/skenra/scene-graph/asset.js';
const rig = new Asset({ id: 'rig', src: 'assets/character.gltf', normalizeScale: 3, anchor: 'center' });
scene.appendChild(rig);
rig.addEventListener('load', () => console.log('rig ready'));