| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| (function(modules) { |
| |
| var installedModules = {}; |
| |
| |
| function __webpack_require__(moduleId) { |
| |
| |
| if(installedModules[moduleId]) |
| return installedModules[moduleId].exports; |
| |
| |
| var module = installedModules[moduleId] = { |
| exports: {}, |
| id: moduleId, |
| loaded: false |
| }; |
| |
| |
| modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); |
| |
| |
| module.loaded = true; |
| |
| |
| return module.exports; |
| } |
| |
| |
| |
| __webpack_require__.m = modules; |
| |
| |
| __webpack_require__.c = installedModules; |
| |
| |
| __webpack_require__.p = ""; |
| |
| |
| return __webpack_require__(0); |
| }) |
| |
| ([ |
| |
| function(module, exports, __webpack_require__) { |
|
|
| BVHCharacter = __webpack_require__(1); |
| C3DCharacter = __webpack_require__(5); |
| MocapParsers = __webpack_require__(2); |
|
|
| }, |
| |
| function(module, exports, __webpack_require__) { |
|
|
| var parsers = __webpack_require__(2); |
| |
| var BVHCharacter = BVHCharacter || {}; |
| |
| |
| BVHCharacter = function(n, jm, bm, jg, bg) { |
| this.name = n; |
| |
| this.jointMaterial = jm; |
| this.boneMaterial = bm; |
| this.makeJointGeometryFCN = jg; |
| this.makeBoneGeometryFCN = bg; |
| |
| this.bvh = []; |
| this.skeleton = new THREE.Group(); |
| |
| this.skelScale = 1; |
| this.jointMeshes = []; |
| this.boneMeshes = []; |
| this.rootMeshes = []; |
| |
| this.originPosition = new THREE.Vector3(0, 0, 0); |
| |
| this.ready = false; |
| this.frameTime = 1 / 30; |
| this.frameCount = 0; |
| this.animIndex = 0; |
| this.animStartTimeRef = 0; |
| this.animOffset = 0; |
| this.playing = true; |
| |
| this.debug = true; |
| this.useWorker = true; |
| |
| this.webSocket = []; |
| this.streamProtocol = "BVHStream"; |
| this.keepStreamedFrames = true; |
| this.isStreaming = false; |
| |
| var self = this; |
| |
| |
| |
| this.log = function(m) { |
| if (self.debug) |
| console.log(self.name + ": " + m.toString()); |
| }; |
| |
| this.loadFromURL = function(url, callback) { |
| self.log("Loading the mocap file ..."); |
| |
| reader = new parsers.bvhParser(this.name + "READER"); |
| this.url = url; |
| reader.load(url, self.createSkel, self.fillFrames); |
| |
| this.callb = callback; |
| }; |
| |
| this.fillFrames = function() { |
| |
| self.ready = true; |
| self.playing = true; |
| |
| if (self.callb) |
| self.callb(); |
| } |
| |
| this.createSkel = function(data) { |
| self.bvh = data; |
| self.frameCount = data.frameCount; |
| self.frameTime = data.frameTime; |
| |
| self.log("Mocap file loaded."); |
| |
| self.log("Creating the WebGL Joints."); |
| self.buildSkelJoints(self.bvh.getSkeleton(), 0); |
| |
| self.log("Creating the WebGL Bones."); |
| self.buildSkelBones(self.jointMeshes[0]); |
| |
| self.skeleton.add(self.jointMeshes[0]); |
| self.setSkeletonScale(self.skelScale); |
| self.setSkelUp(); |
| }; |
| |
| |
| |
| this.onHeaderReceived = function(data) { |
| self.log("Loading the mocap header (skeleton) from the stream..."); |
| headerReader = new parsers.bvhStreamParser(); |
| headerReader.readHeader(data, self.createSkel); |
| |
| if (self.callb) |
| self.callb(); |
| |
| Pace.stop(); |
| } |
| |
| this.onDataChunckReceived = function(rawFrames) { |
| var aa = []; |
| |
| for (f = 1; f < rawFrames.length; f++) { |
| var parts = rawFrames[f].trim().split(" "); |
| for (var j = 0; j < parts.length; j++) |
| parts[j] = +parts[j]; |
| aa.push(parts); |
| } |
| diff = self.bvh.fillFrameArray(aa); |
| self.frameCount = self.bvh.frameArray.length; |
| |
| |
| if (!self.playing) { |
| self.animStartTimeRef = Date.now(); |
| |
| } |
| |
| |
| |
| |
| |
| |
| |
| self.fillFrames(); |
| Pace.stop(); |
| } |
| |
| this.loadFromStream = function(url, callback) { |
| self.log("Connecting to the stream server..."); |
| self.isStreaming = true; |
| this.callb = callback; |
| self.webSocket = new WebSocket(url); |
| |
| self.webSocket.onerror = function(event) { |
| self.log("Error connecting to the stream server " + event.origin); |
| }; |
| |
| self.webSocket.onopen = function(event) { |
| self.log("Connected to the stream server " + event.origin); |
| Pace.stop(); |
| }; |
| |
| self.webSocket.onmessage = function(event) { |
| |
| |
| |
| |
| |
| |
| |
| var messageLines = event.data.split('\n'); |
| |
| |
| |
| |
| if (messageLines.length < 1) |
| return; |
| |
| if (messageLines[0] == "$HEADER$") { |
| self.onHeaderReceived(event.data); |
| |
| } else if (messageLines[0].startsWith("$FRAMES$")) { |
| chunckID = parseInt(messageLines[0].split("$")[2]); |
| self.onDataChunckReceived(messageLines, chunckID); |
| } |
| }; |
| |
| }; |
| |
| this.requestFrames = function(i) { |
| self.webSocket.send("$GETFRAMES" + i + "$"); |
| } |
| |
| |
| |
| this.setOriginPosition = function(x, y, z) { |
| self.originPosition.set(x, y, z); |
| }; |
| |
| this.setSkeletonScale = function(s) { |
| self.rootMeshes.forEach(function(c) { |
| c.scale.set(s, s, s); |
| }); |
| self.jointMeshes[0].scale.set(s, s, s); |
| self.jointMeshes[0].position.multiplyScalar(s); |
| }; |
| |
| this.buildSkelJoints = function(joint, parent) { |
| var jointMesh = new THREE.Mesh(self.makeJointGeometryFCN(joint.name, self.skelScale), self.jointMaterial); |
| jointMesh.bvhIndex = joint.jointIndex; |
| jointMesh.offsetVec = new THREE.Vector3(joint.offset[0], joint.offset[1], joint.offset[2]); |
| jointMesh.name = joint.name; |
| jointMesh.jointparent = parent; |
| var a, b, c; |
| if (!joint.isEndSite()) { |
| a = joint.channelNames[joint.channelNames.length - 3][0]; |
| b = joint.channelNames[joint.channelNames.length - 2][0]; |
| c = joint.channelNames[joint.channelNames.length - 1][0]; |
| } |
| jointMesh.rotOrder = a + b + c; |
| self.jointMeshes.push(jointMesh); |
| |
| jointMesh.position.set(jointMesh.offsetVec.x, jointMesh.offsetVec.y, jointMesh.offsetVec.z); |
| |
| |
| |
| |
| |
| joint.children.forEach(function(child) { |
| jointMesh.add(self.buildSkelJoints(child, 1)); |
| }); |
| |
| return jointMesh; |
| }; |
| |
| this.buildSkelBones = function(rootJointMesh) { |
| rootJointMesh.traverse(function(childJointMesh) { |
| if (childJointMesh.parent !== null) |
| { |
| if (typeof childJointMesh.bvhIndex === "undefined") |
| return; |
| |
| |
| |
| h = math.abs(childJointMesh.offsetVec.length()); |
| var bgeometry = self.makeBoneGeometryFCN(childJointMesh.parent.name, childJointMesh.name, h, self.skelScale); |
| |
| |
| if (childJointMesh.offsetVec.y !== 0) |
| |
| bgeometry.translate(0, -h/2, 0); |
| else |
| bgeometry.translate(0, -h / 2, 0); |
| |
| |
| dx = Math.atan2(childJointMesh.offsetVec.z,childJointMesh.offsetVec.y); |
| dy = Math.atan2(childJointMesh.offsetVec.x,childJointMesh.offsetVec.z); |
| dz = Math.atan2(childJointMesh.offsetVec.x,childJointMesh.offsetVec.y); |
| |
| |
| osx = math.sign(childJointMesh.offsetVec.x) === 0 ? 0: math.sign(childJointMesh.offsetVec.x); |
| osy = math.sign(childJointMesh.offsetVec.y) === 0 ? 0: math.sign(childJointMesh.offsetVec.y); |
| osz = math.sign(childJointMesh.offsetVec.z) === 0 ? 0: math.sign(childJointMesh.offsetVec.z); |
| |
| osxy = math.sign(childJointMesh.offsetVec.x) === 0 ? 0: math.sign(childJointMesh.offsetVec.y); |
| osyx = math.sign(childJointMesh.offsetVec.y) === 0 ? 0: math.sign(childJointMesh.offsetVec.x); |
| osyz = math.sign(childJointMesh.offsetVec.y) === 0 ? 0: math.sign(childJointMesh.offsetVec.z); |
| oszy = math.sign(childJointMesh.offsetVec.z) === 0 ? 0: math.sign(childJointMesh.offsetVec.y); |
| |
| |
| if (osz <0) |
| bgeometry.rotateZ(1*(math.pi-dz)); |
| else if (osz === 0) |
| bgeometry.rotateZ(1*(math.pi-dz)); |
| |
| else if (osz > 0) |
| bgeometry.rotateZ(1*(2*math.pi-dz)); |
| |
| |
| if (oszy >0) |
| bgeometry.rotateX(-1 *(2*math.pi-dx)); |
| else if (childJointMesh.offsetVec.z === 0) |
| |
| console.log(); |
| else if (oszy < 0) |
| bgeometry.rotateX(-1*(2*math.pi-dx)); |
| |
| |
| |
| |
| |
| var boneMesh = new THREE.Mesh(bgeometry, self.boneMaterial); |
| |
| boneMesh.joint = childJointMesh.parent; |
| boneMesh.name = childJointMesh.parent.name + " > " + childJointMesh.name; |
| |
| childJointMesh.parent.add(boneMesh); |
| self.boneMeshes.push(boneMesh); |
| } |
| }); |
| }; |
| |
| this.animFrame = function(frame) { |
| var torad = Math.PI / 180; |
| |
| if (frame >= self.frameCount) { |
| self.playing = false; |
| return; |
| } |
| |
| |
| this.jointMeshes[0].traverse(function(joint) { |
| |
| if (typeof joint.bvhIndex === "undefined") { |
| return; |
| } |
| |
| |
| var bj = self.bvh.jointArray[joint.bvhIndex]; |
| var offsetVec = joint.offsetVec; |
| |
| var thisEuler = []; |
| |
| |
| thisEuler = new THREE.Euler( |
| (bj.channels[frame][bj.rotationIndex.x] * torad), |
| (bj.channels[frame][bj.rotationIndex.y] * torad), |
| (bj.channels[frame][bj.rotationIndex.z] * torad), joint.rotOrder); |
| |
| |
| joint.localRotMat = new THREE.Matrix4(); |
| joint.localRotMat.makeRotationFromEuler(thisEuler); |
| joint.rotation.setFromRotationMatrix(joint.localRotMat); |
| |
| if (joint.jointparent !== 0) { |
| |
| } else { |
| joint.position.set( |
| bj.channels[frame][bj.positionIndex.x] * self.skelScale + self.originPosition.x, |
| bj.channels[frame][bj.positionIndex.y] * self.skelScale + self.originPosition.y, |
| bj.channels[frame][bj.positionIndex.z] * self.skelScale + self.originPosition.z); |
| } |
| }); |
| |
| if (self.isStreaming) { |
| self.bvh.consumeFrames(frame); |
| self.frameCount = self.bvh.frameArray.length; |
| |
| if (self.frameCount <= 0) |
| self.playing = false; |
| |
| self.animOffset = 0; |
| self.animStartTimeRef = Date.now(); |
| } |
| }; |
| |
| this.setSkelUp = function() { |
| this.jointMeshes[0].traverse(function(joint) { |
| if (typeof joint.bvhIndex === "undefined") |
| return; |
| |
| var bj = self.bvh.jointArray[joint.bvhIndex]; |
| |
| var offsetVec = joint.offsetVec; |
| var torad = Math.PI / 180; |
| var thisEuler = []; |
| |
| thisEuler = new THREE.Euler(0, 0, 0, joint.rotOrder); |
| |
| joint.localRotMat = new THREE.Matrix4(); |
| joint.localRotMat.makeRotationFromEuler(thisEuler); |
| joint.rotation.setFromRotationMatrix(joint.localRotMat); |
| |
| if (joint.jointparent !== 0) { |
| |
| } else { |
| joint.position.set(self.originPosition.x, self.originPosition.y, self.originPosition.z); |
| } |
| }); |
| }; |
| }; |
| |
| |
| module.exports = BVHCharacter; |
|
|
| }, |
| |
| function(module, exports, __webpack_require__) { |
|
|
| module.exports ={ |
| bvhParser: __webpack_require__(3), |
| bvhStreamParser: __webpack_require__(4) |
| }; |
|
|
| }, |
| |
| function(module, exports) { |
|
|
| |
| var BVHReader = function () { |
| this.load = function (url, callbackHeader, callbackFrameArray) { |
| $.get(url, function (str) { |
| |
| var dataReturn = parse(str); |
| |
| |
| var jointStack = dataReturn[0]; |
| var jointMap = dataReturn[1]; |
| var jointArray = dataReturn[2]; |
| var connectivityMatrix = dataReturn[3] |
| _bvh = new BVHReader.BVH.Skeleton(jointStack[0], jointMap, jointArray, dataReturn[3], dataReturn[4], dataReturn[5], []); |
| |
| if (callbackHeader) |
| callbackHeader(_bvh,'BVH'); |
| console.log("Blah"); |
| _bvh.fillFrameArray(dataReturn[6]); |
| |
| if (callbackFrameArray) |
| callbackFrameArray(); |
| |
| }); |
| }; |
| |
| function parse(str) { |
| var lines = str.split('\n'); |
| var jointStack = []; |
| var jointMap = {}; |
| var jointArray = []; |
| var connectivityMatrix = []; |
| var frameCount, frameTime, frameArray = []; |
| var i = 0; |
| |
| for (i = 1; i < lines.length; i++) { |
| if (!parseLine(lines[i], jointStack, jointMap, jointArray, connectivityMatrix)) { |
| break; |
| } |
| } |
| |
| for (i = i + 1; i < lines.length; i++) { |
| var line = lines[i].trim(); |
| |
| if (line === "") |
| break; |
| if (line.indexOf("Frames") === 0) { |
| frameCount = +(line.split(/\b/)[2]); |
| } else if (line.indexOf("Frame Time") === 0) { |
| frameTime = +( line.substr(line.indexOf(":") + 1).trim() ) |
| } else { |
| var parts = line.split(" "); |
| for (var j = 0; j < parts.length; j++) |
| parts[j] = +parts[j]; |
| frameArray.push(parts); |
| } |
| } |
| |
| |
| return [jointStack, jointMap, jointArray, connectivityMatrix, frameCount, frameTime, frameArray]; |
| } |
| |
| |
| var parseLine = function (line, jointStack, jointMap, jointArray, connectivityMatrix) { |
| line = line.trim(); |
| if (line.indexOf("ROOT") > -1 || line.indexOf("JOINT") > -1 || line.indexOf("End") > -1) { |
| var parts = line.split(" "); |
| var title = parts[1]; |
| parts[1] = parts[1] + "-" + jointArray.length; |
| var joint = new BVHReader.BVH.Joint(parts[1]); |
| joint.title = title; |
| jointStack.push(joint); |
| |
| joint.jointIndex = Object.keys(jointMap).length; |
| jointMap[parts[1]] = joint; |
| jointArray.push(joint); |
| |
| if( line.indexOf("End") != 0 ){ |
| if (jointArray.length == 1) { |
| joint.channelOffset = 0; |
| } else { |
| joint.channelOffset = jointArray[jointArray.length - 2].channelOffset + jointArray[jointArray.length - 2].channelLength; |
| } |
| }else{ |
| |
| joint.channelLength = 0; |
| joint.channelOffset = jointArray[jointArray.length - 2].channelOffset + jointArray[jointArray.length - 2].channelLength; |
| } |
| |
| } else if (line.indexOf("{") === 0) { |
| |
| } else if (line.indexOf("OFFSET") === 0) { |
| var parts = line.split(" "); |
| jointStack[jointStack.length - 1]["offset"] = parts.slice(1); |
| for(x in jointStack[jointStack.length - 1]["offset"]){ |
| jointStack[jointStack.length - 1]["offset"][x] = +jointStack[jointStack.length - 1]["offset"][x] |
| } |
| } else if (line.indexOf("CHANNELS") === 0) { |
| var parts = line.split(" "); |
| jointStack[jointStack.length - 1].setChannelNames(parts.slice(2)); |
| jointStack[jointStack.length - 1]["channelLength"] = +parts[1]; |
| } else if (line.indexOf("}") === 0) { |
| if (jointStack.length > 1) { |
| child = jointStack.pop(); |
| jointStack[jointStack.length - 1].children.push(child); |
| child.parent = jointStack[jointStack.length - 1]; |
| |
| connectivityMatrix.push([child.parent, child]) |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| } |
| } else if (line.indexOf("MOTION") == 0) { |
| return false; |
| } |
| |
| return true; |
| }; |
| }; |
| |
| BVHReader.BVH = BVHReader.BVH || {}; |
| |
| BVHReader.BVH.Joint = function (name, index) { |
| |
| this.name = name; |
| this.children = []; |
| this.isEndSite = function () { |
| return this.children.length == 0; |
| }; |
| this.rotationIndex = {}; |
| this.positionIndex = {}; |
| |
| this.getChannels = function () { |
| var allChannels = []; |
| for (i = 0; i < this.skeleton.frameArray.length; i++) { |
| allChannels.push(this.getChannelsAt(i)); |
| } |
| return allChannels; |
| }; |
| this.getChannelsAt = function (frameNum) { |
| var channelsAtFrame = this.skeleton.frameArray[frameNum]; |
| return channelsAtFrame.slice(this.channelOffset, this.channelOffset + this.channelLength); |
| }; |
| |
| this.setChannelNames = function (nameArr){ |
| this.channelNames = nameArr; |
| for(i in this.channelNames){ |
| var name = this.channelNames[i]; |
| switch(name){ |
| case "Xposition": this.positionIndex.x = i; break; |
| case "Yposition": this.positionIndex.y = i; break; |
| case "Zposition": this.positionIndex.z = i; break; |
| |
| case "Xrotation": this.rotationIndex.x = i; break; |
| case "Yrotation": this.rotationIndex.y = i; break; |
| case "Zrotation": this.rotationIndex.z = i; break; |
| } |
| } |
| } |
| }; |
| |
| BVHReader.BVH.Skeleton = function (root, map, arr, connectivityMatrix, frameCount, frameTime, frameArray) { |
| thisSkeleton = this; |
| this.root = root; |
| this.jointMap = map; |
| this.jointArray = arr; |
| this.connectivityMatrix = connectivityMatrix; |
| this.frameCount = frameCount; |
| this.frameTime = frameTime; |
| this.frameArray = frameArray; |
| |
| for (i = 0; i < this.jointArray.length; i++) { |
| this.jointArray[i].skeleton = thisSkeleton; |
| } |
| |
| |
| |
| this.fillFrameArray = function (fa) { |
| this.frameArray = fa; |
| this.frameCount = fa.length; |
| |
| for(j=0; j < this.jointArray.length; j++){ |
| var joint = this.jointArray[j]; |
| updateWithPositions(joint); |
| } |
| } |
| |
| this.getChannels = function () { |
| return frameArray; |
| }; |
| this.getChannelsAt = function (frameNum) { |
| |
| |
| return frameArray[frameNum]; |
| }; |
| this.getFrameRate = function () { |
| return frameCount / frameTime; |
| }; |
| this.getSkeleton = function () { |
| return root; |
| }; |
| |
| this.getHeadJoint = function () { |
| |
| return jointMap["Head"]; |
| }; |
| this.getPositionsAt = function (frameNum) { |
| |
| |
| posFrame = []; |
| |
| for (j=0;j<this.jointArray.length;j++) { |
| posFrame.push(this.jointArray[j].positions[frameNum]); |
| } |
| |
| posFrame = posFrame.map(function(d) { |
| return { |
| x : d[0], |
| y : d[1], |
| z : d[2], |
| }; |
| }); |
| |
| return posFrame; |
| }; |
| this.getTPose = function () { |
| |
| console.log("Not yet implemented"); |
| }; |
| |
| function updatePositions(rootOffset, removeRoot, orientation, camera) { |
| |
| |
| for(j=0; j < this.jointArray.length; j++){ |
| var joint = this.jointArray[j]; |
| updateWithPositions(joint); |
| } |
| } |
| |
| function updateWithPositions(joint){ |
| var channelNames = joint.channelNames; |
| joint.channels = joint.getChannels(); |
| joint.rotations = []; |
| joint.positions = []; |
| joint.rotmat = []; |
| for(i in joint.channels){ |
| var channel = joint.channels[i]; |
| var xpos = channel[joint.positionIndex.x] || 0, |
| ypos = channel[joint.positionIndex.y] || 0, |
| zpos = channel[joint.positionIndex.z] || 0, |
| xangle = deg2rad(channel[joint.rotationIndex.x] || 0), |
| yangle = deg2rad(channel[joint.rotationIndex.y] || 0), |
| zangle= deg2rad(channel[joint.rotationIndex.z] || 0); |
| |
| |
| |
| var posMatrix = [xpos, ypos, zpos]; |
| |
| if(joint.parent){ |
| posMatrix = [0,0,0]; |
| |
| |
| |
| |
| |
| |
| |
| |
| if (i==0 && (joint.name == "Spine" || joint.name == "L_Femur")) { |
| |
| |
| |
| |
| |
| |
| |
| |
| } |
| |
| }else{ |
| |
| |
| |
| joint.positions[i] = posMatrix; |
| |
| } |
| } |
| } |
| |
| function deg2rad(deg){ |
| return deg * (Math.PI/180); |
| } |
| |
| |
| function getRotationMatrix(alpha, beta, gamma) { |
| |
| |
| var ca = Math.cos(alpha), |
| sa = Math.sin(alpha), |
| |
| cb = Math.cos(beta), |
| sb = Math.sin(beta), |
| |
| cg = Math.cos(gamma), |
| sg = Math.sin(gamma), |
| |
| Rx = [[1, 0, 0], [0, ca, -sa], [0, sa, ca]]; |
| |
| Ry = [[cb, 0, sb], [0, 1, 0], [-sb, 0, cb]]; |
| |
| Rz = [[cg, -sg, 0], [sg, cg, 0], [0, 0, 1]]; |
| |
| |
| |
| |
| var Rzm = math.matrix(Rz); |
| var Rym = math.matrix(Ry); |
| var Rxm = math.matrix(Rx); |
| |
| var tt = math.multiply(Rzm, Rym); |
| |
| return math.multiply(tt,Rxm).toArray(); |
| |
| |
| |
| } |
| |
| function getRotationMatrix1 (xangle, yangle, zangle, order){ |
| var c1 = Math.cos(xangle), |
| c2 = Math.cos(yangle), |
| c3 = Math.cos(zangle), |
| s1 = Math.sin(xangle), |
| s2 = Math.sin(yangle), |
| s3 = Math.sin(zangle); |
| |
| if(order === undefined || order.trim() === ""){ |
| order = "zxy"; |
| } |
| |
| var rotMat = [ |
| [1,0,0], |
| [0,1,0], |
| [0,0,1] |
| ]; |
| |
| switch(order){ |
| case "___zxy": |
| rotMat = [ |
| [c2*c3-s1*s2*s3, c2*s3+s1*s2*c3, -s2*c1], |
| [-c1*s3, c1*c3, s1], |
| [s2*c3+c2*s1*s3, s2*s3-c2*s1*c3, c2*c1] |
| ]; |
| break; |
| default: |
| for (o in order){ |
| var axis = order[o]; |
| var t; |
| switch(axis){ |
| case "x": |
| t = [ |
| [1, 0, 0], |
| [0, c1, s1], |
| [0, -s1, c1], |
| ] |
| break; |
| case "y": |
| t = [ |
| [c2,0,-s2], |
| [0,1,0], |
| [s2,0,c2] |
| ] |
| break; |
| case "z": |
| t = [[c3,s3,0],[-s3,c3,0],[0,0,1]] |
| break; |
| } |
| |
| rotMat = matrixMultiply(t, rotMat) |
| } |
| } |
| |
| return rotMat; |
| } |
| }; |
| |
| function vectorAdd(a, b){ |
| return math.add(math.matrix(a), math.matrix(b)).toArray(); |
| } |
| |
| function matrixMultiply(m1, m2) { |
| var a = math.matrix(m1); |
| var b = math.matrix(m2); |
| return math.multiply(a, b).toArray(); |
| } |
| |
| |
| module.exports = BVHReader; |
|
|
| }, |
| |
| function(module, exports) { |
|
|
| |
| |
| |
| |
| var BVHStreamParser = function () { |
| this.readHeader = function (str, callback) { |
| var dataReturn = parseHeader(str); |
| var jointStack = dataReturn[0]; |
| var jointMap = dataReturn[1]; |
| var jointArray = dataReturn[2]; |
| var connectivityMatrix = dataReturn[3] |
| if (callback) |
| callback(new BVHStreamParser.BVH.Skeleton(jointStack[0], jointMap, jointArray, dataReturn[3], 0, dataReturn[5], dataReturn[6]),'BVH'); |
| }; |
| |
| function parseHeader(str) { |
| var lines = str.split('\n'); |
| var jointStack = []; |
| var jointMap = {}; |
| var jointArray = []; |
| var connectivityMatrix = []; |
| var frameCount, frameTime, frameArray = []; |
| var i = 0; |
| |
| for (i = 2; i < lines.length; i++) { |
| if (!parseLine(lines[i], jointStack, jointMap, jointArray, connectivityMatrix)) { |
| break; |
| } |
| } |
| |
| for (i = i + 1; i < lines.length; i++) { |
| var line = lines[i].trim(); |
| |
| if (line === "") |
| break; |
| if (line.indexOf("Frames") === 0) { |
| frameCount = +(line.split(/\b/)[2]); |
| } else if (line.indexOf("Frame Time") === 0) { |
| frameTime = +( line.substr(line.indexOf(":") + 1).trim() ) |
| } else { |
| var parts = line.split(" "); |
| for (var j = 0; j < parts.length; j++) |
| parts[j] = +parts[j]; |
| frameArray.push(parts); |
| } |
| } |
| |
| |
| return [jointStack, jointMap, jointArray, connectivityMatrix, frameCount, frameTime, frameArray]; |
| } |
| |
| |
| var parseLine = function (line, jointStack, jointMap, jointArray, connectivityMatrix) { |
| line = line.trim(); |
| if (line.indexOf("ROOT") > -1 || line.indexOf("JOINT") > -1 || line.indexOf("End") > -1) { |
| var parts = line.split(" "); |
| var title = parts[1]; |
| parts[1] = parts[1] + "-" + jointArray.length; |
| var joint = new BVHStreamParser.BVH.Joint(parts[1]); |
| joint.title = title; |
| jointStack.push(joint); |
| |
| joint.jointIndex = Object.keys(jointMap).length; |
| jointMap[parts[1]] = joint; |
| jointArray.push(joint); |
| |
| if( line.indexOf("End") != 0 ){ |
| if (jointArray.length == 1) { |
| joint.channelOffset = 0; |
| } else { |
| joint.channelOffset = jointArray[jointArray.length - 2].channelOffset + jointArray[jointArray.length - 2].channelLength; |
| } |
| }else{ |
| |
| joint.channelLength = 0; |
| joint.channelOffset = jointArray[jointArray.length - 2].channelOffset + jointArray[jointArray.length - 2].channelLength; |
| } |
| |
| } else if (line.indexOf("{") === 0) { |
| |
| } else if (line.indexOf("OFFSET") === 0) { |
| var parts = line.split(" "); |
| jointStack[jointStack.length - 1]["offset"] = parts.slice(1); |
| for(x in jointStack[jointStack.length - 1]["offset"]){ |
| jointStack[jointStack.length - 1]["offset"][x] = +jointStack[jointStack.length - 1]["offset"][x] |
| } |
| } else if (line.indexOf("CHANNELS") === 0) { |
| var parts = line.split(" "); |
| jointStack[jointStack.length - 1].setChannelNames(parts.slice(2)); |
| jointStack[jointStack.length - 1]["channelLength"] = +parts[1]; |
| } else if (line.indexOf("}") === 0) { |
| if (jointStack.length > 1) { |
| child = jointStack.pop(); |
| jointStack[jointStack.length - 1].children.push(child); |
| child.parent = jointStack[jointStack.length - 1]; |
| |
| connectivityMatrix.push([child.parent, child]) |
| } |
| } else if (line.indexOf("MOTION") == 0) { |
| return false; |
| } |
| |
| return true; |
| }; |
| }; |
| |
| BVHStreamParser.BVH = BVHStreamParser.BVH || {}; |
| |
| BVHStreamParser.BVH.Joint = function (name, index) { |
| |
| this.name = name; |
| this.children = []; |
| this.isEndSite = function () { |
| return this.children.length == 0; |
| }; |
| this.rotationIndex = {}; |
| this.positionIndex = {}; |
| |
| this.getChannels = function () { |
| var allChannels = []; |
| for (i = 0; i < this.skeleton.frameArray.length; i++) { |
| allChannels.push(this.getChannelsAt(i)); |
| } |
| return allChannels; |
| }; |
| this.getChannelsAt = function (frameNum) { |
| var channelsAtFrame = this.skeleton.frameArray[frameNum]; |
| return channelsAtFrame.slice(this.channelOffset, this.channelOffset + this.channelLength); |
| }; |
| |
| this.setChannelNames = function (nameArr){ |
| this.channelNames = nameArr; |
| for(i in this.channelNames){ |
| var name = this.channelNames[i]; |
| switch(name){ |
| case "Xposition": this.positionIndex.x = i; break; |
| case "Yposition": this.positionIndex.y = i; break; |
| case "Zposition": this.positionIndex.z = i; break; |
| |
| case "Xrotation": this.rotationIndex.x = i; break; |
| case "Yrotation": this.rotationIndex.y = i; break; |
| case "Zrotation": this.rotationIndex.z = i; break; |
| } |
| } |
| } |
| }; |
| |
| BVHStreamParser.BVH.Skeleton = function (root, map, arr, connectivityMatrix, frameCount, frameTime, frameArray) { |
| thisSkeleton = this; |
| this.root = root; |
| this.jointMap = map; |
| this.jointArray = arr; |
| this.connectivityMatrix = connectivityMatrix; |
| this.frameCount = frameCount; |
| this.frameTime = frameTime; |
| this.frameArray = frameArray; |
| this.bufferSize = 500; |
| |
| for (i = 0; i < this.jointArray.length; i++) { |
| this.jointArray[i].skeleton = thisSkeleton; |
| } |
| |
| this.fillFrameArray = function (fa) { |
| this.frameArray.push.apply(this.frameArray,fa); |
| |
| |
| diff = this.frameArray.length - this.bufferSize; |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| if (diff > 0) |
| addedCount = this.frameCount; |
| else |
| addedCount = fa.length; |
| |
| for(j=0; j < this.jointArray.length; j++){ |
| var joint = this.jointArray[j]; |
| updateWithPositionsSinceLast(joint, addedCount); |
| } |
| |
| return diff; |
| } |
| |
| this.consumeFrames = function (index) { |
| for (i=0;i<=index;i++) { |
| this.frameArray.shift(); |
| for (j=0;j<this.jointArray.length;j++) |
| this.jointArray[j].channels.shift(); |
| } |
| this.frameCount = this.frameArray.length; |
| } |
| |
| this.getChannels = function () { |
| return frameArray; |
| }; |
| this.getChannelsAt = function (frameNum) { |
| |
| |
| return frameArray[frameNum]; |
| }; |
| this.getFrameRate = function () { |
| return frameCount / frameTime; |
| }; |
| this.getSkeleton = function () { |
| return root; |
| }; |
| |
| this.getHeadJoint = function () { |
| |
| return jointMap["Head"]; |
| }; |
| this.getPositionsAt = function (frameNum) { |
| |
| |
| posFrame = []; |
| |
| for (j=0;j<this.jointArray.length;j++) { |
| posFrame.push(this.jointArray[j].positions[frameNum]); |
| } |
| |
| posFrame = posFrame.map(function(d) { |
| return { |
| x : d[0], |
| y : d[1], |
| z : d[2], |
| }; |
| }); |
| |
| return posFrame; |
| }; |
| this.getTPose = function () { |
| |
| console.log("Not yet implemented"); |
| }; |
| |
| function updatePositions(rootOffset, removeRoot, orientation, camera) { |
| |
| |
| for(j=0; j < this.jointArray.length; j++){ |
| var joint = this.jointArray[j]; |
| updateWithPositions(joint); |
| } |
| } |
| |
| function updateWithPositions(joint){ |
| var channelNames = joint.channelNames; |
| joint.channels = joint.getChannels(); |
| joint.rotations = []; |
| joint.positions = []; |
| joint.rotmat = []; |
| for(i in joint.channels){ |
| var channel = joint.channels[i]; |
| var xpos = channel[joint.positionIndex.x] || 0, |
| ypos = channel[joint.positionIndex.y] || 0, |
| zpos = channel[joint.positionIndex.z] || 0; |
| |
| |
| |
| |
| var posMatrix = [xpos, ypos, zpos]; |
| |
| if(!joint.parent){ |
| |
| joint.positions[i] = posMatrix; |
| |
| } |
| } |
| } |
| |
| function updateWithPositionsSinceLast(joint, addedCount){ |
| var channelNames = joint.channelNames; |
| joint.channels = joint.getChannels(); |
| joint.rotations = []; |
| joint.positions = []; |
| joint.rotmat = []; |
| for(i=joint.channels.length - addedCount;i < joint.channels.length; i++){ |
| var channel = joint.channels[i]; |
| var xpos = channel[joint.positionIndex.x] || 0, |
| ypos = channel[joint.positionIndex.y] || 0, |
| zpos = channel[joint.positionIndex.z] || 0; |
| |
| |
| |
| |
| var posMatrix = [xpos, ypos, zpos]; |
| |
| if(!joint.parent){ |
| |
| joint.positions[i] = posMatrix; |
| |
| } |
| } |
| } |
| |
| function deg2rad(deg){ |
| return deg * (Math.PI/180); |
| } |
| }; |
| |
| module.exports = BVHStreamParser; |
|
|
| }, |
| |
| function(module, exports) { |
|
|
| var C3DCharacter = C3DCharacter || {}; |
| |
| C3DCharacter = function(n, jm, jg){ |
| this.name = n; |
| |
| this.markerMaterial = jm; |
| this.makeMarkerGeometryFCN = jg; |
| |
| this.originPosition = new THREE.Vector3(0,0,0); |
| |
| this.markerdata = []; |
| this.ready = false; |
| this.scale = 0.5; |
| this.markerMeshes = []; |
| |
| this.frameTime = 1/30; |
| this.frameCount = 0; |
| |
| this.animIndex = 0; |
| this.animStartTimeRef = 0; |
| this.animOffset = 0; |
| this.playing = true; |
| |
| this.debug = true; |
| |
| var self = this; |
| |
| |
| |
| this.log = function(m) { |
| if (self.debug) |
| console.log(self.name + ": "+m.toString()); |
| }; |
| |
| this.loadFromURL = function(url, callback) { |
| self.log("Loading the mocap file ..."); |
| Pace.start(); |
| url2 = "../" + url; |
| self.url = url; |
|
|
| Papa.parse(url2, { |
| worker: true, |
| delimiter: ",", |
| dynamicTyping: true, |
| download: true, |
| header: false, |
| complete: function(results) { |
| self.processData(results); |
| if (callback) |
| callback(); |
| } |
| }); |
| }; |
|
|
| this.loadFromBuffer = function(data, callback) { |
| self.log("Loading the mocap from buffer..."); |
| Pace.start(); |
| var preData = data.split('\n'); |
| preData = preData.map(function(d,i){ |
| var cols = d.split(','); |
| var floats = cols; |
| |
| if (i!=0) { |
| floats = cols.map(function(p, j){ |
| return parseFloat(p); |
| }); |
| } |
| |
| return floats; |
| }); |
| preData.pop(); |
| |
| this.processData({data: preData}); |
| if (callback) |
| callback(); |
| } |
| |
| this.processData = function(results) { |
| |
| |
|
|
| for (i=0;i<results.data[0].length-3;i+=3) { |
| var markerMesh = new THREE.Mesh(self.makeMarkerGeometryFCN(results.data[0][i], self.scale), self.markerMaterial); |
| markerMesh.markerIndex = i; |
| markerMesh.name = results.data[0][i]; |
| scene.add(markerMesh); |
| self.markerMeshes.push(markerMesh); |
| } |
| |
| self.markerNames = results.data[0]; |
|
|
| for (f=1;f<results.data.length;f++) { |
| self.markerdata[f-1] = []; |
| for (m=0;m<results.data[f].length-3;m+=3) { |
| marker = {}; |
| marker.x = results.data[f][m]; |
| marker.y = results.data[f][m+1]; |
| marker.z = results.data[f][m+2]; |
| marker.name = self.markerNames[m]; |
|
|
| self.markerdata[f-1].push(marker); |
| } |
| } |
|
|
| self.frameCount = self.markerdata.length; |
| self.log("Done parsing!"); |
| self.ready = true; |
| } |
|
|
| this.setOriginPosition = function (x, y, z) { |
| self.originPosition.set(x,y,z); |
| }; |
| |
| this.setSkeletonScale = function(s) { |
| self.rootMeshes.forEach(function (c) { |
| c.scale.set(s,s,s); |
| }); |
| self.jointMeshes[0].scale.set(s,s,s); |
| self.jointMeshes[0].position.multiplyScalar(s); |
| }; |
| |
| |
| this.animFrame = function (frame) { |
| for (m=0;m<self.markerMeshes.length; m++) { |
| self.markerMeshes[m].position.set( |
| self.markerdata[frame][m].x * self.scale + self.originPosition.x, |
| self.markerdata[frame][m].y * self.scale + self.originPosition.y, |
| self.markerdata[frame][m].z * self.scale + self.originPosition.z); |
| } |
| }; |
| }; |
| |
| module.exports = C3DCharacter; |
|
|
| } |
| ]); |
| |
|
|