Commit f98b109d authored by anton's avatar anton
Browse files

Add basic BVH player component

parent 2ad1d132
Pipeline #76918 passed with stage
in 17 seconds
<template lang="pug">
div
// q-window-resize-observable(@resize="onWindowResize")
canvas(ref="three")
</template>
<script>
import path from 'path'
import { dom } from 'quasar'
const { height, width } = dom
const THREE = require('three')
global.THREE = THREE
require('three/examples/js/controls/OrbitControls')
require('three/examples/js/loaders/BVHLoader.js')
export default {
name: 'BVHPlayer',
props: {
bvhPath: String,
scale: Number,
loop: Boolean,
dump: Boolean,
compact: Boolean,
euler: Boolean,
backgroundColor: { type: String, default: '#000000' },
useOSC: { type: Boolean, default: true },
remoteAddress: String,
remotePort: Number
},
data () {
return {
skeletonName: undefined,
sender: undefined,
camera: undefined,
controls: undefined,
scene: undefined,
renderer: undefined,
stats: undefined,
clipAction: undefined,
mixers: [],
skeletons: [],
frames: [],
boneNames: []
}
},
async mounted () {
this.initThreeJS()
await this.loadBVH(this.bvhPath)
},
watch: {
async bvhPath (val) {
await this.loadBVH(val)
}
},
methods: {
onWindowResize (size) {
if (!this.camera || !this.renderer) return
this.camera.aspect = size.width / size.height
this.camera.updateProjectionMatrix()
this.renderer.setSize(size.width, size.height)
},
initThreeJS () {
// const w = window.innerWidth
// const h = window.innerHeight
const w = width(this.$el)
const h = height(this.$el)
this.clock = new THREE.Clock()
this.camera = new THREE.PerspectiveCamera(60, w / h, 1, 5000)
this.camera.position.set(0, 200, 400)
this.controls = new THREE.OrbitControls(this.camera, this.$refs.three)
this.controls.minDistance = 10
this.controls.maxDistance = 1000
this.scene = new THREE.Scene()
this.scene.background = new THREE.Color(this.backgroundColor)
this.scene.add(new THREE.GridHelper(400, 10))
// renderer
this.renderer = new THREE.WebGLRenderer({
canvas: this.$refs.three,
antialias: true
})
this.renderer.setPixelRatio(window.devicePixelRatio)
// this.renderer.setSize(this.$refs.three.offsetWidth, this.$refs.three.offsetHeight)
this.renderer.setSize(w, h)
this.animate()
},
async loadBVH (bvhPath) {
if (!this.bvhPath) return
const loader = new THREE.BVHLoader()
this.skeletonName = path.basename(bvhPath, path.extname(bvhPath))
loader.load(this.bvhPath, this.handleBVHLoaded)
},
handleBVHLoaded (result) {
const scaleVec = new THREE.Vector3(this.scale, this.scale, this.scale)
const skeletonHelper = new THREE.SkeletonHelper(result.skeleton.bones[0])
skeletonHelper.skeleton = result.skeleton // allow animation mixer to bind to SkeletonHelper directly
const boneContainer = new THREE.Group()
boneContainer.add(result.skeleton.bones[0])
boneContainer.scale.copy(scaleVec)
this.scene.add(skeletonHelper)
this.scene.add(boneContainer)
// play animation
const mixer = new THREE.AnimationMixer(skeletonHelper)
const clipAction = mixer.clipAction(result.clip)
.setLoop(this.loop ? THREE.LoopRepeat : THREE.LoopOnce)
.setEffectiveWeight(1.0)
clipAction.play()
mixer.update(0)
this.clipAction = clipAction
this.mixers.push(mixer)
this.skeletons.push(skeletonHelper)
},
async animate () {
requestAnimationFrame(this.animate)
const delta = this.clock.getDelta()
if (this.mixers.length > 0) {
this.mixers.forEach(mixer => {
mixer.update(delta)
})
}
this.renderer.render(this.scene, this.camera)
}
}
}
</script>
<style scoped lang="stylus">
canvas
margin: 0
padding: 0
width: 100vh
height: 100vh
</style>
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment