Why typescript + babylon will report an error

Hello!
Can you tell us what are you doing here exactly? What is you dev environment?
You can try this:

cont material = <PBRMaterial>mesh.material
material?.emissiveColor = ....

I want use es6-tween achive animation, The key problem is that I don’t know what is wrong with my verification rules, and various errors are reported.

{
  "compilerOptions": {
    "outDir": "./dist/",
    "noImplicitAny": true,
    "module": "esnext",
    "target": "es5",
    "jsx": "react-jsx",
    "allowJs": true,
    "moduleResolution": "node",
    "forceConsistentCasingInFileNames": true,
    "noImplicitReturns": true,
    "suppressImplicitAnyIndexErrors": true,
    "noUnusedLocals": false,
    "skipLibCheck": true,
    "experimentalDecorators": true,
    "strict": false,
    "allowSyntheticDefaultImports": true,
    "sourceMap": true,
    "lib": [
      "dom",
      "dom.iterable",
      "esnext"
    ],
    "esModuleInterop": true,
    "noFallthroughCasesInSwitch": true,
    "resolveJsonModule": true,
    "isolatedModules": true,
    "noEmit": true
  },
  "include": [
    "src/page"
  ],
  "exclude": [
    "node_modules",
    "build",
    "dist",
    "scripts",
    "webpack"
  ],
  "extends": "./paths.json"
}

Don’t you have an extra }; here?

Can you share the content of the highlightModel.ts file?

sure

import {
  Color3,
  Mesh,
  PBRMaterial,
  Scene,
  AbstractMesh,
  PBRMetallicRoughnessMaterial,
} from "@babylonjs/core";
//@ts-ignore
import { Tween, autoPlay, Easing, removeAll, getAll } from "es6-tween";
import { ModelPart } from "../../constans/type";

export const highlightSelectedParts = (
  currentModelDesign: AbstractMesh[],
  prevModelDesign: AbstractMesh[]
) => {
  const glowColor = Color3.FromHexString("#b3d4e0").toLinearSpace();
  const glowIntensity = 0.35;
  const selectedMeshes = currentModelDesign;

  const deselectedMeshes = prevModelDesign;
  selectedMeshes.forEach((mesh: Mesh) => {
    const counter = { count: 0 };
    autoPlay(true);
    new Tween(counter)
      .to({ count: 1 }, 250)
      .delay(250)
      .easing(Easing.Quadratic.InOut)
      .on("update", ({ count }: any) => {
        const material = <PBRMaterial>mesh.material;
        material.emissiveColor = Color3.Lerp(Color3.Black(), glowColor, count);
      })
      .on("complete", () => {
        new Tween(counter)
          .to({ count: 0 }, 750)
          .delay(500)
          .easing(Easing.Quadratic.InOut)
          .on("update", ({ count }: any) => {
            const material = <PBRMaterial>mesh.material;
            material.emissiveColor = Color3.Lerp(
              Color3.Black(),
              glowColor,
              count
            );
            material.emissiveIntensity = count * glowIntensity;
            material.emissiveColor = Color3.Lerp(
              Color3.Black(),
              glowColor,
              count
            );
          })
          .start();
      })
      .start();
  });
  deselectedMeshes.forEach((mesh: Mesh) => {
    var material = <PBRMaterial>mesh.material;
    material.emissiveColor = Color3.Black();
  });
};

export default null;

change this:
image

to this

  selectedMeshes.forEach(mesh => {

and the same here:
image

There are no other typescript errors reported by my ts linter.

However I can’t see the export default class Game line you were referring to, because it’s in an other file. Can you share it as well?

OK

// eslint-disable-next-line @typescript-eslint/no-var-requires
import {
  Engine,
  Texture,
  StandardMaterial,
  CubicEase,
  EasingFunction,
  CubeTexture,
  Light,
  FreeCamera,
  Scene,
  PBRMetallicRoughnessMaterial,
  SceneLoader,
  Color4,
  ShadowGenerator,
  AssetsManager,
  Color3,
  ArcRotateCamera,
  Vector3,
  DirectionalLight,
  HemisphericLight,
  Mesh,
  Animation,
  DefaultLoadingScreen,
  AbstractMesh,
  Material,
  PBRMaterial,
  AbstractScene,
  PBRBaseMaterial,
} from "@babylonjs/core";
import "@babylonjs/materials";
import "@babylonjs/loaders";
// eslint-disable-next-line @typescript-eslint/no-var-requires
import {
  AbstractButton3D,
  AdvancedDynamicTexture,
  Button,
} from "@babylonjs/gui";
// eslint-disable-next-line @typescript-eslint/no-var-requires
import { createCameras } from "./api/camera/createCamera";
import { mouseEngagementMeter } from "./api/sence/pointer";

import {
  positionViewport,
  setCameraFOV,
  handleResize,
  setCameraViewport,
  updateCamera,
} from "./api/camera/updateCamera";
import { BabylonProps } from "./constans/type";
import { highlightSelectedParts } from "./api/model/highlightModel";
import * as qs from "querystring";
import { configureShadows, addShadows, setShadows } from "./api/light/update";
import { createLight } from "./api/light/create";
import { createLoading } from "./utils/loading";
import { loadTextureAsync } from "./api/model/loadModel";
import { CameraCoordinates } from "./schema/pointer";
import { cloneMaterial } from "./api/material";
import { ScreenshotTools } from "./api/tools/screenTools";
import { aliOSS } from "./utils/oss";
// import * as LOADER from "@babylonjs/loaders";
// import * as GUI from "@babylonjs/gui";
type Data = {
  [key: string]: any;
};
export default class Game {
  public engine: Engine;

  public scene: Scene;

  public materialList: string[];

  public camera: ArcRotateCamera;

  public light: DirectionalLight;

  public light2: HemisphericLight;

  public shadowGenerator: ShadowGenerator;

  public elem: HTMLCanvasElement;

  public babylonProps: BabylonProps;

  public currentMeshList: Array<AbstractMesh>;

  constructor(elem: HTMLCanvasElement) {
    //canvas
    this.elem = elem;

    this.engine = new Engine(elem, true);
    this.scene = new Scene(this.engine);
    // 设置颜色环境颜色
    var color = Color3.FromHexString("#dadee1");
    this.scene.clearColor = Color4.FromColor3(color, 1);
    this.scene.environmentIntensity = 1;
    this.currentMeshList = [];
    // this.babylonProps['engine'] = this.engine;
    // this.scene.debugLayer.show();
  }
  _init(): void {
    createLoading();
    this.engine.displayLoadingUI();
    this.createCamera();
    this.createLight();
    this.light = createLight(this.scene);
    this.shadowGenerator = setShadows(this.light);
    this.loadModle();
    this.effect();
    this.scene.onPointerObservable.add(mouseEngagementMeter({}));
  }
  private effect(): void {
    // this.scene.onBeforeRenderObservable.add(() => {});
    this.scene.registerBeforeRender(() => {
      if (this.scene.isReady() && this.isReadyAll()) {
        setTimeout(() => {
          this.engine.hideLoadingUI();
        }, 1000);
      } else {
        this.engine.displayLoadingUI();
      }
    });
  }
  isReadyAll() {
    let flag = this.scene.meshes?.every(
      (mesh) => mesh.material && mesh.material.isReady(mesh)
    );
    return flag;
  }

  //创建灯光
  createLight() {
    this.light2 = new HemisphericLight(
      "HemiLight",
      new Vector3(1, 1, 0),
      this.scene
    );
    //灯光强度
    this.light2.intensity = 0.95;
  }
  async changeMaterial(name, id) {
    let mesh = this.scene.getMeshByName(name) as any;
    let data = (await this.get(
      "https://cms-oss-sh-dev.oss-cn-shanghai.aliyuncs.com/jpc/2021-03-10/data/data.json"
    )) as Data;
    let list = data.data.reduce((result, current) => {
      if (current.id == id) {
        result.push(...current.list);
      }
      return result;
    }, []);
    try {
      let albedoTexture = await loadTextureAsync(this.scene, list[0]);
      let bumpTexture = await loadTextureAsync(this.scene, list[1]);
      let metallicTexture = await loadTextureAsync(this.scene, list[2]);
      mesh.material = new PBRMaterial("pbr", this.scene);
      mesh.material.metallic = 0.0;
      mesh.material.roughness = 0.75;
      mesh.material.alpha = 1;
      mesh.material.metallicF0Factor = 0;
      mesh.material.albedoTexture = albedoTexture;
      mesh.material.bumpTexture = bumpTexture;
      mesh.material.metallicTexture = metallicTexture;
      mesh.material.metallicTexture.useAmbientOcclusionFromMetallicTextureRed =
        false;
      mesh.material.metallicTexture.useRoughnessFromMetallicTextureGreen = true;
      mesh.material.metallicTexture.metallic = 0;
      const uScale = 16;
      const vScale = 16;
      mesh.material.albedoTexture.uScale = uScale;
      mesh.material.albedoTexture.vScale = vScale;
      mesh.material.bumpTexture.uScale = uScale;
      mesh.material.bumpTexture.vScale = vScale;
      mesh.material.metallicTexture.uScale = uScale;
      mesh.material.metallicTexture.vScale = vScale;
      mesh.material.invertNormalMapX = true;
      mesh.material.invertNormalMapY = true;
    } catch (error) {
      console.log(error);
    }
  }
  async loadModle(): Promise<void> {
    let queryString = window.location.search.split("?")[1];
    let query = qs.parse(queryString);
    let data = (await this.get(
      "https://cms-oss-sh-dev.oss-cn-shanghai.aliyuncs.com/jpc/2021-03-10/data/data.json"
    )) as Data;

    let list = data.data.reduce((result, current) => {
      if (current.id == query.id) {
        result.push(...current.list);
      }
      return result;
    }, []);

    let materialList = list;

    // this.engine.loadingScreen.displayLoadingUI();
    SceneLoader.LoadAssetContainer(
      "https://api.nike.com/customization/model_assets/v1/3f885af9-549b-423a-8b66-ff203eb9c839/1607623565723/",
      "model.gltf",
      this.scene,
      (container) => {
        this.scene.executeWhenReady(() => {
          if (!this.scene.activeCamera) {
            throw new Error(
              "No camera defined in the scene. Please add at least one camera in the project or create one yourself in the code."
            );
          }
          container.meshes.forEach((mesh: any) => {
            if (mesh.name == "shadow_plane") {
              // mesh.isVisible = false;
              return;
            }
            mesh.material = new PBRMaterial("pbr", this.scene);
            mesh.material.metallic = 0.0;
            mesh.material.roughness = 0.75;
            mesh.material.alpha = 1;
            cloneMaterial(mesh);
            // console.log(mesh.material);
            // mesh.material = new PBRMetallicRoughnessMaterial("pbr", this.scene);
            // // mesh.position = new Vector3(0, -800, 0);
            // mesh.material.metallic = 0.0;
            // mesh.material.roughness = 0.75;
            // mesh.material.alpha = 1;
            // mesh.material.metallicF0Factor = 0;

            // mesh.material.useRoughnessFromMetallicTextureAlpha = false;
            // mesh.material.useRoughnessFromMetallicTextureGreen = true;
            // mesh.material.useMetallnessFromMetallicTextureBlue = true;
            // // //截图是模型保持中心
            // mesh.material.useAmbientInGrayScale = true;

            // mesh.alwaysSelectAsActiveMesh = true;

            // let uScale = 16;
            // let vScale = 16;
            // // //颜色

            // mesh.material.baseTexture = new Texture(materialList[0], this.scene);
            // mesh.material.baseTexture.uScale = uScale;
            // mesh.material.baseTexture.vScale = vScale;

            // mesh.material.normalTexture = new Texture(materialList[1], this.scene);
            // mesh.material.normalTexture.uScale = uScale;
            // mesh.material.normalTexture.vScale = vScale;

            // mesh.material.useParallax = true;
            // mesh.material.useParallaxOcclusion = true;
            // mesh.material.parallaxScaleBias = 11;
            // mesh.material.specularPower = 1000.0;

            // // // 金属/粗糙
            // mesh.material.metallicRoughnessTexture = new Texture(materialList[2], this.scene);
            // mesh.material.metallicRoughnessTexture.uScale = uScale;
            // mesh.material.metallicRoughnessTexture.vScale = vScale;
            // mesh.material.invertNormalMapX = true;
            // mesh.material.invertNormalMapY = true;
            addShadows(this.shadowGenerator, mesh);
            // this.shadowGenerator.getShadowMap().renderList.push(mesh);
          });
          console.log(this.scene.getMeshByName("shadow_plane"));
          // this.scene.getMeshByName("shadow_plane").dispose();
          container.addAllToScene();
          // 删除底部
          configureShadows(
            this.scene,
            "shadow_plane",
            "https://api.nike.com/customization/model_assets/v1/3f885af9-549b-423a-8b66-ff203eb9c839/1607623565723/ground_shadow.png"
          );
          // this.scene.getMeshByName("shadow_plane").dispose();

          // this.scene.onPointerObservable.add((pointerInfo) => {
          //   var pickResult = this.scene.pick(this.scene.pointerX, this.scene.pointerY);
          //   if (pickResult.hit) {
          //     console.log(pointerInfo.pickInfo.pickedMesh);
          //   }
          // });
          this.engine.runRenderLoop(() => {
            if (this.scene) {
              this.scene.render();
            }
          });
        });
      },
      null,
      function (err) {
        console.log("err", err);
      }
    );
  }
  get(url) {
    return new Promise((resolve, reject) => {
      let xhr = new XMLHttpRequest();
      xhr.open("get", url, true);
      xhr.onload = function () {
        if (xhr.status == 200) {
          resolve(JSON.parse(xhr.responseText));
        } else {
          reject(null);
        }
      };
      xhr.onerror = function () {
        reject(null);
      };
      xhr.send(null);
    });
  }
  //选择高亮
  highlightSelectedParts = (name, other) => {
    let oherMesh = other.reduce((result, current) => {
      result.push(this.scene.getMeshByName(current));
      return result;
    }, []);
    highlightSelectedParts([this.scene.getMeshByName(name)], oherMesh);
  };

  //创建摄像头
  createCamera() {
    this.camera = createCameras(this.scene, this.elem);
    this.babylonProps = {
      scene: this.scene,
      camera: this.camera,
      engine: this.engine,
    };
    setCameraFOV(this.engine, this.camera);
  }
  createShot() {
    this.setCameraViewport(100);
    // enableStencilBuffer
    setTimeout(() => {
      ScreenshotTools.CreateScreenshotUsingRenderTarget(
        this.engine,
        this.camera,
        {
          width: 100,
          height: 120,
          precision: 10,
        },
        (data) => {
          aliOSS(data, (res) => {
            console.log("上传");
          });
          console.log(data);
        }
      );
    }, 1200);
  }
  public setCameraViewport(val) {
    setCameraViewport(this.camera, { viewportHeightPercent: val });
  }
  setCameraRotate(cameraCoordinates) {
    updateCamera(cameraCoordinates);
  }
  setup(): void {
    // this.scene.createDefaultCameraOrLight(false, true, true);
    this._init();
  }
  run(): void {
    this.engine.runRenderLoop(() => this.scene.render());
  }
  handleResize(babylonProps: BabylonProps, canvasRef) {
    console.log(Engine.LastCreatedScene);
    handleResize(babylonProps, canvasRef);
  }
  bindEvents(): void {
    window.addEventListener("resize", () => {
      this.handleResize(this.babylonProps, { current: this.elem });
      // this.engine.resize()
    });
  }
}

The best way would be to share a github repo because there are so many missing imports that I can’t tell what’s the problem without compiling the script.

2 Likes

@haoguang_shen you are writing ts typings in a .js file, this can not work ?

1 Like

I add file to eslintignore , resolve this problem .

thank you. no work.

Ok, that’s a solution as well :ok_hand:

1 Like

Thank you

1 Like