Angular не может прочитать свойство undefined нового объекта - PullRequest
0 голосов
/ 21 сентября 2018

Кажется, здесь есть кое-что, чего я не понимаю в этом коде.Он продолжает выдавать ошибку, хотя мне все кажется правильным.Возможно, кто-то может заметить это ...

Я знаю, что класс довольно длинный, но я подумал, что было бы лучше вставить весь код.Сбой внутри метода createScene(), когда я пытаюсь добавить свою 3D-модель в сцену с помощью this.scene.add (объект), хотя сцена была инициализирована в верхней части этого метода с помощью this.scene = new THREE.Scene(), и я также попытался инициализировать еена вершине класса с пустым объектом, но это не помогает.

Если честно, совсем новичок в angular и не знаю, где искать ошибку.Ошибка читает Невозможно прочитать свойство 'scene' из неопределенного .

Самое странное, что если эта строка закомментирована, те же строки используются для добавления света в методе создания света, и кажется,быть в порядке.3D-модель obj также отлично загружается и не входит в скобки ошибок, так что я не думаю, что это так.

Был бы очень признателен, если бы кто-то смог обнаружить ошибку.Спасибо.

        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);
            }



        }

1 Ответ

0 голосов
/ 21 сентября 2018

Перед запуском функции в java должен быть указатель на это. Как получить доступ к правильному `this` внутри обратного вызова?

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' );


    }


  );

}

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...