PV3D マトリックス風(なのか?)

2008/06/13

クリックするたんびにいろいろと切り替わります。

参考。というかそのままです。ありがとうございます。

[ActionScript3.0] BitMapフィルターのエフェクトをPaperVison3Dに応用。

以下ソースです。要Tweener + PV1.7

package {
  import caurina.transitions.Tweener;

  import flash.display.BitmapData;
  import flash.display.Shape;
  import flash.display.Sprite;
  import flash.display.StageAlign;
  import flash.display.StageQuality;
  import flash.display.StageScaleMode;
  import flash.events.Event;
  import flash.events.MouseEvent;
  import flash.filters.BlurFilter;
  import flash.filters.GlowFilter;
  import flash.geom.ColorTransform;
  import flash.geom.Matrix;
  import flash.geom.Point;

  import org.papervision3d.cameras.Camera3D;
  import org.papervision3d.core.geom.Vertex3D;
  import org.papervision3d.materials.BitmapMaterial;
  import org.papervision3d.materials.ColorMaterial;
  import org.papervision3d.materials.MaterialsList;
  import org.papervision3d.objects.Cube;
  import org.papervision3d.objects.Cylinder;
  import org.papervision3d.objects.DisplayObject3D;
  import org.papervision3d.objects.Plane;
  import org.papervision3d.objects.Sphere;
  import org.papervision3d.scenes.Scene3D;


  [SWF(width="600", height="400", frameRate="30", backgroundColor="#000000")]
  public class PaperVisionTest1 extends Sprite
  {
    private var container:Sprite;
    private var scene:Scene3D;
    private var camera:Camera3D;
    private var sphere:Sphere;

    private var shape1:DisplayObject3D;
    private var shape2:DisplayObject3D;
    private var shape3:DisplayObject3D;
    private var shape4:DisplayObject3D;

    private var effectBm:BitmapData;
    private var filterdBm:BitmapData;
    private var baseHue:Number = 0;

    public function PaperVisionTest1():void
    {
      stage.quality = StageQuality.LOW;

      stage.scaleMode = StageScaleMode.NO_SCALE;
      stage.align = StageAlign.TOP_LEFT;

      //effect Bitmap
      effectBm = new BitmapData(100, 100, true, 0);
      filterdBm = effectBm.clone();
      var circle:Shape = new Shape();
      circle.graphics.beginFill(0xffffff, 0.5);
      circle.graphics.drawCircle(0,0,13);
      circle.graphics.endFill();

      var mtx:Matrix = new Matrix();
      mtx.translate(30,30);
      effectBm.draw(circle, mtx, new ColorTransform());

      var bf:BlurFilter = new BlurFilter(4,4,3);
      effectBm.applyFilter(effectBm, effectBm.rect, new Point(0,0), bf);

      //テクスチャが見たい場合はコメントはずす
      //addChild(new Bitmap(filterdBm));


      init3D();
      addEventListener(Event.ENTER_FRAME, loop);
      stage.addEventListener(MouseEvent.MOUSE_DOWN, changeMoph);
    }

    private function init3D():void
    {
      container = new Sprite();
      addChild(container);
      container.x = stage.stageWidth / 2;
      container.y = stage.stageHeight / 2;
      scene = new Scene3D(container);
      camera = new Camera3D();
      camera.focus = 250;
      camera.zoom = 1;
      camera.z = -1000;

      var bmm:BitmapMaterial = new BitmapMaterial(filterdBm);

      var num:int = 300;
      var plane:Plane;
      while(num-- > 0)
      {
        plane = new Plane(bmm, 100, 100);
        plane.extra =
        {
          vx:Math.random() * .7 * (Math.random() * 2 > 1 ? 1 : -1),
          vy:Math.random() * .7 * (Math.random() * 2 > 1 ? 1 : -1),
          vz:Math.random() * .7 * (Math.random() * 2 > 1 ? 1 : -1)
        }
        plane.material.doubleSided = true;
        plane.name = "point" + num;
        scene.addChild(plane);
        plane.x = Math.random() * 800 * (Math.random() * 2 > 1 ? 1 : -1);
        plane.y = Math.random() * 800 * (Math.random() * 2 > 1 ? 1 : -1);
        plane.z = Math.random() * 800 * (Math.random() * 2 > 1 ? 1 : -1);
      }

      shape1 = new Cube(new MaterialsList({all:new ColorMaterial(0xFF0000,100)}),800,800,800,7,7,5);
      shape2 = new Sphere(new ColorMaterial(0xFF0000,0),580,16,17);
      shape3 = new Cylinder(new ColorMaterial(0xFF0000,0),700,2000,16,15);
      shape4 = new Plane(new ColorMaterial(0xFF0000,0),1000,1000,15,15);

    }

    private function changeMoph(e:MouseEvent):void
    {
      var rand:int = Math.ceil(Math.random() * 4);
      var i:int = 0;
      var targetShape:DisplayObject3D = this["shape" + rand];

      Tweener.removeAllTweens();

      while(i++ < targetShape.geometry.vertices.length)
      {
        var item:Object = scene.getChildByName('point'+ i);
         var v3d:Vertex3D = targetShape.geometry.vertices[i - 1];
         Tweener.addTween(item, {x:v3d.x, y:v3d.y, z:v3d.z, time:1, delay:0.5, transition:"easeOutSine"});
      }
      var rand3d:Vertex3D = new Vertex3D()
      rand3d.x = Math.random() * 800 * (Math.random() * 2 > 1 ? 1 : -1);
      rand3d.y = Math.random() * 800 * (Math.random() * 2 > 1 ? 1 : -1);
      rand3d.z = Math.random() * 800 * (Math.random() * 2 > 1 ? 1 : -1);
      var newZoom:int = Math.ceil(Math.random() * 13);
      var newFocus:int = Math.ceil(Math.random() * 500);
      Tweener.addTween(camera, {
      x:rand3d.x, y:rand3d.y, z:rand3d.z, zoom:newZoom, focus:newFocus,
      time:1, transition:"easeOutSine"
                  });
    }

    private function loop(e:Event):void
    {
      camera.x += -(stage.stageWidth / 2 - stage.mouseX) / 64;
      camera.y += (stage.stageHeight / 2 - stage.mouseY) / 64;

      var color:Number = hsvToRGB(baseHue, 100, 100);
      baseHue += .2;
      var grf:GlowFilter = new GlowFilter(color, 0.5, 32, 32, 8, 1, false);
      filterdBm.lock();
      filterdBm.fillRect(filterdBm.rect, 0);
      filterdBm.draw(effectBm);
      filterdBm.applyFilter(filterdBm, filterdBm.rect, new Point(0,0), grf);
      filterdBm.unlock();

      var item:Plane;
      var i:int = 0;
      while(item = scene.getChildByName('point'+ i) as Plane)
      {
        item.lookAt(camera);
        item.x += item.extra.vx;
        item.y += item.extra.vy;
        item.z += item.extra.vz;
        if(item.x < -800)
        {
          item.x = -800;
          item.extra.vx *= -1;
        }
        else if(item.x > 800)
        {
          item.x = 800;
          item.extra.vx *= -1;
        }
        if(item.y < -800)
        {
          item.y = -800;
          item.extra.vy *= -1;
        }
        else if(item.y > 800)
        {
          item.y = 800;
          item.extra.vy *= -1;
        }
        if(item.z < -800)
        {
          item.z = -800;
          item.extra.vz *= -1;
        }
        else if(item.z > 800)
        {
          item.z = 800;
          item.extra.vz *= -1;
        }
        i++;
      }

      scene.renderCamera(camera);
    }

    private function hsvToRGB(hue:Number,saturation:Number,value:Number):uint
    {
      //H: 0-360, S: 0-100, V: 0-100
      hue = (hue < 0) ? (hue % 360 + 360) : ((hue >= 360) ? (hue % 360) : hue);
      saturation = (saturation < 0) ? 0 : ((saturation > 100) ? 100 : saturation);
      value = (value < 0) ? 0 : ((value > 100) ? 100 : value);
      var s:Number = saturation / 100;
      var v:Number = value /100;
      var rgb:uint;
      var r:Number,g:Number,b:Number;
      var f:Number,p:Number,q:Number,t:Number;

      if(s == 0)
      {
        r = g = b = v;
      }
      else
      {
        var h1:Number = Math.floor(hue / 60) % 6;
        f = (hue / 60) - h1;
        p = v * (1 - s);
        q = v * (1 - f * s);
        t = v * (1 - (1 - f) * s);

        switch(h1)
        {
          case 0:
          r = v; g = t; b = 0;
          break;
          case 1:
          r = q; g = v; b = p;
          break;
          case 2:
          r = p; g = v; b = t;
          break;
          case 3:
          r = p; g = q; b = v;
          break;
          case 4:
          r = t; g = p; b = v;
          break;
          default: //case 5
          r = v; g = p; b = q;
          break;
        }
      }

      r = Math.round( r * 255);
      g = Math.round( g * 255);
      b = Math.round( b * 255);

      rgb = (r << 16) + (g << 8 ) + b;
      return rgb;
    }
  }
}

LINEで送る
Pocket

自作iPhoneアプリ 好評発売中!
フォルメモ - シンプルなフォルダつきメモ帳
ジッピー電卓 - 消費税や割引もサクサク計算!

ページトップへ戻る