1 /* 2 主にSE及びBGM等のセリフ以外のサウンドを扱うオブジェクト 3 値にブランクが存在するので、リプレースメントをベースに作成 4 5 初期化引数の(コンテント)形式は、'ラベル"注釈テクスト"' 6 スポッティング等に使用されるトラック 7 */ 8 nas.AnimationSound=function(myParent,myContent){ 9 this.parent = (myParent)? myParent : null ;//xMapElementGroup or null 10 this.contentText = (myContent)? myContent : '';//xMap上のコンテントソースを保存する 自動で再構築が行なわれるタイミングがある 11 //myContent undefined で初期化を行った場合の値は blank-cell 12 this.name ;//要素名(グループ名があればパース時に除く) 13 this.noteText ;//注釈テキスト 要素区間にマージンがあれば表示される 14 this.source ;//nas.AnimationElementSource 15 this.comment ;//コメント文字列 エレメントの注釈プロパティ-xMap編集UIのみで確認できる 16 17 this.parseContent(); 18 } 19 /* 20 主に予約ラベルで構成されるが、シートに入力された注釈テキストがあればそれらをxMapに保存する。 21 注釈テキストは 22 */ 23 nas.AnimationSound.prototype.toString=function(exportForm){ 24 //return this.contentText;//動作確認用ダミー行 25 26 if(exportForm == 'extend'){ 27 var resultArray=[]; 28 if(this.source) resultArray.push('\tfile = "' + this.source.toString(true)+'"'); 29 if(this.size) resultArray.push('\tsize = ' + this.size.toString()); 30 if(this.offset) resultArray.push('\toffset = ' + this.offset.toString()); 31 if(this.rotation) resultArray.push('\trotation = ' + this.rotation.toString()); 32 if(this.comment) resultArray.push('\tcomment = ' + this.comment); 33 return resultArray.join("\n"); 34 }else if ((arguments.length==0)||((arguments.length==1)&&(! arguments[0]))||(exportForm == 'basic')){ 35 var resultArray=[]; 36 37 if(this.source) resultArray.push('"'+this.source.toString()+'"'); 38 if(this.size) resultArray.push(this.size.toString()); 39 if(this.offset) resultArray.push(this.offset.toString()); 40 if(this.rotation) resultArray.push(this.rotation.toString()); 41 resultArray = [resultArray.join(",")]; 42 if(this.comment) resultArray.push(this.comment); 43 return ([this.parent.name,this.name,resultArray.join("\t")]).join('\t'); 44 } 45 } 46 //nas.AnimationSound.prototype.valueOf=function(){ 47 // return nas.parseNumber(nas.normalizeStr(this.name).replace(/^[^0-9]*/,"")) 48 //valueOfの設定自体にあまり意味が無いのでやめたほうがヨサゲ 49 //} 50 /** 与えられたオブジェクトとプロパティ同士を比較して 変更状態を返す 51 引数 52 対照する基準値(オブジェクト) 53 戻り値 54 変更状態コード 55 0 変化なし 最小標準出力に対応 56 1 標準変更 拡張標準出力に対応 57 2 重度変更 フルダンプに対応 58 */ 59 nas.AnimationSound.prototype.compareWith= function(targetValue){ 60 var igunoreProps =['contentText','source']; 61 var basicProp =['size','offset','comment']; 62 var extendProps =['pegOffset',]; 63 } 64 /** タイミングパラメータに従って指定されたフレームのキー間の補完値を返す 65 66 置きかえタイムラインの中間値は前方値で代表されるので基本的に戻り値は自分自身 67 オプションの状態によって(時間的)中間タイミングで後方値に切り替える 68 return endValue; 69 又はブランク状態のオブジェクトを返す 70 return new nas.newAnimationSound("blank"); 71 */ 72 nas.AnimationSound.prototype.interpolate= function(endValue,indexCount,indexOffset,frameCount,frameOffset,props){ 73 return this; 74 } 75 76 /** Contentをパースして プロパティを設定する内部メソッド 77 引数でcontentを与えてオブジェクト全体の値を更新することも可能 78 引数がAnimationRepalcementであった場合は、全プロパティを継承して引き写す 79 ただし引数と同じジョブ内のコレクションに追加を行う場合は、失敗するので要注意 80 81 xMap形式のデータをパースする nas.AnimationXXX シリーズオブジェクトの共通メソッド 82 xMapパーサから呼び出す際に共通でコールされる 83 引数が与えられない場合は、現在の保持コンテンツを再パースする 84 */ 85 nas.AnimationSound.prototype.parseContent = function(myContent){ 86 // var blankRegex = new RegExp("^[xXxX×〆00]$");//カラ判定 システム変数として分離予定 87 var interpRegex = new RegExp("^[\-\+=○●*・a-zア-ン]$|^\[[^\]]+\]$");//中間値補間(動画記号)サイン 同上 88 var valueRegex = new RegExp("^[\(<]?[0-9]+[>\)]?$");//無条件有効値 同上 89 90 //引数がなければ現在のコンテンツを再パース 91 if(typeof myContent == 'undefined'){ 92 myContent = this.contentText; 93 }else{ 94 95 this.contentText = myContent; 96 } 97 /* 98 AnimatiopnReplacementの特殊値として 99 contentText='blank-cell'を設ける 100 AnimationElementSource("") 101 サイズは不問 シンボルとしての「カラセル」 102 103 */ 104 if(myContent == 'blank-cell') return this; 105 var isGroup = (myContent.indexOf('[')==0)? true:false; 106 //第一形式グループ ^[\<group>\t<typeName>[\t<option-text>[\t<comment>]]\]$ 107 //第二形式エントリ ^<group>\t<name>[\t<option-text>[\t<comment>]]$ 108 109 myContent = String(myContent).split('\n'); 110 for ( var line = 0 ; line < myContent.length ; line++){ 111 112 if((isGroup)&&(myContent[line].indexOf('[')==0)) myContent[line] = myContent[line].slice(1,-1);//ブラケット削除 113 114 if(myContent[line].match(/^\t(\S+)\s*=\s*(.+)\s*$/)){ 115 //第二形式(タブ開始)でプロパティ別のデータ更新を行う 116 this.extended=true; 117 118 var myProp=RegExp.$1;var valueArray=csvSimple.parse(RegExp.$2)[0]; 119 120 switch(myProp){ 121 case "file": 122 this.file = new nas.AnimationElementSource(valueArray[0]); 123 break; 124 case "resolution": 125 this.resolution= new nas.Resolution(valueArray.join(',')); 126 break; 127 case "resolution.X": 128 this.resolution.x = new nas.UnitResolution(valueArray[0],this.resolution.type); 129 break; 130 case "resolution.Y": 131 this.resolution.y = new nas.UnitResolution(valueArray[0],this.resolution.type); 132 break; 133 case "size": 134 this.size = (valueArray.length<3)? 135 new nas.Size(valueArray[0],valueArray[1]):new nas.Size(valueArray[0],valueArray[1],valueArray[2]); 136 break; 137 case "size.X": 138 this.size.x = new nas.UnitValue(valueArray[0]); 139 break; 140 case "size.Y": 141 this.size.y = new nas.UnitValue(valueArray[0]); 142 break; 143 case "offset": 144 this.offset = (valueArray.length<3)? 145 new nas.Offset(valueArray[0],valueArray[1]):new nas.Offset(valueArray[0],valueArray[1],valueArray[2]); 146 break; 147 case "offset.X": 148 this.offset.x = new nas.UnitValue(valueArray[0]); 149 break; 150 case "offset.Y": 151 this.offset.y = new nas.UnitValue(valueArray[0]); 152 break; 153 case "offset.R": 154 this.offset.r = new nas.UnitAngle(valueArray[0]); 155 break; 156 case "pegOffset": 157 this.offset = (valueArray.length<3)? 158 new nas.Offset(valueArray[0],valueArray[1]):new nas.Offset(valueArray[0],valueArray[1],valueArray[2]); 159 break; 160 case "pegOffset.X": 161 this.offset.x=new nas.UnitValue(valueArray[0]); 162 break; 163 case "pegOffset.Y": 164 this.offset.y=new nas.UnitValue(valueArray[0]); 165 break; 166 case "pegOffset.R": 167 this.offset.r=new nas.UnitAngle(valueArray[0]); 168 break; 169 default: 170 this[myProp]=valueArray[0]; 171 } 172 } else if(myContent[line].match(/^(\S+)\t?(\S+)\t?([^\t]+)?\t?(.*)$/)){ 173 // 第一形式の再パース 174 console.log(myContent[line]); 175 var myGroup=RegExp.$1; //グループの再パースは行われない 176 var myName =RegExp.$2; 177 var myComment=RegExp.$4; 178 var valueArray=nas.parseDataChank(RegExp.$3); 179 var numeProps =[["size","x"],["size","y"],["offset","x"],["offset","y"]]; 180 181 console.log(myComment); 182 console.log(valueArray); 183 console.log(this); 184 /* 185 フィールド文字列であった場合の判定が必要 2018 10 09 186 187 case :this.parent == null 188 */ 189 if((! (this.parent))||(myGroup == this.parent.name)){ 190 if(! isGroup) this.name = myName.replace(new RegExp('^'+myGroup+'\-'),""); 191 var numCount=0; 192 for(var vix=0;vix<valueArray.length;vix++){ 193 switch(valueArray[vix].type){ 194 case "numeric": 195 case "unitValue": 196 if(numCount<numeProps.length){ 197 if(! this[numeProps[numCount][0]]){ 198 this[numeProps[numCount][0]] = ([numeProps[numCount][0]]=='size')? new nas.Size():new nas.Offset(); 199 } 200 this[numeProps[numCount][0]][numeProps[numCount][1]] = new nas.UnitValue(valueArray[vix].value); 201 numCount++; 202 } 203 break; 204 case "unitAngle": 205 if(! this.offset) this.offset = new nas.Offset(); 206 this.offset.r==new nas.UnitAngle(valueArray[vix].value); 207 break; 208 case "unitResolution": 209 this.resolution=new nas.Resolution(valueArray[vix].value); 210 break; 211 case "source": 212 this.source=new nas.AnimationElementSource(valueArray[vix].value); 213 break; 214 default: 215 continue; 216 } 217 } 218 if(myComment) this.comment = myComment; 219 } 220 } 221 222 } 223 return this; 224 } 225 /** 指定フレーム数に内容を展開して配列で返す 226 引数 :cellCount 227 戻値 :配列 + offset 228 */ 229 nas.AnimationSound.prototype.getStream=function(cellCounts){ 230 var myResult=new Array(cellCounts); 231 myResult[0]=(this.name)? this.name:""; 232 if (myResult[0].match(/blank(-cell)?/)) myResult[0]="X"; 233 return myResult; 234 } 235 /** 236 置きかえタイムライントラックをパースしてセクションコレクションを返す 237 セクションの値を各トラックごとの値オブジェクトからxMapを介したxMapエレメントに変更する 238 239 パース時にセクションの値判定を行う 240 ・無効記述 241 ・有効記述 値あり(xMap既存エレメント)・なし(新規エレメント) 242 243 タイムライントラックをパースする際に統一手順としてトラックに対応するxMapエレメントグループの有無を確認する。 244 現行Jobにトラックと同名のエレメントグループが、存在しなかった場合(Stageには存在する可能性あり)は、新規にグループを作成してエントリすること。 245 この処理は、トラックパースの前段階で共通で行うことにする 246 247 確認手段は xMap.getElementByName(グループ名)を使用 248 //XpsTimelineTrack.parseTimelineTrack() メソッドに置く 249 250 251 中間値補間区間の空セルに対応するために全体のブランク処理をサブセクションコレクションに置く 252 置きかえタイムラインのみの処置 253 カラ状態のみを扱うsctionCollectionを併置してセットで扱うので注意 254 各セクションのvalueは on/off(true/false)のみでオブジェクトは使用されない エレメントへのリンクも無い 255 一つのトラックをパースして二つのセクションコレクションを得る 256 値側のコレクションは、従来のカラを含むことができるが、このパーサが書き出すデータ上は従来型のカラが含まれることは無い 257 カラ区間の値は先行区間の値となる 258 カラセル区間コレクションは2つの状態しか持ち得ないので、サブセクションは発生しない 259 260 */ 261 _parseReplacementTrack=function(){ 262 // var blankRegex = new RegExp("^[xXxX×〆00]$");//カラ判定 システム変数として分離予定 263 var interpRegex = new RegExp("^[\-\+=○◯●*・a-zア-ン]$|^\[[^\]]+\]$");//中間値補間(動画記号)サイン 同上 264 var valueRegex = new RegExp("^[\(<]?[0-9]+[>\)]?$");//無条件有効値 同上 265 //自分自身(トラック)を親として新規セクションコレクションを作成 266 var myCollectionBlank = new XpsTimelineSectionCollection(this);//ブランクベースコレクション 267 var myCollection = new XpsTimelineSectionCollection(this);//ベースコレクション 268 269 var appearance = new nas.AnimationAppearance(null,'on'); 270 var disAppearance = new nas.AnimationAppearance(null,'off'); 271 272 //継続時間0で値未定初期セクションを作成 273 //値を持たないセクションをブランク値のオブジェクトとするか? 274 var currentSection=myCollection.addSection(null); 275 276 var currentSubSection = null; 277 var currentValue = this.getDefaultValue(); 278 if(! currentValue) currentValue = new nas.AnimationSound('system','blank-cell'); 279 //console.log(currentValue) 280 var isInterp = false; 281 var isBlank = ((! currentValue)||(currentValue.contentText == "blank-cell"))? true:false ;//デフォルトのブランク状態を取得 282 283 var currentSectionBlank=(isBlank)? myCollectionBlank.addSection(disAppearance):myCollectionBlank.addSection(appearance); 284 285 var valueDetect = false; 286 /** 287 タイムライントラックのデフォルト値は、以下の手続きで取得 288 タイムラインラベルが指定するグループがあらかじめ存在する場合は、そのグループオブジェクトが保持する値 289 存在しない場合は、新規にグループを作成する。その際にトラックの種別ごとのValueオブジェクトを初期値として登録するのでその値を使用 290 XpsTimelineTrack.getDefeultValue()側で調整 291 Replacementの場合基本はブランクだが、必ずしもブランクとは限らないので要注意 292 トラック上で明示的なブランクが指定された場合は、値にfalse/null/"blank"を与える。 293 */ 294 for (var fix=0;fix<this.length;fix++){ 295 var currentCell=Xps.sliceReplacementLabel(new String(this[fix]));//記述をラベルとエントリに分解 296 if( currentCell.length == 1 ){ currentCell.push(this.id); }//エントリにグループ名が含まれないようならばトラックのラベルで補う 297 // ここでデータの形式は [name,groupName] となる 298 currentSection.duration ++; // 299 currentSectionBlank.duration ++; //セクション長加算 300 if(currentSubSection) currentSubSection.duration ++ ; 301 //未記入データ これが一番多いので最初に処理しておく(処理高速化のため) 302 if(currentCell[0].match(/^([\||;]|\s+)$/)||currentCell.length==0) continue; 303 /* ブランク判定 304 値処理に先立ってブランク関連の処理をすべて終了する 305 ブランク状態切り替え判定 カレントを切り替えて新規セクションを積む 306 */ 307 var valueDetect = false;//値検出状態初期化 308 var blankDetect = (String(currentCell[0]).match(nas.CellDescription.blankRegex))? true:false;//値からブランク状態を検出 309 var interpDetect = (String(currentCell[0]).match(nas.CellDescription.interpRegex))? true:false;//括弧つきの補間サインも同時検出へ 310 //console.log(fix+":"+this[fix]+" interp:"+interpDetect + " blank: " + blankDetect); 311 //ブランク処理判定 312 if(blankDetect){ 313 if(! isBlank){ 314 if(fix==0){ 315 currentSectionBlank.value=disAppearance; 316 currentSection.value = new nas.AnimationSound('system','blank-cell');// *Blank-set 317 }else{ 318 currentSectionBlank.duration --; 319 currentSectionBlank=myCollectionBlank.addSection(disAppearance); 320 currentSectionBlank.duration ++; 321 currentSection.duration --;// * 322 currentSection=myCollection.addSection(this.pushEntry('blank-cell','system'));// * 323 currentSection.duration ++;// * 324 if(currentSubSection){ 325 currentSubSection.duration --; 326 currentSubSection = null; 327 } 328 } 329 isBlank=true; 330 } 331 continue; 332 } 333 // else if(fix==0){ currentSectionBlank.value=appearance; } 334 //中間値補間サインを検出したら中間値処理モード 335 //既定値以外の補間サイン検出が必要>> 規定値のみを補完サインと定義する 他の記述はコメントとして利用 336 if(interpDetect){ 337 if( isBlank ){ 338 if(fix==0){ 339 currentSectionBlank.value=appearance; 340 }else{ 341 currentSectionBlank.duration --; 342 currentSectionBlank=myCollectionBlank.addSection(appearance); 343 currentSectionBlank.duration ++; 344 } 345 isBlank = false; 346 } 347 if(! isInterp ){ 348 //中間値補間区間開始 カレントセクションを切り替え サブセクションを登録 349 isInterp = true; 350 if(fix==0){ 351 currentSection.value="interpolation"; 352 }else{ 353 currentSection.duration --; 354 currentSection=myCollection.addSection("interpolation"); 355 currentSection.duration ++; 356 } 357 currentSubSection = currentSection.subSections.addSection(new nas.AnimationSound(null,currentCell.join("-"))); 358 currentSubSection.duration ++; 359 //新規中間値補間セクションを立てる 以降は、モードを抜けるまでカレント固定 360 }else{ 361 currentSubSection.duration --; 362 currentSubSection = currentSection.subSections.addSection(new nas.AnimationSound(null,currentCell.join("-"))); 363 currentSubSection.duration ++; 364 //中間値補間モード内ではサブセクションを登録 365 } 366 continue; 367 } 368 //区間値を処理 369 /** 370 既存エントリがない場合、エントリ文字列が条件を満たせば新規エントリとしてxMapにグループとエントリを登録して使用する 371 それ以外は、無効エントリとなる 372 */ 373 //console.log(currentCell.join("-")); 374 var currentElement = this.xParent.parentXps.xMap.getElementByName(currentCell.join("-")); 375 if(currentElement) { 376 //console.log("value detcted in xMap:"); 377 valueDetect=true; 378 }else{ 379 //console.log("value not detcted in xMap: push Entry "+currentCell.reverse().join("-")); 380 if(String(currentCell[0]).match(valueRegex)){ 381 valueDetect = true; 382 currentElement=this.pushEntry(currentCell[0],currentCell[1]); 383 } 384 } 385 //console.log(valueDetect); 386 //console.log(currentElement); 387 if(valueDetect){ 388 currentValue = currentElement.content; 389 if(isBlank){ 390 if(fix==0){ 391 currentSectionBlank.value=appearance; 392 }else{ 393 currentSectionBlank.duration --; 394 currentSectionBlank=myCollectionBlank.addSection(appearance); 395 currentSectionBlank.duration ++; 396 } 397 isBlank = false; 398 } 399 if(isInterp){ 400 isInterp = false; 401 currentSubSection.duration --; 402 currentSubSection = null; 403 } 404 if(fix==0){ 405 currentSection.value = currentValue; 406 }else{ 407 currentSection.duration --; 408 currentSection = myCollection.addSection(currentValue); 409 currentSection.duration ++; 410 } 411 } 412 continue 413 } 414 //console.log(myCollection) 415 this.sections = myCollection; 416 this.sectionsBlank = myCollectionBlank; 417 //console.log("sections-length:"+myCollection.length +":blank:"+myCollectionBlank.length); 418 return this.sections;//ブランク情報の返し方を考えたほうが良いかも 419 } 420 421 /*test 422 423 XpsTimelineTrack.prototype.parseReplacementTrack=_parseReplacementTrack; 424 XPS.xpsTracks[2].parseReplacementTrack(); 425 XPS.xpsTracks[2].sections[1].toString(); 426 427 XpsTimelineTrack.prototype.parseReplacementTrack=_parseReplacementTrack; 428 429 XpsTimelineTrack.prototype.parseCameraWorkTrack=_parseCameraworkTrack; 430 431 XpsTimelineTrack.prototype.parseCompositeTrack=_parseCompositeTrack;//コンポジット 432 433 //XpsTimelineTrack.prototype.parseTrack=_parseTrack; 434 //XpsTimelineTrack.prototype.parseTrack=_parseTrack; 435 */