janvorisek / drie

Drie is a Vue 3 component library for THREE.js made with TypeScript and Composition API.
MIT License
77 stars 2 forks source link

OrthographicCamera :up break mesh rendering #61

Open LeoGrosjean opened 1 year ago

LeoGrosjean commented 1 year ago

with this template :

...
 <OrthographicCamera ref="camera" :position="[0, -20, 0]" :up="[0, 0, 1]" :far="200000">
      <TrackballControls :rotate-speed="0.01" :pan-speed="0.01"/>
 </OrthographicCamera>
...

changing :up to :up="[1, 0, 0]" or :up="[0, 1, 0]" break the camera/scene

janvorisek commented 1 year ago

Can you provide more details? It works in all my scenes.

LeoGrosjean commented 1 year ago
<template>
  <div class="example-with-props">
    <div class="example" style="width: 50vh; height: 50vh;">
      <Renderer ref="renderer" :antialias="true" autoResize="true">
        <OrthographicCamera ref="camera" :position="[0, -20, 0]" :up="[0, 1, 0]" :far="200000">
          <TrackballControls :rotate-speed="0.01" :pan-speed="0.01"/>
        </OrthographicCamera>
        <Scene ref='scene'>
          <PointLight ref="light"/>
          <Group>
            <GLTFLoader
                url='/test-mesh/'
                @load="onCreation"
                enable-raycasting
                @click="onClick"
            >

            </GLTFLoader>
          </Group>
        </Scene>
      </Renderer>
    </div>
  </div>
</template>

<script>
import {Renderer} from "@janvorisek/drie";
import {Scene} from "@janvorisek/drie";
import {GLTFLoader} from "@janvorisek/drie"
import {OrthographicCamera} from "@janvorisek/drie"
import {TrackballControls} from "@janvorisek/drie"
import {PointLight} from "@janvorisek/drie"
import {defineComponent} from "vue";

export default defineComponent({
  name: "AddMesh",
  components: {
    Renderer,
    Scene,
    GLTFLoader,
    //TransformControls,
    OrthographicCamera,
    TrackballControls,
    PointLight,
  },
  props: {
    firstNode: {
      type: String,
      default: "node_name"
    }
  },
  data() {
  },
  mounted() {
    this.light = this.$refs.light.three
    this.scene = this.$refs.scene.three
    this.camera = this.$refs.camera.three
    this.renderer = this.$refs.renderer.three

    window['light'] = this.light
    window['intersects'] = this.intersects
    window['scene'] = this.scene
  },
  methods: {
    onCreation(group) {
      this.mesh = group.getObjectByName(this.firstNode)
      this.group = group
    },
    onClick(is) {
      console.log(is)
    },
    onMouseMove(is) {
      console.log(is); // Do whatever you need to with is
    },

    /**
     * is contains objects entered by the mouse
     */
    onMouseEnter(is) {
      console.log(is); // Do whatever you need to with is
    },

    /**
     * is contains objects left by the mouse
     */
    onMouseLeave(is) {
      console.log(is); // Do whatever you need to with is
    }
  },
  created() {
    window.setInterval(() => {
      this.light.position.set(
          this.camera.position.x - this.LIGHT_PARAMS.distCamX,
          this.camera.position.y - this.LIGHT_PARAMS.distCamX,
          this.camera.position.z - this.LIGHT_PARAMS.distCamX)
    }, 10);
  }
});

</script>

<style>
</style>
janvorisek commented 1 year ago

Can you provide screenshots of what doesn't work? I cannot run the code as I don't have your glTF file.

I only found a small issue with auto-resize="true" which should be :auto-resize="true" otherwise you are passing a string value 'true'. Also note autoResize is true by default.

LeoGrosjean commented 1 year ago

chrome-capture-2023-0-26 (2)

It occurs only when x=0, z=0 and y=any value

Edit : it occurs also when z=0 and x, y is any value I used many stl files from different designer

I will update to the new release, maybe its fixed on your side

LeoGrosjean commented 1 year ago

not fixed on 1.0.0-alpha-1.34

janvorisek commented 1 year ago

I'm sorry, but can you explain what are you doing to the model? I still don't understand what might be wrong

Are you rotating?

LeoGrosjean commented 1 year ago

I'm just left clicking on the canvas to rotate the camera !

with :up="[0, 1, 0]"

with :up="[0, 1, 1]"

with :up="[0, 0, 1]"

I'm still using GLTFLoader and the code shared previously

    "@formkit/vue": "^1.0.0-beta.14",
    "@janvorisek/drie": "^1.0.0-alpha-1.34",
    "@sipec/vue3-tags-input": "^3.0.4",
    "@tweakpane/plugin-essentials": "^0.1.7",
    "@vuelidate/core": "^2.0.0",
    "@vuelidate/validators": "^2.0.0",
    "axios": "^1.2.3",
    "core-js": "^3.8.3",
    "dat.gui": "^0.7.9",
    "three": "^0.148.0",
    "three-trackballcontrols": "^0.9.0",
    "troisjs": "^0.3.4",
    "tweakpane": "^3.1.2",
    "v-tweakpane": "^0.2.0",
    "vue": "^3.2.13",
    "vue-axios": "^3.5.2",
    "vue-router": "^4.1.6",
    "vue-select": "^4.0.0-beta.6",
    "vuetify": "^3.1.2"

The file I'm using : Torso_F.zip

I can share my screen with parsec if needed

janvorisek commented 1 year ago

I think you are running into the three controls limitations. You can't for example use OrbitControls and set camera position to [0,0,ANYTHING] when target is [0,0,0] - position can't be on line passing through target in the up direction.

I haven't got much experience with OrthographicCamera and TrackballControls. There may be a simialr issues with TrackballControls. Got a busy weak ahead. I cannot help you at the moment, but I will try to replicate the issue later this week and find solution/reason why it is not Drie issue :)

Note: I think :up="[0, 1, 1]" is incorrect value for three.js. The up vector should be normalized.

LeoGrosjean commented 1 year ago

No worries, it's not even an issue for my project ! I don't use it. I was just testing your release by using random parameters on props

I will tell the level of criticity on my next issue

Do you have a ticket template you want to adopt ?

LeoGrosjean commented 1 year ago

I loaded a new stl files much bigger than the previous one (x,y,z not size) and the disapear glitch came back!

I think I figure out what the issue was It was due to the camera position when moving the camera with the mouse !

I need to test if the camera position is correct, because if I load my mesh with the camera "inside" (but in the renderer/canvas, Im not inside) it glitches, maybe the camera position is not well updated ?

If I zoom in or zoom out, the camera.position don't get updated ! It only update if i rotate with left click (maybe another issue unrelated ?)

I will try to make a component that emulate it when I have time !

<template>
   ...
     <OrthographicCamera ref="camera" :position="[0, -20, 0]" :far="200000">
       <TrackballControls :rotate-speed="LIGHT_PARAMS.rotateSpeed" :pan-speed="LIGHT_PARAMS.panSpeed"/>
     </OrthographicCamera>
    ...
    <GLTFLoader
        v-bind:url='fileName_'
        @load="onCreation"
    >
   ...
</template>

<script>
  ...
  methods: {
    onCreation(group) {
      this.mesh = group.getObjectByName("myMesh")
      this.mesh.geometry.center()
      //this.camera.position.y = -this.mesh.geometry.boundingSphere.radius / 0.5
}
  ...
</script>

In this example:

  1. my camera init position is [0, -20, 0]
  2. Im loading a mesh bigger, my camera is inside the mesh
  3. vertices and faces dont render after -20, even if my camera position is far away from my mesh

Anyway, I fixed it by doing this (commented line upper):

this.camera.position.y = -this.mesh.geometry.boundingSphere.radius / 0.5

Or by editing manually camera.position to any value

I'm trying to figure out your code but I guess I should read typescript doc instaid

LeoGrosjean commented 1 year ago

So :up props was a bad lead, I'm just a dumbo that didn't get it should take a normalized vector!

janvorisek commented 1 year ago

Can you check again? There were some issues with props handling in cameras.

LeoGrosjean commented 1 year ago

I think my issue covers multiple ones :

In my scene I am dynamically adding Meshes with GltfLoader and then I cheat with

this.cameraBox = new THREE.Box3();
this.cameraBox.setFromObject(this.$refs.group.three)
let bsphere = this.cameraBox.getBoundingSphere(new THREE.Sphere(this.center));
this.$refs.camera.three.position.y = -bsphere.radius * 1.2
this.$refs.camera.three.position.x = -bsphere.radius * 1.2
this.$refs.camera.three.position.z = -bsphere.radius * 1.2

To set camera position with code (like this, I have no disappearing issues)

All my loaded meshes are added into this.$refs.group.three as descendants

When the camera position is not set with code (but by moving camera with click + mouse), meshes disapear like the camera is within (but its not)

Should I open another issue and close this one ?

LeoGrosjean commented 1 year ago

It occurs for example when :

<OrthographicCamera ref="camera" :far="200000" :position="[0,0,0]">

And then a mesh is added to scene and the mesh have a centroid of [0,0,0]

If I unzoom with my mouse, I wont be able to see the mesh

If I unzoom(changing camera position) from console/code I can see it