div style text align center CANVAS WIDTH 800 HEIGHT 800 ID mycanvas style border 1pt dotted blue Canvas tag not supported CANVAS input type file onchange loadbvh event div https notebook xbdev net index php page vector script src https notebook xbdev net var scripts vector0 9 js script script function assert v details if v true throw Assert thrown details helpers mat4 prototype getTranslate function return new vec3 this m 12 this m 13 this m 14 mat4 prototype getAxis function return new vec3 this m 0 this m 1 this m 2 new vec3 this m 4 this m 5 this m 6 new vec3 this m 8 this m 9 this m 10 var bvh new function parse a BVH file this readBvh function lines read model structure if lines shift trim toUpperCase HIERARCHY throw HIERARCHY expected var list var root readNode lines lines shift trim list read motion data if lines shift trim toUpperCase MOTION throw MOTION expected var tokens lines shift trim split s number of frames var numFrames parseInt tokens 1 if isNaN numFrames throw Failed to read number of frames frame time tokens lines shift trim split s var frameTime parseFloat tokens 2 if isNaN frameTime throw Failed to read frame time read frame data line by line for var i 0 i numFrames i tokens lines shift trim split s readFrameData tokens i frameTime root list return root Recursively parses the HIERACHY section of the BVH file function readNode lines firstline list var node name type frames list push node parse node tpye and name var tokens firstline trim split s if tokens 0 toUpperCase END tokens 1 toUpperCase SITE node type ENDSITE node name ENDSITE bvh end sites have no name else node name tokens 1 node type tokens 0 toUpperCase opening bracket if lines shift trim throw Expected opening after type name parse OFFSET tokens lines shift trim split s if tokens 0 toUpperCase OFFSET throw Expected OFFSET but got tokens 0 if tokens length 4 throw OFFSET Invalid number of values var offset x parseFloat tokens 1 y parseFloat tokens 2 z parseFloat tokens 3 if isNaN offset x isNaN offset y isNaN offset z throw OFFSET Invalid values node offset offset parse CHANNELS definitions if node type ENDSITE tokens lines shift trim split s if tokens 0 toUpperCase CHANNELS throw Expected CHANNELS definition var numChannels parseInt tokens 1 node channels tokens splice 2 numChannels node children read children while true var line lines shift trim if line return node else node children push readNode lines line list Recursively reads data from a single frame into the bone hierarchy The bone hierarchy has to be structured in the same order as the BVH file keyframe data is stored in bone frames function readFrameData data frameTime bone if bone type ENDSITE end sites have no motion data return add keyframe var keyframe time frameTime order krot x 0 y 0 z 0 kpos x 0 y 0 z 0 bone frames push keyframe parse values for each channel in node for var i 0 i bone channels length i switch bone channels i case Xposition let xp parseFloat data shift trim keyframe position x xp keyframe kpos x xp break case Yposition let yp parseFloat data shift trim keyframe kpos y yp break case Zposition let zp parseFloat data shift trim keyframe kpos z zp break case Xrotation let xang parseFloat data shift trim Math PI 180 keyframe krot x xang keyframe order X break case Yrotation let yang parseFloat data shift trim Math PI 180 keyframe krot y yang keyframe order Y break case Zrotation let zang parseFloat data shift trim Math PI 180 keyframe krot z zang keyframe order Z break default throw invalid channel type break parse child nodes for var i 0 i bone children length i readFrameData data frameTime bone children i var bvhroot 0 function readTextFile file var rawFile new XMLHttpRequest rawFile open GET file rawFile onreadystatechange function if rawFile readyState 4 if rawFile status 200 rawFile status 0 let allText rawFile responseText alert allText console log allText bvhroot bvh readBvh allText split n maxFrames bvhroot frames length 1 console log bvhroot rawFile send null function loadbvh event let selectedFile event target files 0 let reader new FileReader let result document getElementById result reader onload function event let allText event target result footpath bvhroot bvh readBvh allText split n maxFrames bvhroot frames length 1 console log bvhroot reader readAsText selectedFile readTextFile https notebook xbdev net var resources walk bvh var footpath var fnum 50 var maxFrames 0 let base x 400 y 600 z 0 let build true function drawJoint parent parentMatrix for let i 0 i parent children length i if parent children i type ENDSITE continue let coffset parent children i offset let cframe parent children i frames fnum let matTrans mat4 translate new vec3 cframe kpos x coffset x cframe kpos y coffset y cframe kpos z coffset z let matRotX mat4 fromAxisAngle new vec3 1 0 0 cframe krot x let matRotY mat4 fromAxisAngle new vec3 0 1 0 cframe krot y let matRotZ mat4 fromAxisAngle new vec3 0 0 1 cframe krot z assert cframe order ZXY order was cframe order let matRot mat4 mul mat4 mul matRotZ matRotX matRotY let matChild mat4 mul mat4 mul parentMatrix matTrans matRot let v0 parentMatrix getTranslate let v1 matChild getTranslate drawline v0 x base x v0 y base y v1 x base x v1 y base y console log parent children i name if build parent children i name lFoot footpath push x v1 x base x y v1 y base y if parent children i name lFoot let ts new vec3 matChild m 12 matChild m 13 matChild m 14 drawaxis ts matChild drawJoint parent children i matChild function drawline x0 y0 x1 y1 ctx beginPath ctx moveTo x0 y0 ctx lineTo x1 y1 ctx lineWidth 5 ctx setLineDash 5 ctx strokeStyle ff0000 ctx fillStyle red ctx strokeStyle red ctx stroke function drawline2 x0 y0 x1 y1 col green ctx beginPath ctx moveTo x0 y0 ctx lineTo x1 y1 ctx lineWidth 1 ctx setLineDash 4 2 ctx fillStyle FF0000 ctx strokeStyle col green 002200 ctx stroke function drawaxis t m let v m getAxis let s 20 drawline2 t x base x t y base y t x v 0 x s base x t y v 0 y s base y red drawline2 t x base x t y base y t x v 1 x s base x t y v 1 y s base y green drawline2 t x base x t y base y t x v 2 x s base x t y v 2 y s base y blue function drawloop if bvhroot 0 return ctx document getElementById mycanvas getContext 2d ctx clearRect 0 0 800 800 clear canvas let roffset bvhroot offset let rframe bvhroot frames fnum let rootTrans mat4 translate new vec3 rframe kpos x roffset x rframe kpos y roffset y rframe kpos z roffset z let matRotX mat4 fromAxisAngle new vec3 1 0 0 rframe krot x let matRotY mat4 fromAxisAngle new vec3 0 1 0 rframe krot y let matRotZ mat4 fromAxisAngle new vec3 0 0 1 rframe krot z assert rframe order ZYX order was rframe order let matRot mat4 mul mat4 mul matRotZ matRotY matRotX let matRoot mat4 mul rootTrans matRot let mat mat4 mul mat4 scale new vec3 1 1 1 mat4 mul mat4 fromAxisAngle new vec3 0 1 0 1 54 matRoot let mat mat4 identity drawJoint bvhroot mat for let i 0 i footpath length 1 i drawline2 footpath i x footpath i y footpath i 1 x footpath i 1 y intervalId setInterval function try if footpath length 0 build true for fnum 0 fnum maxFrames fnum drawloop build false fnum 1 fnum 1 if fnum maxFrames fnum 0 drawloop catch e clearInterval intervalId console log exception console log e e 30 setTimeout fnum 117 build true drawloop 1000 script
rawFile open GET file rawFile onreadystatechange function if rawFile readyState 4 if rawFile status 200 rawFile status 0 let allText rawFile responseText alert allText console log allText bvhroot bvh readBvh allText split n maxFrames bvhroot frames length 1 console log bvhroot rawFile send null function loadbvh event let selectedFile event target files 0 let reader new FileReader let result document getElementById result reader onload function event let allText event target result footpath bvhroot bvh readBvh allText split n maxFrames bvhroot frames length 1 console log bvhroot reader readAsText selectedFile readTextFile https notebook xbdev net var resources walk bvh var footpath var fnum 50 var maxFrames 0 let base x 400 y 600 z 0 let build true function drawJoint parent parentMatrix for let i 0 i parent children length i if parent children i type ENDSITE continue let coffset parent children i offset let cframe parent children i frames fnum let matTrans mat4 translate new vec3 cframe kpos x coffset x cframe kpos y coffset y cframe kpos z coffset z let matRotX mat4 fromAxisAngle new vec3 1 0 0 cframe krot x let matRotY mat4 fromAxisAngle new vec3 0 1 0 cframe krot y let matRotZ mat4 fromAxisAngle new vec3 0 0 1 cframe krot z assert cframe order ZXY order was cframe order let matRot mat4 mul mat4 mul matRotZ matRotX matRotY let matChild mat4 mul mat4 mul parentMatrix matTrans matRot let v0 parentMatrix getTranslate let v1 matChild getTranslate drawline v0 x base x v0 y base y v1 x base x v1 y base y console log parent children i name if build parent children i name lFoot footpath push x v1 x base x y v1 y base y if parent children i name lFoot let ts new vec3 matChild m 12 matChild m 13 matChild m 14 drawaxis ts matChild drawJoint parent children i matChild function drawline x0 y0 x1 y1 ctx beginPath ctx moveTo x0 y0 ctx lineTo x1 y1 ctx lineWidth 5 ctx setLineDash 5 ctx strokeStyle ff0000 ctx fillStyle red ctx strokeStyle red ctx stroke function drawline2 x0 y0 x1 y1 col green ctx beginPath ctx moveTo x0 y0 ctx lineTo x1 y1 ctx lineWidth 1 ctx setLineDash 4 2 ctx fillStyle FF0000 ctx strokeStyle col green 002200 ctx stroke function drawaxis t m let v m getAxis let s 20 drawline2 t x base x t y base y t x v 0 x s base x t y v 0 y s base y red drawline2 t x base x t y base y t x v 1 x s base x t y v 1 y s base y green drawline2 t x base x t y base y t x v 2 x s base x t y v 2 y s base y blue function drawloop if bvhroot 0 return ctx document getElementById mycanvas getContext 2d ctx clearRect 0 0 800 800 clear canvas let roffset bvhroot offset let rframe bvhroot frames fnum let rootTrans mat4 translate new vec3 rframe kpos x roffset x rframe kpos y roffset y rframe kpos z roffset z let matRotX mat4 fromAxisAngle new vec3 1 0 0 rframe krot x let matRotY mat4 fromAxisAngle new vec3 0 1 0 rframe krot y let matRotZ mat4 fromAxisAngle new vec3 0 0 1 rframe krot z assert rframe order ZYX order was rframe order let matRot mat4 mul mat4 mul matRotZ matRotY matRotX let matRoot mat4 mul rootTrans matRot let mat mat4 mul mat4 scale new vec3 1 1 1 mat4 mul mat4 fromAxisAngle new vec3 0 1 0 1 54 matRoot let mat mat4 identity drawJoint bvhroot mat for let i 0 i footpath length 1 i drawline2 footpath i x footpath i y footpath i 1 x footpath i 1 y intervalId setInterval function try if footpath length 0 build true for fnum 0 fnum maxFrames fnum drawloop build false fnum 1 fnum 1 if fnum maxFrames fnum 0 drawloop catch e clearInterval intervalId console log exception console log e e 30 setTimeout fnum 117 build true drawloop 1000 script