Reputation: 565
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 :
Upvotes: 0
Views: 1326
Reputation: 565
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.
Upvotes: 0
Reputation: 31076
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
Upvotes: 1