Zooming through globe with vite/cesium/react

Good Morning Cesium,
Recently we changed our frontend tooling from webpack to vite. Ever since doing so, we seem to have broken Zoom when we try to set the reference frame to Earth Centered Inertial. The line of code causing the problem is here:

map.scene.postUpdate.addEventListener(cameraTrackEci);

Here’s the function being called:

const cameraTrackEci = (scene, time) => {
  if (scene.mode !== Cesium.SceneMode.SCENE3D) {
    return;
  }
  const icrfToFixed = Cesium.Transforms.computeIcrfToFixedMatrix(time);

  if (Cesium.defined(icrfToFixed)) {
    const { camera } = scene;
    const offset = Cesium.Cartesian3.clone(camera.position);
    const transform = Cesium.Matrix4.fromRotationTranslation(icrfToFixed);
    camera.lookAtTransform(transform, offset);
  }
};

It seems like the camera isn’t aware of it’s height/altitude. I can seemingly zoom right through the globe and when panning left/right/up/down the map moves so fast, it’s hard to control. I found another way to set ECI but had the same zoom issue.

After some tinkering, I managed to get small example that exhibits the problem working on codesandbox. You will have to provide the Cesium.Ion token to get the globe to show up.

I hope that’s ok? If some kind person might take a look and offer advise it would be much appreciated.

sg

Here is the entire React App:

import { Viewer } from "cesium";
import React, {useEffect, useRef, useState} from "react";
import * as Cesium from 'cesium';
import "./App.css";

const cameraTrackEci = (scene, time) => {
  if (scene.mode !== Cesium.SceneMode.SCENE3D) {
    return;
  }
  const icrfToFixed = Cesium.Transforms.computeIcrfToFixedMatrix(time);

  if (Cesium.defined(icrfToFixed)) {
    const { camera } = scene;
    const offset = Cesium.Cartesian3.clone(camera.position);
    const transform = Cesium.Matrix4.fromRotationTranslation(icrfToFixed);
    camera.lookAtTransform(transform, offset);
  }
};
function App() {
  const divRef = useRef(null);


  useEffect(() => {
    const map = new Viewer(divRef.current);

    map.scene.postUpdate.addEventListener(cameraTrackEci);

    return () => map.destroy();
  }, []);

  return (
    <div className="App">
      <div className="cesium" ref={divRef} />
    </div>
  );
}

export default App;

Hi there,

Huh, I’m not sure why switching build tooling would cause a functional issue such as this. Would you be able to provide your build configuration?

Certainly Gabby,
Thank you for responding. Here is the vite.config.js

import { defineConfig } from "vite";
import reactRefresh from "@vitejs/plugin-react-refresh";
import cesium from "vite-plugin-cesium";

export default defineConfig({
  plugins: [reactRefresh(), cesium()]
});

package.json

{
  "name": "vite-react-js",
  "private": true,
  "version": "0.0.0",
  "type": "module",
  "scripts": {
    "dev": "vite",
    "build": "vite build",
    "preview": "vite preview"
  },
  "dependencies": {
    "@vitejs/plugin-react-refresh": "1.3.6",
    "cesium": "1.104.0",
    "react": "^18.2.0",
    "react-dom": "^18.2.0",
    "vite-plugin-cesium": "1.2.22"
  },
  "devDependencies": {
    "@types/react": "^18.0.17",
    "@types/react-dom": "^18.0.6",
    "@vitejs/plugin-react": "^2.0.1",
    "vite": "^3.0.7"
  },
  "keywords": [],
  "description": ""
}

Versions:
node: 18.17.0
yarn: 1.22.19
vite: 2.9.16

Incidentally, I did put up an codesandbox example of the problem, in action so-to-speak in the original post, up above.

Got it, thanks.

Yes, I can reproduce the issue in a standalone Sandcastle outside of using vite.

Which version of CesiumJS were you using before the switch?

We were using 1.84. I have been digging around and am starting to think ECI and zoom just don’t make a lot of sense together. As I zoom in very slowly while in ECI, as I get closer and closer to the surface the Earth the spin of the the globe gets faster and faster. At some point it must give up trying to tile as fast as the earth is spinning, just guessing.

I’m still unsure why that behavior would have broken sometime after 1.84, but my best guess would be the picking result, which would be used by the camera result to keep the camera from going under terrain.

As a next step I would suggest identifying in which version of CesiumJS the issue starts to show up. From there, we should be able to narrow down the cause.