pbrtools
Version:
laya pbr tools
134 lines (122 loc) • 5.58 kB
text/typescript
import { BufferReader } from './buffer';
import * as fs from 'fs';
import * as path from 'path';
class KeyFramesContent{
startTime=0;
duration=0;
//interpolationData
data:Float32Array;
dData:Float32Array;
nextData:Float32Array;
}
class AnimationNodeContent{
name:string;
parentIndex=-1;
parent:AnimationNodeContent;
keyframeWidth=0;
lerpType=0;
interpolationMethod:Function[];
childs:AnimationNodeContent[];
keyFrame:KeyFramesContent[];
playTime=0;
extenData:ArrayBuffer;
dataOffset=0;
}
class AnimationContent{
nodes:AnimationNodeContent[];
name:string;
playTime=0;
bone3DMap:any;
totalKeyframesLength =0;
}
class aniLoader{
buffR:BufferReader;
aniClsName:string;
_publicExtData:ArrayBuffer;
_anis:AnimationContent[];
_aniMap={};
static interpolation = [];
load(src:string){
var fbuff = fs.readFileSync(src);
this.buffR =new BufferReader();
this.buffR.init(fbuff.buffer);
var reader = this.buffR;
var version = reader.readString();
this.aniClsName = reader.readString();
var strList = reader.readString().split('\n'); //所有骨骼名称
var aniCount = reader.readU8(); //有多少套动画
var publicDataPos = reader.readU32();//公用数据POS
var publicExtDataPos = reader.readU32();//公用扩展数据POS
var publicData:ArrayBuffer;
if(publicDataPos>0)
publicData = fbuff.buffer.slice(publicDataPos, publicExtDataPos);
if(publicExtDataPos>0)
this._publicExtData = fbuff.buffer.slice(publicExtDataPos, fbuff.buffer.byteLength);
var publicRead = new BufferReader(); publicRead.init(publicData);
var useParent = !!this.buffR.readU8(); //问题:难道还能不用parent?
this._anis = [];
this._anis.length = aniCount;
for( var i=0; i<aniCount; i++){
var ani = this._anis[i] = new AnimationContent();
ani.nodes = [];
var name = ani.name = strList[this.buffR.readU16()];
this._aniMap[name]=i;
ani.bone3DMap = {};
ani.playTime = this.buffR.readF32();
var boneCount = ani.nodes.length = this.buffR.readU8(); //本动画的骨骼数目。本动画?
ani.totalKeyframesLength = 0;
for( var j=0; j<boneCount; j++){
var node = ani.nodes[j] = new AnimationNodeContent();
node.childs = [];
var nameIndex = this.buffR.readU16();
if(nameIndex>0){
node.name = strList[nameIndex];
ani.bone3DMap[node.name] = j;
}
node.keyFrame = [];
node.parentIndex = this.buffR.readU16();
node.parentIndex==-1?node.parent=null:ani.nodes[node.parentIndex];
node.lerpType = this.buffR.readU8();//该节点插值类型:0为不插值,1为逐节点插值,2为私有插值
var keyframeParamsOffset = this.buffR.readU32();//相对于数据扩展区的偏移地址
publicRead.readpos = keyframeParamsOffset;//移到数据区
var keyframeDataCount = node.keyframeWidth = publicRead.readU16();//keyframe数据宽度
ani.totalKeyframesLength += keyframeDataCount;
if(node.lerpType===0 || node.lerpType===1){
node.interpolationMethod = new Array(keyframeDataCount);
node.interpolationMethod.forEach((v,ii)=>{
node.interpolationMethod[ii]=aniLoader.interpolation[publicRead.readU8()];
})
}
if(node.parent!=null)
node.parent.childs.push(node);
var privateDataLen = this.buffR.readU16();//
if(privateDataLen>0){
node.extenData = this.buffR.buff.slice(this.buffR.readpos,this.buffR.readpos+privateDataLen);//
this.buffR.readpos+=privateDataLen;
}
var keyframeCount = this.buffR.readU16();
node.keyFrame.length=keyframeCount;
var startTime = 0;
for(var k=0, n=keyframeCount; k<n; k++){
var keyFrame = node.keyFrame[k] = new KeyFramesContent();
keyFrame.duration = this.buffR.readF32();
keyFrame.startTime = startTime;
if(node.lerpType===2){
throw 'not imp';
}
keyFrame.data = new Float32Array(keyframeDataCount);
keyFrame.dData = new Float32Array(keyframeDataCount);
keyFrame.nextData = new Float32Array(keyframeDataCount);
for( var l=0; l<keyframeDataCount; l++){
keyFrame.data[l] = this.buffR.readF32();
}
startTime += keyFrame.duration;
console.log('starttm='+startTime);
}
node.playTime = ani.playTime;//节点总时间可能比总时长大,次处修正
//_calculateKeyFrame(node, keyframeCount, keyframeDataCount);
}
}
}
}
new aniLoader().load('E:/layaair/layaair/publish/LayaAirPublish/samples/as/3d/bin/h5/threeDimen/models/dude/dude.lsani');