aframe icon indicating copy to clipboard operation
aframe copied to clipboard

setObject3D will give false negatives for CSS3DRenderer when checking whether it's a THREE.Object3D

Open ResourceHog opened this issue 10 months ago • 2 comments

Tried to use https://github.com/mrdoob/three.js/blob/master/examples/jsm/renderers/CSS3DRenderer.js to embed dom elements in 3D space. However setObject3D will reject it because instanceof is not properly detecting the type.

    setupCss3D(sceneEl: Scene) : void {
        const wrapper = document.createElement('div');
        wrapper.style.position = 'absolute';
        wrapper.style.transformStyle = 'preserve-3d';

        const children = Array.from(this.el.children);
        for(const child of children) {
            
                wrapper.appendChild(child);
            
        }

        this.wrapper = wrapper;
        this.cssObject = new CSS3DObject(wrapper);
        this.cssObject.scale.set(1,1,1);
        this.el.object3D.add(this.cssObject);

        console.log(this.cssObject instanceof THREE.Object3D);
        
        this.el.setObject3D('mesh', this.cssObject);
        console.log(this.el.object3D);

    },

Additional Context: Object3D provides an "isObject3D" parameter specifically for type checking. https://github.com/mrdoob/three.js/blob/e3ee9682fb2c776cd77fd8b89f73c321945fa52c/src/core/Object3D.js#L79

Suggested solution: use a custom type guard to leverage this parameter.


function isObject3D(obj: unknown) is THREE.Object3D {
    return (obj as THREE.Object3D).isObject3D === true;
}

then replace the instanceof check.

...
  setObject3D (type, obj) {
    var oldObj;
    var self = this;

    if (!isObject3D(obj)) {
      throw new Error(
        '`Entity.setObject3D` was called with an object that was not an instance of ' +
        'THREE.Object3D.'
      );
    }
...

ResourceHog avatar Apr 06 '25 19:04 ResourceHog