Hi guys,
So I am trying to build an application that is using Angular 10 with threejs.
I am loading an obj file into scene by selecting a file to load through File input. Upon selecting the file I can load the obj into a scene. This is working but it is not in the center of it’s respective div element that I am loading it into. See component.ts and component.html below
Edit 1
OK so the problem I am having is that the #rendererContainer I am passing to create the scene is not conforming to the angular flex layout rules. It seems to be doing it’s own thing. What is the correct way to set this up inside the component.ts file so that when it creates the scene it stays inside the bounds of my div element?
So a couple of questions
- I am unsure what window.innerWidth & window.innerHeight are? Do these relate to the div container window size or the full window of the application?
- I am not sure if this is the correct way of accessing the div container in question @ViewChild(‘rendererContainer’) rendererContainer: ElementRef;
- Am I calling the resize event correctly i.e is this passing the size of the container element or am I passing the over all application window size?
- How should I pass the correct size of the container window to my component.ts file?
- My scene background is black. How do I change this?
- How do I limit the size of the scene window - is that just a html thing using FxLayout?
Thanks in advance
I have the following code in my component.ts file
import {Component, ViewChild, ElementRef} from '@angular/core';
import * as THREE from 'three';
import { ResizedEvent } from 'angular-resize-event';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';
import { OBJLoader2 } from 'three/examples/jsm/loaders/OBJLoader2';
import * as ROSLIB from 'roslib';
@Component({
selector: 'app-part-view',
templateUrl: './part-view.component.html',
styleUrls: ['./part-view.component.css']
})
export class PartViewComponent
{
@ViewChild('rendererContainer') rendererContainer: ElementRef;
axisHelper = new THREE.AxesHelper(500);
renderer = new THREE.WebGLRenderer({antialias: true});
scene = null;
camera = null;
mesh = null;
controls = null;
ambientLight = null;
object = null;
objtext = null;
ros: any;
clr_cal_publisher:any;
constructor() {
this.scene = new THREE.Scene();
this.camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 1, 10000);
this.camera.position.z = 1000;
this.ambientLight = new THREE.AmbientLight( 0xcccccc, 1 );
this.scene.add( this.ambientLight );
this.controls = new OrbitControls( this.camera, this.renderer.domElement );
this.controls.enableZoom = true;
this.controls.enablePan = false;
if (this.object != null )
{
this.scene.add(this.object);
}
this.scene.add(this.axisHelper);
}
ngAfterViewInit() {
this.renderer.setSize(window.innerWidth, window.innerHeight);
this.rendererContainer.nativeElement.appendChild(this.renderer.domElement);
this.animate();
}
animate() {
window.requestAnimationFrame(() => this.animate());
if (this.object != null)
this.renderer.render(this.scene, this.camera);
this.controls.update();
}
onResize(event) {
this.camera.aspect = (event.target.innerWidth) / (event.target.innerHeight);
this.renderer.setSize( (event.target.innerWidth), (event.target.innerHeight) );
this.camera.updateProjectionMatrix();
}
loadObject(fileContents,rotationX,rotationY,rotationZ) {
console.log("loadObject called "+ fileContents);
this.objtext = fileContents;
if (this.object != null )
this.scene.remove(this.object);
var loader = new OBJLoader2();
loader.setLogging(true, true);
loader.setUseIndices(true);
loader.setDisregardNormals(true);
this.object = loader.parse(this.objtext);
var boxObj = new THREE.Box3();
this.object.rotation.x = rotationX;
this.object.rotation.y = rotationY;
this.object.rotation.z = rotationZ;
var boxHelper = new THREE.BoxHelper( this.object );
boxObj.setFromObject( boxHelper );
var cent = new THREE.Vector3();
boxObj.getCenter(cent);
this.camera.position.set(0,0,-Math.max(Math.abs(cent.x),Math.abs(cent.y),Math.abs(cent.z)) -50);
this.object.position.x = -cent.x;
this.object.position.y = -cent.y;
this.object.position.z = -cent.z;
this.scene.add(this.object);
}
changeListener($event) : void {
this.readThis($event.target);
}
readThis(inputValue: any) : void {
var file:File = inputValue.files[0];
var myReader:FileReader = new FileReader();
var txt;
let that = this;
myReader.onloadend = function(e){
// you can perform an action with readed data here
//console.log(myReader.result);
console.log("Loading obj file");
txt = myReader.result;
that.loadObject(txt,0,0,0);
}
myReader.readAsText(file);
}
}
I have the following code inside my component.html
<div>
Select file:
<input type="file" (change)="changeListener($event)">
</div>
<div class="container">
<div id="" class="flex-container" fxLayoutGap="50px" fxLayout="row" fxLayoutAlign="space-evenly none">
<div id="visual_id" fxFlex="1 1 0" fxLayout >
<div #rendererContainer (window:resize)="onResize($event)" >
</div>
</div>
<div id="sidebar_id" fxFlex fxLayout fxLayoutGap="50px" >
<mat-tab-group>
<mat-tab label="First"> Content 1 </mat-tab>
<mat-tab label="Second"> Content 2 </mat-tab>
<mat-tab label="Third"> Content 3 </mat-tab>
</mat-tab-group>
</div>