0

I'm trying for the first time to render 3D things on my browser. Here's few informations about my app :

I get a 3D model on clara.io (https://clara.io/view/1a03ac6b-d6b5-4c2d-9f1a-c80068311396) and downloaded it as JSON and as .obj (I wanted to try both ways), but I fail to render it on my screen.

Here's some code :

fox.component.html :

<div id="rendu"></div>

fox.component.ts :

import { Component, OnInit, ElementRef, ViewChild } from '@angular/core';
import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap';
import { JhiEventManager } from 'ng-jhipster';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs/Observable';
import { Detector } from 'detector-js';
const raf = require('raf');
import { LoginModalService, Principal, Account } from 'app/core';

import * as THREE from 'three-full';

@Component({
    selector: 'jhi-poc',
    templateUrl: './fox.component.html',
    styleUrls: ['fox.component.scss']
})
export class FoxComponent implements OnInit {
    @ViewChild('rendu') rendererContainer: ElementRef;
    camera: THREE.PerspectiveCamera = new THREE.PerspectiveCamera();
    scene: THREE.Scene = new THREE.Scene();
    renderer: THREE.WebGLRenderer = new THREE.WebGLRenderer();
    geometry: THREE.Geometry = new THREE.Geometry();
    material: THREE.MeshBasicMaterial = new THREE.MeshBasicMaterial();
    mesh: THREE.Mesh = new THREE.Mesh();

    constructor(private http: HttpClient) {}

    ngOnInit() {
        const _this = this;

        _this.camera = new THREE.PerspectiveCamera(75, (window.innerWidth * 3 / 4) / (window.innerHeight * 3 / 4), 0.01, 1000);
        _this.camera.position.z = 5;

        _this.scene = new THREE.Scene();

        _this.renderer = new THREE.WebGLRenderer({ alpha: true });
        _this.renderer.setSize(window.innerWidth * 3 / 4, window.innerHeight * 3 / 4);
        _this.renderer.setClearColor(new THREE.Color(0.7, 0.7, 0.7);
        const loader = new THREE.OBJLoader2();
        const url = '3D/fox.json';
        loader.load(url, function(obj) {
            _this.scene.add(obj.detail.loaderRootNode);
            console.log(obj);
        });

        const light = new THREE.AmbientLight(0.7, 0.7, 0.7);
        _this.scene.add(light);
        document.getElementById('rendu').appendChild(this.renderer.domElement);
        _this.renderer.render( _this.scene, _this.camera );
    }
}

You can download json or .obj files from the link I gave above.

Problem is, weither I try with .obj or .json, I only get a gray empty canvas. No error in console, so I'm a bit lost about what I do wrong here. I displayed the result of the load() function in console :

{detail: {…}}
    detail:
        instanceNo: 0
        loaderRootNode: Group
            castShadow: false
            children: []
            frustumCulled: true
            layers: Layers {mask: 1}
            matrix: Matrix4 {elements: Array(16)}
            matrixAutoUpdate: true
            matrixWorld: Matrix4 {elements: Array(16)}
            matrixWorldNeedsUpdate: false
            name: ""
            parent: Scene {uuid: "066CCCF6-B0DE-42FA-AA60-9679BFB688E3", name: "", type: "Scene", parent: null, children: Array(2), …}
            position: Vector3 {x: 0, y: 0, z: 0}
            quaternion: Quaternion {_x: 0, _y: 0, _z: 0, _w: 1, onChangeCallback: ƒ}
            receiveShadow: false
            renderOrder: 0
            rotation: Euler {_x: 0, _y: 0, _z: 0, _order: "XYZ", onChangeCallback: ƒ}
            scale: Vector3 {x: 1, y: 1, z: 1}
            type: "Group"
            up: Vector3 {x: 0, y: 1, z: 0}
            userData: {}
            uuid: "C98D648A-6929-4EFA-AF62-7C27270F5D4E"
            visible: true
            id: 24
            modelViewMatrix: Matrix4 {elements: Array(16)}
            normalMatrix: Matrix3 {elements: Array(9)}
            __proto__: Object3D
        modelName: ""
        __proto__: Object
    __proto__: Object

Seems like the object is properly read to me. Don't hesitate to ask if you need anything else, I'm not familiar with three.js or 3D in general.

UPDATE :

0

2 Answers 2

1
 const loader = new THREE.OBJLoader2();
 const url = '3D/fox.json';
 loader.load(url, function(obj) {

You can't load JSON files with OBJLoader2 which is exclusively intended for OBJ files. Try it with THREE.ObjectLoader instead.

three.js R104

Sign up to request clarification or add additional context in comments.

9 Comments

Using ObjectLoader leads me to this error in browser console : webpack-internal:///./node_modules/three-full/builds/Three.es.js:141595 ObjectLoader: You have to import LegacyJSONLoader in order load geometry data of type "Geometry". parseGeometries @ webpack-internal:///./node_modules/three-full/builds/Three.es.js:141595 I also tried using an .obj file with OBJLoader2, but same as with .json file : nothing appears.
As mentioned in the error message you have to include LegacyJSONLoader into your project. However, I suggest you download your model as glTF and use GLTFLoader instead. It's the recommended 3D format of three.js, see threejs.org/docs/index.html#manual/en/introduction/…
Using GLTF file and GLTFLoader gives me the same output : gray empty canvas. No error in browser console. I converted the obj file with 52.4.31.236/convertmodel.html
Also, I just tried with LegacyJSONLoader, and I have this error in browser console : JSONLoader: 3D/fox.json should be loaded with ObjectLoader instead.
Can you please share you code as a live example? Or maybe share the entire repository? In any event, you should definitely target a glTF based workflow.
|
0

Alright, I found few things.

First of all, I ended using GLTF files, and GLTFLoader as recommended. Then, I started over, using this example : https://github.com/makimenko/angular-three-examples/blob/master/src/app/scene/scene.component.ts

I don't really know if using <canvas> instead of <div> in .html is what I missed, but it might be. I used all the code from the link I gave and only changed one part :

private createScene() {
    this.scene = new THREE.Scene();
    const loader = new THREE.GLTFLoader();
    loader.load('3D/fox.gltf', this.onModelLoadingComplete);
}

Works perfectly fine now. This code uses more options for the rendering part, and use AfterViewInit (I was trying to do it in OnInit), and canvas as I said. That's the big differences I saw. Anyway, it works now.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.