Diagonal Think
Diagonal Think

Reputation: 323

aframe error: Entity.setObject3D was called with an object that was not an instance of THREE.Object3D

hello i've tried to add a mesh to my aframe component, but i receive a strange error also with a very simple code like this

AFRAME.registerComponent('mysquare', {
      init: function(){
        var el = this.el; 

        var box = new THREE.BoxGeometry(40, 5, 40);
        var boxMesh = new THREE.Mesh(box);
        boxMesh.position.set(25, 0, 25);
        el.setObject3D("mesh", boxMesh);

      }
    });

home.html

<ion-content>
      <div></div>
      <a-scene embedded>
         <a-entity mysquare></a-entity>
       </a-scene> 
</ion-content>

error message

Error: Entity.setObject3D was called with an object that was not an instance of THREE.Object3D.

i tried also the add function but i receive the same message. how is possible?

i develop my app with ionic 2 + aframe v.0.7.1. i've tried also with the 0.5.0 version but i have the same problem

Upvotes: 1

Views: 2532

Answers (3)

Shashank Agrawal
Shashank Agrawal

Reputation: 25807

For me, I was successfully able to use it with Angular 13 application by installing the followings-

npm install aframe
npm install -D @types/aframe
npm install -D @types/three

And then importing it in one of my components-

import * as AFRAME from 'aframe';

And then using it-

AFRAME.registerComponent('test-obj', {
    init: function () {
    }
});

enter image description here

Upvotes: 0

Noble Dinasaur
Noble Dinasaur

Reputation: 107

I was working in an Angular 9 project, which uses webpack to handle dependency.

Having these following imports

import { Component, OnInit } from '@angular/core';
import * as AFRAME from 'aframe';
import * as THREE from 'three';

...

AFRAME.registerComponent('box', {
...
  // Create mesh.
  this.mesh = new THREE.Mesh(this.geometry, this.material);

  // Set mesh on entity.
  el.setObject3D('mesh', this.mesh);
...

The console shows the same error as your error:

core:a-node:error Failure loading node:   
Error: `Entity.setObject3D` was called with an object that was not an instance of THREE.Object3D.

Looking the transpiled code, we see that the import for THREE is a Module object

/* harmony import */ var three__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! three */ "./node_modules/three/build/three.module.js");

Which the code uses three__WEBPACK_IMPORTED_MODULE_2__ as the reference to create the Mesh, which is not the global THREE but a Module of THREE (since threejs provides it as a module build/three.module.js).

three__WEBPACK_IMPORTED_MODULE_2__ === THREE
// false
three__WEBPACK_IMPORTED_MODULE_2__ + ''
// [object Module]
THREE + ''
// [object Object]

The imported AFRAME, however, has the reference to the global THREE, which it internally uses it for check instances. Note that AFRAME does not provide itself as a module, so webpack resolves as the global AFRAME.

three__WEBPACK_IMPORTED_MODULE_2__ === THREE
// false
aframe__WEBPACK_IMPORTED_MODULE_1__.THREE === THREE
// true
aframe__WEBPACK_IMPORTED_MODULE_1__ === AFRAME
// true

Note that typescript is able to recognize AFRAME.THREEas the THREE type, thus having all the benefit of the THREE type.

So the import * as THREE from 'three'; is not needed if you are using AFRAME.THREE.

Here is an example of my registerComponent

AFRAME.registerComponent('box', {
  schema: {
    width: {type: 'number', default: 1},
    height: {type: 'number', default: 1},
    depth: {type: 'number', default: 1},
    color: {type: 'color', default: '#AAA'}
  },
  init() {
    const data = this.data;
    const el = this.el;
    // Extract THREE
    const {THREE} = AFRAME;

    // Create geometry.
    this.geometry = new THREE.BoxBufferGeometry(data.width, data.height, data.depth);

    // Create material.
    this.material = new THREE.MeshStandardMaterial({color: data.color});

    // Create mesh.
    this.mesh = new THREE.Mesh(this.geometry, this.material);

    // Set mesh on entity.
    el.setObject3D('mesh', this.mesh);
  }
});

Upvotes: 1

Diagonal Think
Diagonal Think

Reputation: 323

finally i've solved the problem without include directly the threejs library.

my import section was this

import * as THREE from 'three';
declare var AFRAME;

i've deleted the first import and now all it's okay. now i can create a 3d object in this mode

el.setObject3D("mesh", new AFRAME.THREE.Object3D());

Upvotes: 2

Related Questions