Beg-in / vue-babylonjs

A ready-to-go 3d environment for Vue.js using Babylon.js
https://vuebabylonjs.com
MIT License
463 stars 73 forks source link

Loading multiple 3d models to the canvas and assign clickable events #62

Open aj-fernando opened 4 years ago

aj-fernando commented 4 years ago

I want to load a 3d venue (i.e a large stadium or conference hall) in to my canvas and then depending on the information provided by the backend (grpc + golang server), I would like to dynamically load 3d speaker models in their respective positions. The number of speakers can range from 10 to 2500. I'm able to load multiple speaker models using a nested v-for in Asset. I would like to know the the most optimized way to do this when it comes to rendering large number of 3d models.

      <Asset :src="this.venuePath"></Asset>

      <Asset v-for="array in arrayInfos" :key="array.arrayId">
        <Asset
          v-for="deviceId in array.deviceIdsList"
          :key="deviceId"
          :src="this.speakerPath"
          :scaling="this.speakerScaling"
          :position="deviceInfoForDeviceId(deviceId).position"
        ></Asset>
      </Asset>

But the most concerning problem is to add a clickable event to these loaded 3d models. I would like to be able to click any of the rendered speaker models and display corresponding speaker details on a table next to the 3d view. Appreciate your help. I thought perhaps BABYLON.GUI.MeshButton3D is the way but I cannot figure out how to use it with this library.

Note: I'm using Vue with Typescript in Class based components. So my classes looks like this.

<script lang="ts">
import { Component, Vue, Prop } from 'vue-property-decorator';
import { Getter } from 'vuex-class';
import { IArrayInfo } from '../store/array/types';
import { IDeviceInfo } from '../store/device/types';

import vb from 'vue-babylonjs';
import { Vector3 } from 'vue-babylonjs/classes';
Vue.use(vb);

@Component
export default class View3D extends Vue {
  private venuePath: string;
  private venuePosition: Vector3;
  private speakerPath: string;
  private speakerScaling: Vector3;

  @Getter('arrayInfos', { namespace: 'arrayState' })
  private arrayInfos!: IArrayInfo[];
  @Getter('deviceInfos', { namespace: 'deviceState' })
  private deviceInfos!: IDeviceInfo[];

  constructor() {
    super();
    this.venuePath = `${process.env.BASE_URL}msg_seating_13K.obj`;
    this.venuePosition = [0, 0, 0];
    this.speakerPath = `${process.env.BASE_URL}speakermodule.obj`;
    this.speakerScaling = [0.01, 0.01, 0.01];
  }

  private deviceInfoForDeviceId(deviceId: string): IDeviceInfo {
    for (const deviceInfo of this.deviceInfos) {
      if (deviceInfo.deviceId === deviceId) {
        return deviceInfo;
      }
    }
    return {} as IDeviceInfo;
  }
}
</script>

Thank you:)

BrainBacon commented 4 years ago

Sorry I missed this. I noticed your comment in #63, were you able to figure this out then?