Metasequoia.as 拡張クラス ( ローカルの zip 書庫内のファイルをロードする )


  概要




Shot_miku

Metasequoia_v クラスについて
Metasequoia クラスは、Papervision3D に Metasequoia のデータをロードするクラスですが、
これに限らず、swf からロードできる WEB 上に置く必要があります。しかし、Flash の 10.0.12 から
ローカルの PC にあるデータ( ファイルシステム ) をロードできるので、zip ファイルに mqo と テクスチャ
を保存して、zip ファイルを読み込む事で本来の Metasequoia クラス の機能を果たせるようにしたものです。
( zip 内にフォルダは作成しないで下さい )

まだ基本機能ができただけなので、後 dae に対応して うまくいったら、
Google SketchUp のエクスポートデータもできるはずなので、
最低そこまではなんとかしたいと思っています

Papervision3D の標準マテリアルは独自形式を作ってロードできるようにして、
最終的には、マテリアル単位の map ファイルを書庫に含めようと思っています。
そうすると、ある意味 3D 紙芝居程度は簡単にできそうな気がします

( もちろん Papervision3D の シューティングゲームはやってみたいです )

zipfile の処理は、Papervision3D に付属していたクラスを使っていますが、
FLARToolKit の Papervision3Dには付属していないので、必要なライブラリを持ち寄る必要があります

  ビルド時の注意

ローカルのファイルをロードする機能を使っていますので以下のようになります

  

mxmlc Main.mxml -target-player=10.0.12
  

  ソースコード


Metasequoia.as を継承して使っていますが、後々のメンテナンス性を考えての事です。
結局 その都合から、Metasequoia.as の private を 全て protected に変更しています。



▼ 実装ページ
WEB カメ くらぶ

サンプルでは、FLARToolKit で使っていますので、インスタンスを FLARToolKit の baseNode に addChild します
それ以外の 通常 Flexでは、rawChildren.addChild です。 ( Canvas 等 )

▼ public class SimpleCube extends PV3DARApp の内部
  

public function loadMqo( data:DisplayObject3D ):void {

	this._baseNode.addChild( data );

}
  

▼ Main.mxml の呼び出し
  

// *************************************************
// メタセコイア拡張のロード完了
// *************************************************
mqo_v = new Metasequoia_v();
mqo_v.addEventListener(Event.COMPLETE, function(e:Event):void {

	sc.loadMqo(mqo_v);
	mqo_v.rotationX = -90;
	mqo_v.scale = 1;
	ns.value = 1;

});
  


  

/**
 * Metasequoia.as
 * 
 * @see http://snippets.libspark.org/
 * @see http://snippets.libspark.org/trac/wiki/rch850/Metasequoia
 * 
 * Copyright (c) 2007-2008 rch850
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

package org.libspark.pv3d {

  // Main.mxml の firebug 関数参照用
  import mx.core.Application;
  import mx.controls.*;

  import flash.display.BitmapData;
  import flash.display.Loader;
  import flash.events.*;
  import flash.net.URLLoader;
  import flash.net.URLLoaderDataFormat;
  import flash.net.URLRequest;
  import flash.net.FileReference;
  import flash.utils.ByteArray;
  import flash.utils.Dictionary;
  import org.libspark.pv3d.decoders.TGADecoder;
  import org.papervision3d.core.geom.TriangleMesh3D;
  import org.papervision3d.core.geom.renderables.Triangle3D;
  import org.papervision3d.core.geom.renderables.Vertex3D;
  import org.papervision3d.core.math.Matrix3D;
  import org.papervision3d.core.math.NumberUV;
  import org.papervision3d.core.proto.DisplayObjectContainer3D;
  import org.papervision3d.core.proto.GeometryObject3D;
  import org.papervision3d.core.proto.MaterialObject3D;
  import org.papervision3d.events.FileLoadEvent;
  import org.papervision3d.events.InteractiveScene3DEvent;
  import org.papervision3d.materials.BitmapFileMaterial;
  import org.papervision3d.materials.BitmapMaterial;
  import org.papervision3d.materials.ColorMaterial;
  import org.papervision3d.materials.utils.MaterialsList;
  import org.papervision3d.objects.DisplayObject3D;
  import nochump.util.zip.*;

  import com.voidelement.images.BMPDecoder;  

  import org.libspark.pv3d.Metasequoia;

  //*******************************************************
  // Metasequoia 継承クラス
  //*******************************************************
  public class Metasequoia_v extends Metasequoia {

    public var fRef:FileReference;
    public var imageExt:String = "png,jpg,jpeg";
    private var texget:BitmapMaterial = null;
    private var loader:Loader;
    private var bmp_loader:Loader;
    private var _ext:String;
    private var data_list:Object = new Object();
    private var zip_num:int;    // zipfile 内の ファイル数
    private var bitmap_num:int;    // zipfile 内の 画像数
    private var zipFile:ZipFile;
    private var mqo_temp:Array;
    private var mqo_target:ByteArray;
    private var bitamp_count:int = 0;
    private var zip:ByteArray;

    // ファイル参照対象ファイルのデフォルト
    private var targetDreft:String = "zipfile";

    // *************************************************
    // コンストラクタ
    // *************************************************
    function Metasequoia_v() {
      super();

      // ファイルリファレンスのイベント登録
      frefinit();
    }

    // *************************************************
    // ファイルリファレンスのイベント登録
    // *************************************************
    private function frefinit():void {

      bmp_loader = new Loader();

      // 画像( テクスチャの取り出し )
      bmp_loader.contentLoaderInfo.addEventListener(Event.COMPLETE,function(e:Event):void{

        var i:int;
        var ename:String = ZipEntry(zipFile.entries[bitamp_count]).name;
        // data_list は、Object。ファイル名によるプロパティに
        // Material(テクスチャ) を保存
        data_list[ename] =   new BitmapMaterial( e.target.content.bitmapData );

        bitmap_num--;
        if ( bitmap_num <= 0 ) {
          mx.core.Application.application.firebug("メタセコイアロード開始");
          buildMetasequoia(mqo_target.readMultiByte(mqo_target.length, charset));

          dispatchEvent(new Event(Event.COMPLETE));

        }
        else {
          // 次のテクスチャをロードする
          for( i = bitamp_count+1; i < zip_num; i++ ) {
            if ( chkExt( ZipEntry(zipFile.entries[i]).name, imageExt ) ) {
              // 明示的に ByteArray とする
              zip = zipFile.getInput(ZipEntry(zipFile.entries[i]));
              bmp_loader.loadBytes(zip);
              bitamp_count = i;
              break;
            }
          }
        }
      });

      // ファイルリファレンスの準備
      fRef = new FileReference();
      fRef.addEventListener(Event.OPEN, function(e:Event):void {} );
      fRef.addEventListener(ProgressEvent.PROGRESS, function(e:ProgressEvent):void {} );
      // load 完了
      fRef.addEventListener(Event.COMPLETE, function(e:Event):void {
        mx.core.Application.application.firebug("fref : COMPLETE(load) : "+e.target.name);

        // zipfile の場合、画像ファイルの bitmapData を BitmapMaterial
        // に変換してファイル名で 配列に保存しておく
        if ( chkExt( e.target.name, "zip" ) ) {
          var i:int; // ループ用
          // 明示的に ByteArray とする
          zip = FileReference(e.target).data;
          // ZipFile のインスタンスを作成する
          zipFile = new ZipFile(zip);

          zip_num = zipFile.entries.length;
          bitmap_num = 0;
          // まず画像ファイル数のカウント
          for( i = 0; i < zip_num; i++ ) {
            if ( chkExt( ZipEntry(zipFile.entries[i]).name, imageExt ) ) {
              bitmap_num++;
            }
            // メタセコイアの ByteArray
            if ( chkExt( ZipEntry(zipFile.entries[i]).name, "mqo" ) ) {
              mqo_target = zipFile.getInput(ZipEntry(zipFile.entries[i]));
            }
          }

          // 画像( 最初のテクスチャの取り出し ) : 非同期
          for( i = 0; i < zip_num; i++ ) {
            if ( chkExt( ZipEntry(zipFile.entries[i]).name, imageExt ) ) {
              // 明示的に ByteArray とする
              zip = zipFile.getInput(ZipEntry(zipFile.entries[i]));
              bmp_loader.loadBytes(zip);
              bitamp_count = i;
              break;
            }
          }

        }

      } );
      // キャンセル
      fRef.addEventListener(Event.CANCEL, function(e:Event):void {
        mx.core.Application.application.firebug("fref : cancel : "+e);
      } );
      // 選択直後
      fRef.addEventListener(Event.SELECT, function(e:Event):void {
        mx.core.Application.application.firebug("fref : select : "+e.target.name);
        if ( chkExt( e.target.name, _ext ) ) {
          FileReference(e.target).load();
        }
      } );
      fRef.addEventListener(IOErrorEvent.IO_ERROR, fRefError );
    }
    private function fRefError( e:IOErrorEvent ):void {
      Alert.show(e.text);
    }

    // *************************************************
    // ●公開メソッド : ロード : zipfile のByteArray
    // ※ 未テストです
    // *************************************************
    public function loadZipfle(byteArray:ByteArray, scale:Number = 1):void {
      _scale = scale;
      var i:int; // ループ用
      // ZipFile のインスタンスを作成する
      zipFile = new ZipFile(byteArray);

      zip_num = zipFile.entries.length;
      bitmap_num = 0;
      // まず画像ファイル数のカウント
      for( i = 0; i < zip_num; i++ ) {
        if ( chkExt( ZipEntry(zipFile.entries[i]).name, imageExt ) ) {
          bitmap_num++;
        }
        // メタセコイアの ByteArray
        if ( chkExt( ZipEntry(zipFile.entries[i]).name, "mqo" ) ) {
          mqo_target = zipFile.getInput(ZipEntry(zipFile.entries[i]));
        }
      }

      // 画像( 最初のテクスチャの取り出し ) : 非同期
      for( i = 0; i < zip_num; i++ ) {
        if ( chkExt( ZipEntry(zipFile.entries[i]).name, imageExt ) ) {
          // 明示的に ByteArray とする
          zip = zipFile.getInput(ZipEntry(zipFile.entries[i]));
          bmp_loader.loadBytes(zip);
          bitamp_count = i;
          break;
        }
      }
    }

    // *************************************************
    // ●公開メソッド : 参照 : 引数は拡張子リスト
    // 例 : browse( "zip" ) または 
    //      browse( "jpeg,jpg,png" )
    // *************************************************
    public function browse(ext:String,scale:Number = 1):void {
      _scale = scale;
      _ext = ext;
      fRef.browse();
    }

    // *************************************************
    // 拡張子チェック
    // *************************************************
    private function chkExt( target:String, ext:String ):Boolean {

      var lst:Array = ext.split(",");

      var test:Array = target.split(".");
      if ( test.length == 1 ) {
        return false;
      }
      var str:String = String(test[1]);
      str = str.toLocaleUpperCase();

      var chk:String;
      for( var i:int = 0; i < lst.length; i++ ) {
        chk = (lst[i]).toLocaleUpperCase();
        if ( str == chk ) {
          return true;
        }
      }
      return false;

    }

    
    /**
    * Material チャンクを読み込み、その最後の行番号を返します。
    * エラーが起こった場合は -1 を返します。
    */
    //*******************************************************
    // データ処理の心臓部
    //*******************************************************
    protected override function parseMaterialChunk(lines:Array, startLine:int):int {
      var l:int = getMaterialChunkLine(lines, startLine);

      if (l == -1) {
        return -1;
      }
      

      // 解析中の行の文字列
      var line:String = lines[l];
      
      // マテリアル数を取得
      var num:Number = parseInt(line.substr(9));
      if (isNaN(num)) {
        return -1;
      }

      ++l;
      _materialNames = new Array();
      
      // } で閉じているところの行番号
      var endLine:int = l + int(num);

      // mqo ファイルのあるディレクトリのパス
//      var path:String = _filename.slice(0, _filename.lastIndexOf("/") + 1);

      for (; l < endLine; ++l) {
        var material:MaterialObject3D;
        line = lines[l];
        
        // マテリアルの名前を取得
        var nameBeginIndex:int = line.indexOf("\"");
        var nameEndIndex:int = line.indexOf("\"", nameBeginIndex + 1);
        var name:String = line.substring(nameBeginIndex + 1, nameEndIndex);
        _materialNames.push(name);
        
        // テクスチャファイル名
        var tex:String = getParam(line, "tex");
        
        if (tex) {

          // テクスチャファイル名を取り囲む " " を取り除く
          tex = tex.substr(1, tex.length - 2);

/*
          _materialsToLoad++;
          if (tex.toLowerCase().search(/\.tga$/) != -1) {
            material = loadTGAMaterial(path + tex);
          } else if (tex.toLowerCase().search(/\.bmp$/) != -1) {
            material = loadBMPMaterial(path + tex);
          } else {
            // テクスチャの URL を絶対にして読み込む
            material = new BitmapFileMaterial(path + tex);
            material.addEventListener(FileLoadEvent.LOAD_COMPLETE, materialLoadCompleteHandler);
            material.addEventListener(FileLoadEvent.LOAD_ERROR, materialLoadErrorHandler);
          }
          // あまり重さが変わらないのでせっかくだからスムージング
*/
          material = data_list[tex];
          material.smooth = true;

        } else {
          // 形式 - col(1.000 1.000 0.000 1.000)
          var colorstr:String = getParam(line, "col");
          if (colorstr != null) {
            var color:Array = colorstr.match(/\d+\.\d+/g);
            var r:int = parseFloat(color[0]) * 255;
            var g:int = parseFloat(color[1]) * 255;
            var b:int = parseFloat(color[2]) * 255;
            var a:Number = parseFloat(color[3]) * 100;
            //trace("rgb = " + r + "," + g + "," + b);
            material = new ColorMaterial((r << 16) | (g << 8) | b);
          } else {
            material = MaterialObject3D.DEFAULT;
          }
        }
        
        material.doubleSided = this.doubleSided;
        material.interactive = this.interactive;
        material.name = name;
        
        materials.addMaterial(material, name);

      }
      
      return endLine;
    }
    
  }
}
  





yahoo  google  MSDN  MSDN(us)  WinFAQ  Win Howto  tohoho  ie_DHTML  vector  wdic  辞書  天気 


[flex3]
Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; ClaudeBot/1.0; +claudebot@anthropic.com)
24/04/20 20:48:22
InfoBoard Version 1.00 : Language=Perl

1 BatchHelper COMprog CommonSpec Cprog CprogBase CprogSAMPLE CprogSTD CprogSTD2 CprogWinsock Cygwin GameScript HTML HTMLcss InstallShield InstallShieldFunc JScript JScriptSAMPLE Jsfuncs LLINK OldProg OracleGold OracleSilver PRO PRObrowser PROc PROconePOINT PROcontrol PROftpclient PROjscript PROmailer PROperl PROperlCHAT PROphp PROphpLesson PROphpLesson2 PROphpLesson3 PROphpfunction PROphpfunctionArray PROphpfunctionMisc PROphpfunctionString PROsql PROvb PROvbFunction PROvbString PROvbdbmtn PROvbonepoint PROwebapp PROwin1POINT PROwinSYSTEM PROwinYOROZU PROwindows ProjectBoard RealPHP ScriptAPP ScriptMaster VBRealtime Vsfuncs a1root access accreq adsi ajax amazon argus asp aspSample aspVarious aspdotnet aw2kinst cappvariety centura ckeyword classStyle cmaterial cmbin cmdbapp cmenum cmlang cmlistbox cmstd cmstdseed cmtxt cs daz3d db dbCommon dbaccess dnettool dos download flex2 flex3 flex4 framemtn framereq freeWorld freesoft gimp ginpro giodownload google hdml home hta htmlDom ie9svg install java javaSwing javascript jetsql jquery jsp jspTest jspVarious lightbox listasp listmsapi listmsie listmsiis listmsnt listmspatch listmsscript listmsvb listmsvc memo ms msde mysql netbeans oraPlsql oracle oracleWiper oraclehelper orafunc other panoramio pear perl personal pgdojo pgdojo_cal pgdojo_holiday pgdojo_idx pgdojo_ref pgdojo_req php phpVarious phpguide plsql postgres ps r205 realC realwebapp regex rgaki ruby rule sboard sc scprint scquest sdb sdbquest seesaa setup sh_Imagick sh_canvas sh_dotnet sh_google sh_tool sh_web shadowbox shgm shjquery shvbs shweb sjscript skadai skywalker smalltech sperl sqlq src systemdoc tcpip tegaki three toolbox twitter typeface usb useXML vb vbdb vbsfunc vbsguide vbsrc vpc wcsignup webanymind webappgen webclass webparts webtool webwsh win8 winofsql wmi work wp youtube