
- 2024年10月
- 2021年5月
- 2020年8月
- 2020年6月
- 2020年5月
- 2019年1月
- 2018年8月
- 2018年6月
- 2018年5月
- 2018年3月
- 2018年1月
- 2017年12月
- 2017年11月
- 2017年10月
- 2017年9月
- 2017年8月
- 2017年7月
- 2017年6月
- 2016年11月
- 2013年9月
- 2013年8月
- 2013年6月
- 2013年5月
- 2013年4月
- 2013年3月
- 2013年2月
- 2013年1月
- 2012年12月
- 2012年11月
- 2012年10月
- 2012年9月
- 2012年6月
- 2012年5月
- 2012年4月
- 2012年2月
- 2011年7月
- 2011年5月
- 2011年4月
- 2011年2月
- 2010年12月
- 2010年11月
- 2010年10月
- 2010年9月
- 2010年8月
- 2010年7月
- 2010年6月
- 2010年5月
- 2010年4月
- 2010年3月
- 2010年2月
- 2010年1月
- 2009年12月
- 2008年2月
- 2008年1月
- 2007年12月
- 2007年5月
- 2007年4月
- 2007年3月
- 2007年2月
JavaScriptでテキストデータの読み込み / magicien
JavaScriptでXファイルを読み込んだときに使った方法。バイナリデータの読み込みについて書きかけの状態ですが、今回はテキストデータの読み込みについて。
実行速度よりも実装のしやすさを優先するなら、Ginがおすすめ。
実際の使い方としてはこんな感じ。
var xfileGrammar; function start() { xfileGrammar = new Gin.Grammar({ XFile: / XFileHeader:header (XObjectLong)* /, XFileHeader: / 'xof ':xof VersionNumber FormatType:showValue FloatSize:showValue /, VersionNumber: / <\d\d>:showValue <\d\d>:showValue /, FormatType: / 'txt ' | 'bin ' | 'tzip' | 'bzip' /, FloatSize: / '0064' | '0032' /, XObject: / Template | Animation | AnimationKey | AnimationOptions | AnimationSet | AnimTicksPerSecond | Boolean | Boolean2d | ColorRGB | ColorRGBA | Coords2d | DeclData | EffectDWorld | EffectFloats | EffectInstance | EffectParamDWorld | EffectParamFloats | EffectString | FaceAdjacency | FloatKeys | Frame | FrameTransformMatrix | FVFData | Header | IndexedColor | Material | Matrix4x4 | MeshFaceWraps | MeshFace | MeshMaterialList | MeshNormals | MeshTextureCoords | MeshVertexColors | Mesh | Patch | PatchMesh9 | PatchMesh | PMAttributeRange | PMInfo | PMVSplitRecord | SkinWeights | TextureFilename | TimedFloatKeys | Vector | VertexDuplicationIndices | VertexElement | XSkinMeshHeader /, XObjectLong: / Template | AnimationLong | AnimationKeyLong | AnimationOptionsLong | AnimationSetLong | AnimTicksPerSecondLong | BooleanLong | Boolean2dLong | ColorRGBLong | ColorRGBALong | Coords2dLong | DeclDataLong | EffectDWorldLong | EffectFloatsLong | EffectInstanceLong | EffectParamDWorldLong | EffectParamFloatsLong | EffectStringLong | FaceAdjacencyLong | FloatKeysLong | FrameLong | FrameTransformMatrixLong | FVFDataLong | HeaderLong | IndexedColorLong | MaterialLong | Matrix4x4Long | MeshFaceWrapsLong | MeshFaceLong | MeshMaterialListLong | MeshNormalsLong | MeshTextureCoordsLong | MeshVertexColorsLong | MeshLong | PatchLong | PatchMeshLong | PatchMesh9Long | PMAttributeRangeLong | PMInfoLong | PMVSplitRecordLong | SkinWeightsLong | TextureFilenameLong | TimedFloatKeysLong | VectorLong | VertexDuplicationIndicesLong | VertexElementLong | XSkinMeshHeaderLong /, XString: / <[0-9A-Za-z]*> /, Identifier: / XString /, Name: / XString /, UUID: / '<' (<[0-9A-Za-z]|->)* '>' /, Member: / ('array' TemplateType Name '[' ($INT | XString) ']') | (TemplateType Name) /, TemplateType: / XString /, XArray: / '[' $INT ']' /, XObjectTemplate: / Identifier:identifier Name:name '{' UUID ('[...]' | ('[' Name ']') | (Member ';'))* '}' /, Template: / 'template':template Name '{' UUID ('[...]' | ('[' Name ']') | (Member ';'))* '}' /, IntValue: / $INT ';' ::first /, IntArray: / $INT (',' $INT)* (',')? ';' /, FloatValue: / $REAL ';' ::first /, FloatArray: / $REAL (',' $REAL)* (',')? ';' /, Header: / HeaderLong | (HeaderValue ';') /, HeaderLong: / 'Header' (Name)? '{' (UUID)? HeaderValue '}' /, HeaderValue: / IntValue:major IntValue:minor IntValue:flags /, Animation: / AnimationLong | ( AnimationValue ';') /, AnimationLong: / 'Animation' (Name)? '{' (UUID)? AnimationValue '}' /, AnimationValue: / $ANY /, AnimationKey: / AnimationKeyLong | ( AnimationKeyValue ';') /, AnimationKeyLong: / 'AnimationKey' (Name)? '{' (UUID)? AnimationKeyValue '}' /, AnimationKeyValue: / $ANY /, AnimationOptions: / AnimationOptionsLong | ( AnimationOptionsValue ';') /, AnimationOptionsLong: / 'AnimationOptions' (Name)? '{' (UUID)? AnimationOptionsValue '}' /, AnimationOptionsValue: / $ANY /, AnimationSet: / AnimationSetLong | ( AnimationSetValue ';') /, AnimationSetLong: / 'AnimationSet' (Name)? '{' (UUID)? AnimationSetValue '}' /, AnimationSetValue: / $ANY /, AnimTicksPerSecond: / AnimTicksPerSecondLong | ( AnimTicksPerSecondValue ';') /, AnimTicksPerSecondLong: / 'AnimTicksPerSecond' (Name)? '{' (UUID)? AnimTicksPerSecondValue '}' /, AnimTicksPerSecondValue: / $ANY /, Boolean: / BooleanLong | ( BooleanValue ';') /, BooleanLong: / 'Boolean' (Name)? '{' (UUID)? BooleanValue '}' /, BooleanValue: / $ANY /, Boolean2d: / Boolean2dLong | ( Boolean2dValue ';') /, Boolean2dLong: / 'Boolean2d' (Name)? '{' (UUID)? Boolean2dValue '}' /, Boolean2dValue: / $ANY /, ColorRGB: / ColorRGBLong | (ColorRGBValue ';') /, ColorRGBLong: / 'ColorRGB' (Name)? '{' (UUID)? ColorRGBValue '}' /, ColorRGBValue: / FloatValue:red FloatValue:green FloatValue:blue /, ColorRGBA: / ColorRGBALong | (ColorRGBAValue ';') /, ColorRGBALong: / 'ColorRGBA' (Name)? '{' (UUID)? ColorRGBAValue '}' /, ColorRGBAValue: / FloatValue:red FloatValue:green FloatValue:blue FloatValue:alpha /, Coords2d: / Coords2dLong | (Coords2dValue ';') /, Coords2dLong: / 'Coords2d' (Name)? '{' (UUID)? Coords2dValue '}' /, Coords2dArray: / Coords2dValue (',' Coords2dValue)* (',')? ';' /, Coords2dValue: / FloatValue:u FloatValue:v /, (中略) XSkinMeshHeader: / XSkinMeshHeaderLong | ( XSkinMeshHeaderValue ';') /, XSkinMeshHeaderLong: / 'XSkinMeshHeader' (Name)? '{' (UUID)? XSkinMeshHeaderValue '}' /, XSkinMeshHeaderValue: / $ANY /, }, "XFile", Gin.SPACE); function XFileHandler() { this._s = [] }; XFileHandler.prototype = { first: function(v){ return v[0]; }, header: function(v){ alert("version: " + v[1]); }, identifier: function(v){ alert("identifier:" + v[0]); }, xof: function(v){ alert("xof"); }, showValue: function(v){ alert("value:" + v); }, name: function(v){ alert("name:" + v); }, (中略) // Mesh mesh: function(v){ alert("Mesh start"); }, nVertices: function(v){ alert("nVertices: " + v); }, vertices: function(v){}, nFaces: function(v){ alert("nFaces: " + v); }, faces: function(v){}, (中略) }; var match; function parseXFile(request) { var text = request.responseText; var handler = new XFileHandler(); match = xfileGrammar.parse(text, handler); if(match && match.full) { alert("OK"); }else{ alert("NG"); } } var url = "xfile.x"; var myAjax = new Ajax.Request( url, { method: 'get', onComplete: parseXFile }); }パースしたいデータの構文が分かっているなら、それをそのまま書いてやれば簡単にパーサが実装できる。
速度を優先するなら、各ファイル形式に合わせて自分で実装すべし。
xファイルのパーサはこんな感じで作りました。
var XParser = Class.create({ _text: null, (中略) parse: function(text){ this._text = text; if(!this._obj){ this._obj = new XModel(); } this._offset = 0; this._err = 0; if(!this.XFileHeader(this._obj)){ alert("header format error"); this._err = 1; return null; } while(this.XObjectLong(this._obj)){} if(this._err){ alert("obj format error:" + this._err); return null; } this.splitFaceNormals(); return this._obj; }, moveIndex: function(len) { this._text = this._text.substring(len); this._offset += len; }, getString: function(pattern) { this.skip(); var str = this._text.match(pattern); if(str != null){ this.moveIndex(str[0].length); return str[0]; } return null; }, /* matching patterns */ skip: function() { var i=0; var code; while(1){ code = this._text.charCodeAt(i); if(code != 32 && (code < 9 || code > 13)){ break; } i++; } if(i>0){ this.moveIndex(i); } }, _integerPattern: new RegExp(/^(-|\+)?\d+;?/), getInteger: function() { var str = this.getString(this._integerPattern); var val = parseInt(str); return val; }, _floatPattern: new RegExp(/^(-|\+)?(\d)*\.(\d)*;?/), getFloat: function() { var str = this.getString(this._floatPattern); var val = parseFloat(str); return val; }, (中略) XObjectLong: function(parent){ var id = this.getWord(); if(id == null){ return null; } switch(id){ case "template": return this.Template(parent); case "Header": return this.Header(parent); case "Mesh": return this.Mesh(parent); case "MeshMaterialList": return this.MeshMaterialList(parent); case "MeshNormals": return this.MeshNormals(parent); case "MeshTextureCoords": return this.MeshTextureCoords(parent); case "MeshVertexColors": return this.MeshVertexColors(parent); default: alert("unknown type:" + id); break; } return false; }, (中略) Mesh: function(parent) { this.getLeftBrace(); // vertices var nVertices = this.getInteger(); var skinArray = $A(); for(var i=0; i<nVertices; i++){ var skin = new Skin(); var pos = new DHVector3(); pos.x = this.getFloat(); pos.y = this.getFloat(); pos.z = -this.getFloat(); skin.position = pos; skin.boneIndex[0] = 0; skin.boneIndex[1] = -1; skin.boneIndex[2] = -1; skin.boneIndex[3] = -1; skin.skinWeight[0] = 1; skin.skinWeight[1] = 0; skin.skinWeight[2] = 0; skin.skinWeight[3] = 0; skinArray.push(skin); this.getCommaOrSemicolon(); } this._obj.skinArray = skinArray; this._obj.dynamicSkinOffset = -1; // faces var nFaces = this.getInteger(); var faces = $A(); for(var i=0; i<nFaces; i++){ var face = this.getIntegerArray(); faces.push(face); } this._indices = faces; this.getRightBrace(); return true; }, (中略) }
タグ:
この記事のURL: https://darkhorse2.0spec.jp/176/
2012/10/05(Fri) 01:21:39