UNPKG

pbrtools

Version:
134 lines (122 loc) 5.58 kB
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');