这里的代码中似乎有些我不理解的东西。它一直在抛出错误,尽管在我看来一切都正确。可能有人可以发现它...
我知道这个类很长,但是我认为插入整个代码会更好。当我尝试使用this.scene.add(object)将3D模型添加到场景中时,它在createScene()
方法内崩溃了,尽管场景已经使用this.scene = new THREE.Scene()
在此方法的顶部进行了初始化尝试使用空对象在类顶部初始化它,但这无济于事。
说实话,Angular还很陌生,不知道在哪里查找错误。错误显示为无法读取未定义的属性“场景” 。
最奇怪的是,如果注释掉该行,则在create light方法中使用相同的行来添加光,这似乎很好。 obj 3D模型也可以很好地加载,并且不会放入错误括号中,所以我猜不是。
如果有人发现错误,将非常感谢。谢谢。
import { AfterContentInit, Component, ElementRef, HostListener, OnInit, ViewChild } from '@angular/core';
import * as THREE from 'three-full';
@Component({
selector: 'app-home',
templateUrl: './home.component.html',
styleUrls: ['./home.component.css']
})
export class HomeComponent implements AfterContentInit {
private renderer: THREE.WebGLRenderer;
private camera: THREE.PerspectiveCamera;
private cameraTarget: THREE.Vector3;
public scene: THREE.Scene = {make: null};
public fieldOfView: number = 60;
public nearClippingPane: number = 1;
public farClippingPane: number = 1100;
public controls: THREE.OrbitControls;
@ViewChild('canvas')
private canvasRef: ElementRef;
constructor() {
this.render = this.render.bind(this);
this.onModelLoadingCompleted = this.onModelLoadingCompleted.bind(this);
}
ngAfterContentInit() {
this.createScene();
this.createLight();
this.createCamera();
this.startRendering();
this.addControls();
}
private get canvas(): HTMLCanvasElement {
return this.canvasRef.nativeElement;
}
private createScene() {
this.scene = new THREE.Scene();
var objLoader = new THREE.OBJLoader();
var myMan: any = {};
objLoader.load(
// resource URL
'/assets/man.obj',
// called when resource is loaded
function ( object ) {
myMan = object;
this.scene.add(object);
},
// called when loading is in progresses
function ( xhr ) {
console.log( ( xhr.loaded / xhr.total * 100 ) + '% loaded' );
},
// called when loading has errors
function ( error ) {
console.log( 'An error happened' );
}
);
}
public render() {
this.renderer.render(this.scene, this.camera);
}
private onModelLoadingCompleted(collada) {
var modelScene = collada.scene;
this.scene.add(modelScene);
this.render();
}
private createLight() {
var light = new THREE.PointLight(0xffffff, 1, 1000);
light.position.set(0, 0, 100);
this.scene.add(light);
var light = new THREE.PointLight(0xffffff, 1, 1000);
light.position.set(0, 0, -100);
this.scene.add(light);
}
private createCamera() {
let aspectRatio = this.getAspectRatio();
this.camera = new THREE.PerspectiveCamera(
this.fieldOfView,
aspectRatio,
this.nearClippingPane,
this.farClippingPane
);
// Set position and look at
this.camera.position.x = 10;
this.camera.position.y = 10;
this.camera.position.z = 100;
}
private getAspectRatio(): number {
let height = this.canvas.clientHeight;
if (height === 0) {
return 0;
}
return this.canvas.clientWidth / this.canvas.clientHeight;
}
private startRendering() {
this.renderer = new THREE.WebGLRenderer({
canvas: this.canvas,
antialias: true
});
this.renderer.setPixelRatio(devicePixelRatio);
this.renderer.setSize(this.canvas.clientWidth, this.canvas.clientHeight);
this.renderer.shadowMap.enabled = true;
this.renderer.shadowMap.type = THREE.PCFSoftShadowMap;
this.renderer.setClearColor(0xffffff, 1);
this.renderer.autoClear = true;
let component: HomeComponent = this;
(function render() {
//requestAnimationFrame(render);
component.render();
}());
}
public addControls() {
this.controls = new THREE.OrbitControls(this.camera);
this.controls.rotateSpeed = 1.0;
this.controls.zoomSpeed = 1.2;
this.controls.addEventListener('change', this.render);
}
public onMouseDown(event: MouseEvent) {
console.log("onMouseDown");
event.preventDefault();
// Example of mesh selection/pick:
var raycaster = new THREE.Raycaster();
var mouse = new THREE.Vector2();
mouse.x = (event.clientX / this.renderer.domElement.clientWidth) * 2 - 1;
mouse.y = - (event.clientY / this.renderer.domElement.clientHeight) * 2 + 1;
raycaster.setFromCamera(mouse, this.camera);
var obj: THREE.Object3D[] = [];
this.findAllObjects(obj, this.scene);
var intersects = raycaster.intersectObjects(obj);
console.log("Scene has " + obj.length + " objects");
console.log(intersects.length + " intersected objects found")
intersects.forEach((i) => {
console.log(i.object); // do what you want to do with object
});
}
private findAllObjects(pred: THREE.Object3D[], parent: THREE.Object3D) {
// NOTE: Better to keep separate array of selected objects
if (parent.children.length > 0) {
parent.children.forEach((i) => {
pred.push(i);
this.findAllObjects(pred, i);
});
}
}
public onMouseUp(event: MouseEvent) {
console.log('Mouse Up');
}
@HostListener('window:resize', ['$event'])
public onResize(event: Event) {
this.canvas.style.width = "100%";
this.canvas.style.height = "100%";
console.log("onResize: " + this.canvas.clientWidth + ", " + this.canvas.clientHeight);
this.camera.aspect = this.getAspectRatio();
this.camera.updateProjectionMatrix();
this.renderer.setSize(this.canvas.clientWidth, this.canvas.clientHeight);
this.render();
}
@HostListener('document:keypress', ['$event'])
public onKeyPress(event: KeyboardEvent) {
console.log("onKeyPress: " + event.key);
}
}
答案 0 :(得分:0)
在Java中启动该函数之前,必须有一个指向它的指针。 How to access the correct `this` inside a callback?
private createScene() {
this.scene = new THREE.Scene();
var objLoader = new THREE.OBJLoader();
var self = this; //ADDED THIS BEFORE FUNCTION START
objLoader.load(
// resource URL
'/assets/man.obj',
// called when resource is loaded
function ( object ) {
self.onBodyLoadingCompleted(object); //CAN REFERENCE THE CORRECT OBJECT NOW
},
// called when loading is in progresses
function ( xhr ) {
console.log( ( xhr.loaded / xhr.total * 100 ) + '% loaded' );
},
// called when loading has errors
function ( error ) {
console.log( 'An error happened' );
}
);
}