Camera.js:104 Uncaught TypeError: Cannot read properties of undefined (reading 'attributes')

974 views Asked by At

Why am I getting this error?Camera.js:104 Uncaught TypeError: Cannot read properties of undefined (reading 'attributes') at u.frustumIntersectsMesh (Camera.js:104:28). I'm using the OGL library? There is a media.js class where the error only pops up when a create a mesh(createMesh) and use setParent to add it to the scene.

import { Mesh, Program, Texture } from "ogl";
import fragment from "shaders/fragment.glsl";
import vertex from "shaders/vertex.glsl";

export default class {
  constructor({
    geometry,
    gl,
    image,
    index,
    length,
    renderer,
    scene,
    screen,
    text,
    viewport,
  }) {
    this.geometry = geometry;
    this.gl = gl;
    this.image = image;
    this.index = index;
    this.length = length;
    this.scene = scene;
    this.screen = screen;

    this.viewport = viewport;

    this.createShader();
    this.createMesh();

    this.onResize();
  }

  createShader() {
    const texture = new Texture(this.gl, {
      generateMipmaps: false,
    });

    this.program = new Program(this.gl, {
      fragment,
      vertex,
      uniforms: {
        tMap: { value: texture },
        uPlaneSizes: { value: [0, 0] },
        uImageSizes: { value: [0, 0] },
        uViewportSizes: { value: [this.viewport.width, this.viewport.height] },
      },
      transparent: true,
    });

    const image = new Image();

    image.src = this.image.src;
    image.onload = (_) => {
      texture.image = image;

      this.program.uniforms.uImageSizes.value = [
        image.naturalWidth,
        image.naturalHeight,
      ];
    };
  }

  createMesh() {
    this.plane = new Mesh(this.gl, {
      geometry: this.geometry,
      program: this.program,
    });

    this.plane.setParent(this.scene);
  }

  onResize({ screen, viewport } = {}) {
    if (screen) {
      this.screen = screen;
    }

    if (viewport) {
      this.viewport = viewport;

      this.plane.program.uniforms.uViewportSizes.value = [
        this.viewport.width,
        this.viewport.height,
      ];
    }

    this.scale = this.screen.height / 1500;

    this.plane.scale.y =
      (this.viewport.height * (900 * this.scale)) / this.screen.height;
    this.plane.scale.x =
      (this.viewport.width * (700 * this.scale)) / this.screen.width;

    this.plane.program.uniforms.uPlaneSizes.value = [
      this.plane.scale.x,
      this.plane.scale.y,
    ];
  }

import { Renderer, Camera, Transform, Plane } from "ogl";
import map from "lodash/map";
import Media from "./Media";

export default class Canvas {
  constructor() {
    this.createRenderer();
    this.createCamera();
    this.createScene();

    this.onResize();

    this.createMedias();

    this.update();

    this.addEventListeners();
  }

  createRenderer() {
    this.renderer = new Renderer();

    this.gl = this.renderer.gl;
    this.gl.clearColor(0.79607843137, 0.79215686274, 0.74117647058, 1);

    document.body.appendChild(this.gl.canvas);
  }

  createCamera() {
    this.camera = new Camera(this.gl);
    this.camera.fov = 45;
    this.camera.position.z = 20;
  }

  createScene() {
    this.scene = new Transform();
  }

  createGeometry() {
    this.planeGeometry = new Plane(this.gl, {
      heightSegments: 50,
      widthSegments: 100,
    });
  }

  createMedias() {
    this.mediasImages = document.querySelectorAll(".home__gallery__image");
    console.log(this.mediasImages);
    this.medias = map(this.mediasImages, (image, index) => {
      // console.log(image);
      const media = new Media({
        geometry: this.planeGeometry,
        gl: this.gl,
        image,
        index,
        length: this.mediasImages.length,
        scene: this.scene,
        screen: this.screen,

        viewport: this.viewport,
      });

      return media;
    });
  }

  /**
   * Events.
   */
  onTouchDown(event) {}

  onTouchMove(event) {}

  onTouchUp(event) {}

  onWheel(event) {}

  /**
   * Resize.
   */
  onResize() {
    this.screen = {
      height: window.innerHeight,
      width: window.innerWidth,
    };

    this.renderer.setSize(this.screen.width, this.screen.height);

    this.camera.perspective({
      aspect: this.gl.canvas.width / this.gl.canvas.height,
    });

    const fov = this.camera.fov * (Math.PI / 180);
    const height = 2 * Math.tan(fov / 2) * this.camera.position.z;
    const width = height * this.camera.aspect;

    this.viewport = {
      height,
      width,
    };

    if (this.medias) {
      this.medias.forEach((media) =>
        media.onResize({
          screen: this.screen,
          viewport: this.viewport,
        })
      );
    }
  }

  /**
   * Update.
   */
  update() {
    this.renderer.render({
      scene: this.scene,
      camera: this.camera,
    });
    this.medias.forEach((media) => media.update(this.scroll, this.direction));

    window.requestAnimationFrame(this.update.bind(this));
  }

  /**
   * Listeners.
   */
  addEventListeners() {
    window.addEventListener("resize", this.onResize.bind(this));

    window.addEventListener("mousewheel", this.onWheel.bind(this));
    window.addEventListener("wheel", this.onWheel.bind(this));

    window.addEventListener("mousedown", this.onTouchDown.bind(this));
    window.addEventListener("mousemove", this.onTouchMove.bind(this));
    window.addEventListener("mouseup", this.onTouchUp.bind(this));

    window.addEventListener("touchstart", this.onTouchDown.bind(this));
    window.addEventListener("touchmove", this.onTouchMove.bind(this));
    window.addEventListener("touchend", this.onTouchUp.bind(this));
  }
}

I rechecked the doc and everything but still no clue on this error. The console output is kind of ambiguous.

1

There are 1 answers

0
Nabeel Ahmed On

You need to call this.createGeometry method before this.createMedia in your Canvas class constructor

Here is your updated constructor method:

export default class Canvas {
constructor() {
    this.createRenderer();
    this.createCamera();
    this.createScene();

    this.onResize();

    this.createGeometry()
    this.createMedias();

    this.update();

    this.addEventListeners();
  }
// ...