模型对象缓存0-1-版

<template>
<div></div>
</template>
<script>
import * as THREE from 'three'
import Dexie from 'dexie'
import Worker from './model.worker.js'
export default {
  name: 'ModelStorage',
  inject: {
    Action: {
      name: 'Action',
      default () {
        return null
      }
    }
  },
  data () {
    var db = new Dexie('ModelDatabase')
    db.version(1).stores({
      //  创建表
      modelList: '++id,name,model,edition,animation'
    })
    return {
      db,
      animationAction: [],
      animationMixer: null,
      models: {},
      meshName: 'HDM_01_04_trunk'
    }
  },
  props: {
    edition: Number
  },
  created () {},
  beforeDestroy () {
    this.animationAction = null
    this.animationMixer = null
  },
  methods: {
    /** 线程 保存
     *@param obj: obj保存的对象
     */
    WorkerSave (obj) {
      const worker = new Worker()
      worker.postMessage(obj)
      worker.onmessage = e => {
        console.log('Received message ' + e.data)
        worker.terminate()
      }
    },
    /** 该方法用于读取数据库模型文件
     *@param modelName: 数据库存储的模型 名字
     **/
    async readModel (modelName) {
      let dbmodel = null
      await this.db.modelList
        .where('name')
        .equalsIgnoreCase(modelName)
        .first()
        .then(res => {
          if (res) {
            if (res.edition !== this.edition) {
              this.db.modelList.delete(res.id)
              dbmodel = null
            } else {
              //  返回模型
              dbmodel = res
            }
          } else {
            //  加载模型文件
            dbmodel = null
          }
        })
        .catch(err => {
          console.log('数据读取失败', err)
          dbmodel = null
        })

      return dbmodel
    },
    /** 加载 three 对象
     * @param resModel: 需要解析的模型
     */
    loaderModel (res) {
      const loader = new THREE.ObjectLoader() // 加载 three 对象

      return new Promise(resolve => {
        loader.parse(res.model, model => {
          this.meshVm.curObj = model
          console.log('model', model)
          if (model) {
            this.$bus.$emit('isLoad')
          }
          this.getModel(model.children)
          this.$bus.$on('changeColor', obj => {
            if (obj === true) {
              this.meshName = 'HDM_01_04_seat_driver'
            } else {
              this.meshName = 'HDM_01_04_trunk'
            }
            this.getModel(model.children)
          })

          this.$bus.$on('emitColor', obj => {
            if (this.models) {
              this.models.material.color.r = obj.r
              this.models.material.color.g = obj.g
              this.models.material.color.b = obj.b
            }
          })
          // 加载动画
          this.loaderAnimations(res.animation, model)
          resolve(model)
        })
      })
    },
    getModel (model) {
      model.forEach(items => {
        //  HDM_01_04_trunk
        if (items.name === this.meshName) {
          this.models = items
          return items
        } else {
          return this.getModel(items.children)
        }
      })
    },
    /** 加载数据库动画动画
     * @param animations: 动画数据
     * @param obj: 模型数据
     */
    loaderAnimations (animations, obj) {
      if (!this.animationAction) {
        this.animationAction = []
      }
      if (animations && animations.length) {
        animations = new THREE.AnimationLoader().parse(animations) // 转换  AnimationClip 对象
        const mixer = new THREE.AnimationMixer(obj)
        for (let i = 0; i < animations.length; i++) {
          //   animations[i]   THREE.AnimationClip.parse(animations[i])
          const animation = animations[i]
          //  There's .3333 seconds junk at the tail of the Monster animation that
          //  keeps it from looping cleanly. Clip it at 3 seconds
          // animation.duration = 3;
          //  保存动画 ACtion
          this.animationAction.push(mixer.clipAction(animation))
        }
        this.animationMixer = mixer
      }
    },
    /** 加载模型动画
     * @param animations: 动画数据
     * @param obj: 模型数据
     */
    animation (animations, obj) {
      if (!this.animationAction) {
        this.animationAction = []
      }
      this.needsUpdate = true
      const animationList = [] //  保存 动画数据
      if (animations && animations.length) {
        const mixer = new THREE.AnimationMixer(obj)
        for (let i = 0; i < animations.length; i++) {
          const animation = animations[i]
          //  There's .3333 seconds junk at the tail of the Monster animation that
          //  keeps it from looping cleanly. Clip it at 3 seconds
          //  animation.duration = 3;
          //  保存动画 ACtion
          this.animationAction.push(mixer.clipAction(animation))
          animationList.push(THREE.AnimationClip.toJSON(animation))
        }
        this.animationMixer = mixer
      }
      return animationList
    },
    /** 初始化函数
     * @param fileName : 文件名称
     */
    initial (fileName) {
      //  查看数据有没有 模型
      // 读取数据库
      this.loadFile()
      try {
        new Promise(resolve => {
          this.readModel(fileName).then(async dbmodel => {
            if (dbmodel) {
            //  解析模型  console.log('解析模型')
              await this.loaderModel(dbmodel).then((newmodel) => {
                this.process()
                resolve(newmodel)
              })
            } else {
            //  重新加载模型  console.log('重新加载模型')
              await this.requireModel().then((newmodel) => {
                this.process()
                resolve(newmodel)
              })
            }
          })
        }).then((model) => {
          this.$emit('getModels', model)
          //  把动画对象 传给 ACtion
          if (this.Action) {
            this.Action.animationAction = this.animationAction
            this.Action.mixer = this.animationMixer
          }
        })
      } catch (err) {
        this.requireModel().then((newmodel) => {
          this.$emit('getModels', newmodel)
        })
      }
    },
    /**
     * 加载 文件model
     */
    requireModel () {},
    /**
     * 请求文件
     */
    loadFile () {
      const loader = new THREE.FileLoader()
      // 加载一个文本文件,并把结果输出到控制台上
      loader.load(
        // resource URL
        this.gltfUrl,

        // onLoad回调
        function (data) {
          // output the text to the console
          console.log(data)
        },

        // onProgress回调
        function (xhr) {
          console.log((xhr.loaded / xhr.total * 100) + '% loaded')
        },

        // onError回调
        // eslint-disable-next-line handle-callback-err
        function (err) {
          console.error('An error happened')
        }
      )
    }
  }
}
</script>

<style></style>

posted @ 2023-02-02 11:01  过好每一天2022  阅读(15)  评论(0)    收藏  举报