import { SceneNode } from "./SceneNode.js";
import { Renderable } from "./Renderable.js";
export class Object3D extends SceneNode {
    isObject3D = true;
    constructor(options = {}) {
        super(options);
        applyObject3DOptions(this, options);
    }
    get position() {
        return this.transform.position;
    }
    get quaternion() {
        return this.transform.rotation;
    }
    get scale() {
        return this.transform.scale;
    }
    get matrix() {
        return this.transform.localMatrix;
    }
    get matrixWorld() {
        return this.transform.worldMatrix;
    }
    get matrixAutoUpdate() {
        return this.transform.matrixAutoUpdate;
    }
    set matrixAutoUpdate(enabled) {
        this.transform.setMatrixAutoUpdate(enabled);
    }
    setLocalMatrix(matrix, options = {}) {
        this.transform.setLocalMatrix(matrix, options);
        return this;
    }
}
export class Group extends Object3D {
    isGroup = true;
}
export class Mesh extends Object3D {
    isMesh = true;
    constructor(options = {}) {
        super(options);
        if (options.renderable)
            this.renderable = toRenderable(options.renderable);
    }
    setRenderable(renderable) {
        this.renderable = toRenderable(renderable);
        return this;
    }
}
export class SkinnedMesh extends Mesh {
    isSkinnedMesh = true;
    get skinning() {
        return this.renderable?.skinning;
    }
    setSkinning(skinning) {
        if (!this.renderable)
            throw new Error("SkinnedMesh requires a renderable before skinning can be assigned.");
        this.renderable.skinning = {
            jointCount: skinning.jointCount,
            matrices: new Float32Array(skinning.matrices)
        };
        return this;
    }
}
export class InstancedMesh extends Mesh {
    isInstancedMesh = true;
    get instanceTransforms() {
        return this.renderable?.instanceTransforms;
    }
    get instanceColors() {
        return this.renderable?.instanceColors;
    }
    setInstanceTransforms(transforms) {
        if (!this.renderable)
            throw new Error("InstancedMesh requires a renderable before instance transforms can be assigned.");
        this.renderable.instanceTransforms = new Renderable({
            geometry: this.renderable.geometry,
            material: this.renderable.material,
            layerMask: this.renderable.layerMask,
            castShadow: this.renderable.castShadow,
            receiveShadow: this.renderable.receiveShadow,
            skinning: this.renderable.skinning,
            morphWeights: this.renderable.morphWeights,
            instanceTransforms: transforms,
            instanceColors: this.renderable.instanceColors
        }).instanceTransforms;
        return this;
    }
    setInstanceColors(colors) {
        if (!this.renderable)
            throw new Error("InstancedMesh requires a renderable before instance colors can be assigned.");
        this.renderable.instanceColors = new Renderable({
            geometry: this.renderable.geometry,
            material: this.renderable.material,
            layerMask: this.renderable.layerMask,
            castShadow: this.renderable.castShadow,
            receiveShadow: this.renderable.receiveShadow,
            skinning: this.renderable.skinning,
            morphWeights: this.renderable.morphWeights,
            instanceTransforms: this.renderable.instanceTransforms,
            instanceColors: colors
        }).instanceColors;
        return this;
    }
}
function applyObject3DOptions(node, options) {
    if (options.visible !== undefined)
        node.visible = options.visible;
    if (options.layerMask !== undefined)
        node.layerMask = options.layerMask;
    if (options.renderOrder !== undefined) {
        if (!Number.isFinite(options.renderOrder))
            throw new Error("Object3D renderOrder must be finite.");
        node.renderOrder = options.renderOrder;
    }
    if (options.userData)
        node.userData = { ...options.userData };
}
function toRenderable(renderable) {
    return renderable instanceof Renderable ? renderable : new Renderable(renderable);
}
//# sourceMappingURL=Object3D.js.map