Created
April 1, 2012 06:40
-
-
Save 2no/2272034 to your computer and use it in GitHub Desktop.
BVH データ読み込み JS
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var aachan = new Bvh(); | |
var nocchi = new Bvh(); | |
var kashiyuka = new Bvh(); | |
aachan.load({ | |
src: "./bvh/aachan.bvh", | |
complete: function(xhr) { | |
console.log("あーちゃんの BVH データ読み込み完了"); | |
nocchi.load({ | |
src: "./bvh/nocchi.bvh", | |
complete: function(xhr) { | |
console.log("のっちの BVH データ読み込み完了"); | |
kashiyuka.load({ | |
src: "./bvh/kashiyuka.bvh", | |
complete: function(xhr) { | |
console.log("かしゆかの BVH データ読み込み完了"); | |
completeHandler(xhr); | |
}, | |
error: errorHandler | |
}); | |
}, | |
error: errorHandler | |
}); | |
}, | |
error: errorHandler | |
}); | |
function errorHandler(xhr) | |
{ | |
console.log('error'); | |
} | |
function completeHandler(xhr) | |
{ | |
console.log('complete'); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// https://github.com/perfume-dev/example-flash/tree/master/src/com/perfume/utils/bvh からの簡単移植 | |
var Bvh = window.Bvh || (function() { | |
function Bvh(str) | |
{ | |
this.init(str); | |
} | |
Bvh.prototype = { | |
_loop: false, | |
setLoop: function(b) | |
{ | |
this._loop = !!b; | |
return this; | |
}, | |
isLoop: function() { return this._loop; }, | |
_root: null, | |
setRoot: function(bone) | |
{ | |
if (bone instanceof Bvh.Bone) { | |
this._root = bone; | |
} | |
return this; | |
}, | |
_frames: [], | |
// TODO: 値をチェックするか | |
addFrame: function(frame) | |
{ | |
if (frame instanceof Array) { | |
this._frames.push(frame); | |
} | |
}, | |
setFrames: function(frames) | |
{ | |
this._frames = []; | |
for (var i = 0, length = frames.length; i < length; i++) { | |
this.addFrame(frames[i]); | |
} | |
return this; | |
}, | |
getFrames: function() { return this._frames; }, | |
_numFrames: 0, | |
getNumFrames: function() { return this._numFrames; }, | |
setNumFramesInternal: function(num) { | |
if (!isNaN(num)) { | |
this._numFrames = Number(num); | |
} | |
return this; | |
}, | |
_frameTime: 0, | |
getFrameTime: function() { return this._frameTime; }, | |
setFrameTimeInternal: function(num) | |
{ | |
if (!isNaN(num)) { | |
this._frameTime = Number(num); | |
} | |
return this; | |
}, | |
_bones: [], | |
getBones: function() { return this._bones; }, | |
init: function(str) | |
{ | |
this._bones = []; | |
this._frames = []; | |
this._root = null; | |
if (typeof str === "string") { | |
new Bvh.Parser(this, str); | |
} | |
return this; | |
}, | |
gotoFrame: function(frame) | |
{ | |
if (isNaN(frame)) { | |
return; | |
} | |
if (!this._loop) { | |
if (frame >= this._numFrames) { | |
frame = this._numFrames - 1; | |
} | |
} | |
else { | |
while (frame >= this._numFrames) { | |
frame -= this._numFrames; | |
} | |
} | |
frame = this._frames[frame]; | |
var numFrame = frame.length; | |
var count = 0; | |
var bone; | |
var channel; | |
for (var key in this._bones) { | |
bone = this._bones[key]; | |
channel = bone.getChannels(); | |
for (var i = 0, l = bone.getNumChannels(), v; i < l; i++) { | |
if (count < numFrame) { | |
v = frame[count++]; | |
switch (channel[i]) { | |
case "Xposition": | |
bone.setPositionX(v); | |
break; | |
case "Yposition": | |
bone.setPositionY(v); | |
break; | |
case "Zposition": | |
bone.setPositionZ(v); | |
break; | |
case "Xrotation": | |
bone.setRotationX(v); | |
break; | |
case "Yrotation": | |
bone.setRotationY(v); | |
break; | |
case "Zrotation": | |
bone.setRotationZ(v); | |
break; | |
} | |
} | |
} | |
} | |
return this; | |
}, | |
load: function(settings) | |
{ | |
if (typeof settings.src !== "string") { | |
return; | |
} | |
var xhr = null; | |
if (window.ActiveXObject) { | |
try { | |
xhr = new ActiveXObject("Msxml2.XMLHTTP"); | |
} | |
catch (e) { | |
try { | |
xhr = new ActiveXObject("Microsoft.XMLHTTP"); | |
} | |
catch (e) { | |
if (typeof settings.error === "function") { | |
settings.error.apply(this, [null]); | |
} | |
} | |
} | |
} | |
else if (window.XMLHttpRequest) { | |
xhr = new XMLHttpRequest(); | |
} | |
var self = this; | |
xhr.onreadystatechange = function() { | |
if (this.readyState === 4) { | |
if (this.status === 200) { | |
self.init(xhr.responseText); | |
if (typeof settings.complete === "function") { | |
settings.complete.apply(self, [xhr]); | |
} | |
} | |
else if (typeof settings.error === "function") { | |
settings.error.apply(self, [xhr]); | |
} | |
} | |
}; | |
xhr.open("GET", settings.src, true); | |
try { | |
xhr.send(); | |
} | |
catch (e) { | |
if (typeof settings.error === "function") { | |
settings.error.apply(this, [xhr]); | |
} | |
} | |
return this; | |
} | |
}; | |
return Bvh; | |
})(); | |
Bvh.Bone = window.Bvh.Bone || (function() { | |
function Bone(parent) | |
{ | |
this.setParent(parent); | |
} | |
Bone.prototype = { | |
_name: "", | |
_offsetX: 0, | |
_offsetY: 0, | |
_offsetZ: 0, | |
_endOffsetX: 0, | |
_endOffsetY: 0, | |
_endOffsetZ: 0, | |
_positionX: 0, | |
_positionY: 0, | |
_positionZ: 0, | |
_rotationX: 0, | |
_rotationY: 0, | |
_rotationZ: 0, | |
_numChannels: 0, | |
_channels: [], | |
_parent: null, | |
_children: [], | |
_end: false, | |
setName: function(name) | |
{ | |
if (typeof name === "string") { | |
this._name = name; | |
} | |
return this; | |
}, | |
getName: function() { return this._name; }, | |
setParent: function(bone) | |
{ | |
if (bone instanceof Bone || bone === null) { | |
this._parent = bone; | |
} | |
return this; | |
}, | |
getParent: function() | |
{ | |
return this._parent; | |
}, | |
addChild: function(child) | |
{ | |
if (child instanceof Bone) { | |
child.setParent(this); | |
this._children.push(child); | |
} | |
return this; | |
}, | |
getChild: function(index) { return this._children[index]; }, | |
getChildren: function() { return this._children; }, | |
setNumChannels: function(num) | |
{ | |
if (!isNaN(num)) { | |
this._numChannels = Number(num); | |
} | |
return this; | |
}, | |
getNumChannels: function() { return this._numChannels; }, | |
setChannels: function(channels) | |
{ | |
this._channels = channels instanceof Array ? channels : [channels]; | |
return this; | |
}, | |
getChannels: function() { return this._channels; }, | |
setOffset: function(offset) | |
{ | |
if (typeof offset.x !== 'undefined') { | |
this.setOffsetX(offset.x); | |
} | |
if (typeof offset.y !== 'undefined') { | |
this.setOffsetY(offset.y); | |
} | |
if (typeof offset.z !== 'undefined') { | |
this.setOffsetZ(offset.z); | |
} | |
return this; | |
}, | |
setOffsetX: function(x) | |
{ | |
if (!isNaN(x)) { | |
this._offsetX = Number(x); | |
} | |
return this; | |
}, | |
setOffsetY: function(y) | |
{ | |
if (!isNaN(y)) { | |
this._offsetY = Number(y); | |
} | |
return this; | |
}, | |
setOffsetZ: function(z) | |
{ | |
if (!isNaN(z)) { | |
this._offsetZ = Number(z); | |
} | |
return this; | |
}, | |
getOffset: function() | |
{ | |
return { | |
x: this._offsetX, | |
y: this._offsetY, | |
z: this._offsetZ | |
}; | |
}, | |
getOffsetX: function() { return this._offsetX; }, | |
getOffsetY: function() { return this._offsetY; }, | |
getOffsetZ: function() { return this._offsetZ; }, | |
setEndOffset: function(offset) | |
{ | |
if (typeof offset.x !== 'undefined') { | |
this.setEndOffsetX(offset.x); | |
} | |
if (typeof offset.y !== 'undefined') { | |
this.setEndOffsetY(offset.y); | |
} | |
if (typeof offset.z !== 'undefined') { | |
this.setEndOffsetZ(offset.z); | |
} | |
return this; | |
}, | |
setEndOffsetX: function(x) | |
{ | |
if (!isNaN(x)) { | |
this._endOffsetX = Number(x); | |
} | |
return this; | |
}, | |
setEndOffsetY: function(y) | |
{ | |
if (!isNaN(y)) { | |
this._endOffsetY = Number(y); | |
} | |
return this; | |
}, | |
setEndOffsetZ: function(z) | |
{ | |
if (!isNaN(z)) { | |
this._endOffsetZ = Number(z); | |
} | |
return this; | |
}, | |
getEndOffset: function() | |
{ | |
return { | |
x: this._endOffsetX, | |
y: this._endOffsetY, | |
z: this._endOffsetZ | |
}; | |
}, | |
getEndOffsetX: function() { return this._endOffsetX; }, | |
getEndOffsetY: function() { return this._endOffsetY; }, | |
getEndOffsetZ: function() { return this._endOffsetZ; }, | |
setPosition: function(position) | |
{ | |
if (typeof position.x !== "undefined") { | |
this.setPositionX(position.x); | |
} | |
if (typeof position.y !== "undefined") { | |
this.setPositionY(position.y); | |
} | |
if (typeof position.z !== "undefined") { | |
this.setPositionZ(position.z); | |
} | |
return this; | |
}, | |
setPositionX: function(x) | |
{ | |
if (!isNaN(x)) { | |
this._positionX = Number(x); | |
} | |
return this; | |
}, | |
setPositionY: function(y) | |
{ | |
if (!isNaN(y)) { | |
this._positionY = Number(y); | |
} | |
return this; | |
}, | |
setPositionZ: function(z) | |
{ | |
if (!isNaN(z)) { | |
this._positionZ = Number(z); | |
} | |
return this; | |
}, | |
getPosition: function() | |
{ | |
return { | |
x: this._positionX, | |
y: this._positionY, | |
z: this._positionZ | |
}; | |
}, | |
getPositionX: function() { return this._positionX; }, | |
getPositionY: function() { return this._positionY; }, | |
getPositionZ: function() { return this._positionZ; }, | |
setRotation: function(rotation) | |
{ | |
if (typeof rotation.x !== "undefined") { | |
this.setRotationX(rotation.x); | |
} | |
if (typeof rotation.y !== "undefined") { | |
this.setRotationY(rotation.y); | |
} | |
if (typeof rotation.z !== "undefined") { | |
this.setRotationZ(rotation.z); | |
} | |
return this; | |
}, | |
setRotationX: function(x) | |
{ | |
if (!isNaN(x)) { | |
this._rotationX = Number(x); | |
} | |
return this; | |
}, | |
setRotationY: function(y) | |
{ | |
if (!isNaN(y)) { | |
this._rotationY = Number(y); | |
} | |
return this; | |
}, | |
setRotationZ: function(z) | |
{ | |
if (!isNaN(z)) { | |
this._rotationZ = Number(z); | |
} | |
return this; | |
}, | |
getRotation: function() | |
{ | |
return { | |
x: this._rotationX, | |
y: this._rotationY, | |
z: this._rotationZ | |
}; | |
}, | |
getRotationX: function() { return this._rotationX; }, | |
getRotationY: function() { return this._rotationY; }, | |
getRotationZ: function() { return this._rotationZ; }, | |
isRoot: function() { return this._parent === null; }, | |
isEnd: function() { return this._end; }, | |
setEnd: function(b) | |
{ | |
this._end = !!b; | |
return this; | |
}, | |
init: function() | |
{ | |
this._parent = null; | |
this._channels = []; | |
this._children = []; | |
return this; | |
} | |
}; | |
return Bone; | |
})(); | |
Bvh.Parser = window.Bvh.Parser || (function() { | |
function Parser(bvh, str) | |
{ | |
var lineArr = str.split("\n"); | |
this._lines = []; | |
for (var key in lineArr) { | |
this._lines.push(new Bvh.Line(lineArr[key])); | |
} | |
this._currentLine = 1; | |
bvh.rootBone = this._parseBone(bvh.getBones()); | |
var length = this._lines.length; | |
for (var currentLine = 0; currentLine < length; currentLine++) { | |
if (this._lines[currentLine].getLineType() === "MOTION") { | |
break; | |
} | |
} | |
var numFrames = this._lines[++currentLine].getNumFrames(); | |
bvh.setNumFramesInternal(numFrames); | |
bvh.setFrameTimeInternal(this._lines[++currentLine].getFrameTime()); | |
var frames = []; | |
var length = this._lines.length; | |
for (var i = ++currentLine; i < length; i++) { | |
frames.push(this._lines[i].getFrames()); | |
} | |
bvh.setFrames(frames); | |
bvh.setNumFramesInternal(frames.length); | |
} | |
Parser.prototype = { | |
_lines: [], | |
_currentLine: 0, | |
_currentBone: null, | |
_parseBone: function(bones) | |
{ | |
var bone = new Bvh.Bone(this._currentBone); | |
bones.push(bone); | |
bone.setName(this._lines[this._currentLine++].getBoneName()); | |
bone.setOffset(this._lines[++this._currentLine].getOffset()); | |
var line = this._lines[++this._currentLine]; | |
bone.setNumChannels(line.getNumChannels()); | |
bone.setChannels(line.getChannelsProps()); | |
this._currentLine++; | |
while (this._currentLine < this._lines.length) { | |
switch (this._lines[this._currentLine].getLineType()) { | |
case "ROOT": | |
case "JOINT": | |
var child = this._parseBone(bones); | |
bone.addChild(child); | |
break; | |
case "End": | |
this._currentLine++; | |
this._currentLine++; | |
bone.setEnd(true); | |
var line = this._lines[this._currentLine]; | |
bone.setOffset(line.getOffset()); | |
this._currentLine++; | |
this._currentLine++; | |
case "}": | |
return bone; | |
} | |
this._currentLine++; | |
} | |
return bone; | |
} | |
}; | |
return Parser; | |
})(); | |
Bvh.Line = window.Bvh.Line || (function() { | |
function Line(str) | |
{ | |
this._parse(str); | |
} | |
Line.prototype = { | |
_lineType: "", | |
_boneType: "", | |
_boneName: "", | |
_offsetX: 0, | |
_offsetY: 0, | |
_offsetZ: 0, | |
_numChannels: 0, | |
_channelsProps: [], | |
_numFrames: 0, | |
_frameTime: 0, | |
_frames: [], | |
_parse: function(str) | |
{ | |
var lineStr = this._trim(str); | |
var words = lineStr.split(" "); | |
if (String(words[0]).indexOf("Frames:") !== -1) { | |
words[0] = "Frames:"; | |
words.push(lineStr.split(":")[1]); | |
} | |
if (words[0] === "Frame" && words.length === 2) { | |
words[1] = "Time:"; | |
words[2] = lineStr.split(":")[1]; | |
} | |
this._lineType = !isNaN(Number(words[0])) ? "FRAME" : words[0]; | |
switch (this._lineType) { | |
case "HIERARCHY": | |
break; | |
case "ROOT": | |
case "JOINT": | |
this._boneType = words[0] === "ROOT" ? "ROOT" : "JOINT"; | |
this._boneName = words[1]; | |
break; | |
case "OFFSET": | |
this._offsetX = Number(words[1]); | |
this._offsetY = Number(words[2]); | |
this._offsetZ = Number(words[3]); | |
break; | |
case "CHANNELS": | |
this._numChannels = Number(words[1]); | |
this._channelsProps = []; | |
for (var i = 0; i < this._numChannels; i++) { | |
this._channelsProps.push(words[i + 2]); | |
} | |
break; | |
case "Frames:": | |
this._numFrames = Number(words[1]); | |
break; | |
case "Frame": | |
this._frameTime = Number(words[2]); | |
break; | |
case "End": | |
case "{": | |
case "}": | |
case "MOTION": | |
break; | |
case "FRAME": | |
this._frames = []; | |
for (var key in words) { | |
this._addFrame(words[key]); | |
} | |
break; | |
} | |
}, | |
_trim: function(str) | |
{ | |
var startIndex = 0; | |
while (this._isWhitespace(str.charAt(startIndex))) { | |
++startIndex; | |
} | |
var endIndex = str.length - 1; | |
while (this._isWhitespace(str.charAt(endIndex))) { | |
--endIndex; | |
} | |
return endIndex >= startIndex | |
? str.slice(startIndex, endIndex + 1) : ""; | |
}, | |
_isWhitespace: function(character) | |
{ | |
return character.match(/\s|\t|\r|\n|\f/); | |
}, | |
_addFrame: function(frame) | |
{ | |
if (!isNaN(frame)) { | |
this._frames.push(Number(frame)); | |
} | |
}, | |
getFrames: function() { return this._frames; }, | |
getFrameTime: function() { return this._frameTime; }, | |
getNumFrames: function() { return this._numFrames; }, | |
getChannelsProps: function() { return this._channelsProps; }, | |
getNumChannels: function() { return this._numChannels; }, | |
getOffset: function() { | |
return { | |
x: this._offsetX, | |
y: this._offsetY, | |
z: this._offsetZ | |
} | |
}, | |
getOffsetZ: function() { return this._offsetZ; }, | |
getOffsetY: function() { return this._offsetY; }, | |
getOffsetX: function() { return this._offsetX; }, | |
getBoneName: function() { return this._boneName; }, | |
getBoneType: function() { return this._boneType; }, | |
getLineType: function() { return this._lineType; } | |
}; | |
return Line; | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment