babylonjs从importedMesh返回未定义

时间:2019-12-21 00:08:56

标签: javascript typescript babylonjs

我正在使用BabylonJS,我只是从Blender导入了一个网格。

问题是在此行:

         x = this.cube.position.x;

我知道

  

未捕获的TypeError:无法读取未定义的属性“位置”

这是完整的代码:

export class Game {
private canvas: HTMLCanvasElement;
private engine: BABYLON.Engine;
private scene: BABYLON.Scene;
private camera: BABYLON.FreeCamera;
private light: BABYLON.Light;
private skybox: BABYLON.Mesh;
private skyboxMaterial: BABYLON.StandardMaterial;
private waterMesh: BABYLON.Mesh;
private water: Materials.WaterMaterial;
private ground: BABYLON.Mesh;
private groundTexture: BABYLON.Texture;
private groundMaterial: BABYLON.StandardMaterial;
private sphere: BABYLON.Mesh;
private sphereMaterial: BABYLON.StandardMaterial;
private cube: BABYLON.Mesh;


constructor(canvasElement : string) {
    // Create canvas and engine.
    this.canvas = document.getElementById(canvasElement) as HTMLCanvasElement;
    this.engine = new BABYLON.Engine(this.canvas, true);
}

createScene() : void {
    this.scene = new BABYLON.Scene(this.engine);

    this.camera = new BABYLON.FreeCamera("Camera", BABYLON.Vector3.Zero(), this.scene);
    this.camera.attachControl(this.canvas, true);


    this.light = new BABYLON.HemisphericLight("light1", new BABYLON.Vector3(0, 1, 0), this.scene);

    // Skybox
    this.skybox = BABYLON.Mesh.CreateBox("skyBox", 1000.0, this.scene);
    this.skyboxMaterial = new BABYLON.StandardMaterial("skyBox", this.scene);
    this.skyboxMaterial.backFaceCulling = false;
    this.skyboxMaterial.reflectionTexture = new BABYLON.CubeTexture("../../../assets/Terrain/skybox/TropicalSunnyDay", this.scene);
    this.skyboxMaterial.reflectionTexture.coordinatesMode = BABYLON.Texture.SKYBOX_MODE;
    this.skyboxMaterial.diffuseColor = new BABYLON.Color3(0, 0, 0);
    this.skyboxMaterial.specularColor = new BABYLON.Color3(0, 0, 0);
    this.skyboxMaterial.disableLighting = true;
    this.skybox.material = this.skyboxMaterial;

    // Ground
    this.groundTexture = new BABYLON.Texture("../../../assets/Terrain/sand.jpg", this.scene);
    this.groundTexture.vScale = this.groundTexture.uScale = 4.0;

    this.groundMaterial = new BABYLON.StandardMaterial("groundMaterial", this.scene);
    this.groundMaterial.diffuseTexture = this.groundTexture;

    this.ground = BABYLON.Mesh.CreateGround("ground", 512, 512, 32, this.scene, false);
    this.ground.position.y = -1;
    this.ground.material = this.groundMaterial;


    // Sphere
    this.sphereMaterial = new BABYLON.StandardMaterial("sphereMaterial", this.scene);
    this.sphereMaterial.diffuseTexture = new BABYLON.Texture("../../../assets/Terrain/wood.jpg", this.scene);

    this.sphere = BABYLON.Mesh.CreateSphere("sphere", 16, 10, this.scene);
    this.sphere.position.y = 20;
    this.sphere.material = this.sphereMaterial;

        // The first parameter can be used to specify which mesh to import. Here we import all meshes
    BABYLON.SceneLoader.ImportMesh("cube", "../../../assets/Vessel/", "untitled.glb", this.scene, function (newMeshes) {
        this.cube = newMeshes[0];
        this.cube.position.y = 20;
        this.cube.position.x = 20;
    }.bind(this));


        // Water
    this.waterMesh = BABYLON.Mesh.CreateGround("waterMesh", 512, 512, 32, this.scene, false);
    this.water = new Materials.WaterMaterial("water", this.scene, new BABYLON.Vector2(1024, 1024));
    this.water.backFaceCulling = true;
    this.water.bumpTexture = new BABYLON.Texture("../../../assets/Terrain/waterbump.png", this.scene);
    this.water.windForce = -10;
    this.water.waveHeight = 0.5;
    this.water.bumpHeight = 0.1;
    this.water.waveLength = 0.1;
    this.water.waveSpeed = 50.0;
    this.water.colorBlendFactor = 0;
    this.water.windDirection = new BABYLON.Vector2(1, 1);
    this.water.colorBlendFactor = 0;
    this.waterMesh.material = this.water;

    this.water.addToRenderList(this.skybox);
    this.water.addToRenderList(this.ground);
    this.water.addToRenderList(this.sphere);
    this.water.addToRenderList(this.cube);

        ////////// RAY CAST TO FIND WATER HEIGHT ////////////
    //var angle = 0;
    this.scene.registerBeforeRender(function() {
        let time = this.water._lastTime / 100000;
        let x = this.sphere.position.x;
        let z = this.sphere.position.z;
        this.sphere.position.y = Math.abs((Math.sin(((x / 0.05) + time * this.water.waveSpeed)) * this.water.waveHeight * this.water.windDirection.x * 5.0) + (Math.cos(((z / 0.05) +  time * this.water.waveSpeed)) * this.water.waveHeight * this.water.windDirection.y * 5.0));

        x = this.cube.position.x;
        z = this.cube.position.z;
        this.cube.position.y = Math.abs((Math.sin(((x / 0.05) + time * this.water.waveSpeed)) * this.water.waveHeight * this.water.windDirection.x * 5.0) + (Math.cos(((z / 0.05) +  time * this.water.waveSpeed)) * this.water.waveHeight * this.water.windDirection.y * 5.0));

    }.bind(this));
}

doRender() : void {
    // Run the render loop.
    this.engine.runRenderLoop(() => {
        this.scene.render();
    });

    // The canvas/window resize event handler.
    window.addEventListener('resize', () => {
        this.engine.resize();
    });
}

我知道我可以进行空检查,但是我不明白为什么我的多维数据集是未定义的,因为(ImportMesh)是一个Synched函数。

一旦我设置了空检查,我就会摆脱错误。

1 个答案:

答案 0 :(得分:0)

由于bue是使用ImportMesh函数异步加载的,因此您在前几帧中没有使用它,这会导致在registerBeforeRender函数中引发异常,请尝试以下操作:

    this.scene.registerBeforeRender(function() {
        let time = this.water._lastTime / 100000;
        let x = this.sphere.position.x;
        let z = this.sphere.position.z;
        this.sphere.position.y = Math.abs((Math.sin(((x / 0.05) + time * this.water.waveSpeed)) * this.water.waveHeight * this.water.windDirection.x * 5.0) + (Math.cos(((z / 0.05) +  time * this.water.waveSpeed)) * this.water.waveHeight * this.water.windDirection.y * 5.0));

        if(this.cube) {
          x = this.cube.position.x;
          z = this.cube.position.z;
          this.cube.position.y = Math.abs((Math.sin(((x / 0.05) + time * this.water.waveSpeed)) * this.water.waveHeight * this.water.windDirection.x * 5.0) + (Math.cos(((z / 0.05) +  time * this.water.waveSpeed)) * this.water.waveHeight * this.water.windDirection.y * 5.0));
        }

    }.bind(this));

这是一种非常简单的方法。另一种方法是在加载多维数据集之后(在ImportMesh的onSuccess回调中)注册before-Render函数