PV3D もねもねもねね

by toyoshim
-----------------------------------------------------------
* 激しく未完成
*-----------------------------------------------------------
*
* 以下は完了済み
*  1. traceを使う実験
*  2. 外部サイトからデータを読み込む実験
*  3. 頂点データを解析する実験
*  4. Particleで表示する実験
*  5. アニメーションさせる実験(補間なし)
*  6. ワイヤフレームで表示する実験
*  7. ポリゴンで表示する実験
* 以下は未解決
*  8. テクスチャを張る実験
*  9. アニメーションさせる実験(補間あり)
*-----------------------------------------------------------
♥0 | Line 226 | Modified 2009-08-20 02:25:17 | MIT License
play

ActionScript3 source code

/**
 * Copyright toyoshim ( http://wonderfl.net/user/toyoshim )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/jSSx
 */

/*
 *-----------------------------------------------------------
 * 激しく未完成
 *-----------------------------------------------------------
 *
 * 以下は完了済み
 *  1. traceを使う実験
 *  2. 外部サイトからデータを読み込む実験
 *  3. 頂点データを解析する実験
 *  4. Particleで表示する実験
 *  5. アニメーションさせる実験(補間なし)
 *  6. ワイヤフレームで表示する実験
 *  7. ポリゴンで表示する実験
 * 以下は未解決
 *  8. テクスチャを張る実験
 *  9. アニメーションさせる実験(補間あり)
 *-----------------------------------------------------------
 */

package {
    import flash.display.*;
    import flash.net.*;
    import flash.events.*;

    import org.papervision3d.view.*;
    import org.papervision3d.objects.*;
    import org.papervision3d.objects.primitives.*;
    import org.papervision3d.core.geom.*;
    import org.papervision3d.core.effects.view.*;
    import net.hires.debug.Stats;
    
    [SWF(backgroundColor="#000000")]

    public class FlashTest extends ReflectionView {
        private var urlMone  : String = "http://wonderfl.toyoshima-house.net/CDIMAGE04060.BIN";
        private var loader   : URLLoader;
        private var mone     : PS2Icon;
        private var rootNode : DisplayObject3D;

        public function FlashTest() {
            // 初期化
            stage.frameRate = 30;
            setReflectionColor(0.3, 0.1, 0.1, 0.1, 0.1, 0.1);
            rootNode = new DisplayObject3D();
            scene.addChild(rootNode);

            // カメラ設定
            camera.z = -300;
            camera.focus = 10;
            camera.zoom = 20;

            // デバッグ情報
            stage.addChild(new Stats()); 

            // データ読み込み
            loader = new URLLoader();
            loader.dataFormat = URLLoaderDataFormat.BINARY;
            loader.load(new URLRequest(urlMone));
            trace("loading mone...");
            loader.addEventListener(Event.COMPLETE, moneLoadDone);
        }
        
        private function moneLoadDone(event: Event): void {
            // 読み込み完了・表示
            trace("done: " + loader.bytesTotal + " bytes (" + loader.dataFormat + ")");
            mone = new PS2Icon();
            mone.load(loader.data);
//            rootNode.addChild(mone.particles);
//            rootNode.addChild(mone.wireframes);
            rootNode.addChild(mone.mesh);

            // イベント登録
            stage.addEventListener(Event.ENTER_FRAME, draw);
        }
        
        private function draw(event: Event): void {
            camera.x = -232.5 + mouseX;
            camera.y =  232.5 - mouseY;
            
//            mone.animeVertices();
//            mone.animeLines();
            mone.animeMesh();

            // 描画
            singleRender();
        }
    }
}

import flash.utils.*;
import org.papervision3d.objects.*;
import org.papervision3d.core.math.*;
import org.papervision3d.core.proto.*;
import org.papervision3d.core.geom.*;
import org.papervision3d.core.geom.renderables.*;
import org.papervision3d.materials.*;
import org.papervision3d.materials.special.*;

class PS2Icon {
    public  var particles    : Particles;
    public  var wireframes   : Lines3D;
    public  var mesh         : DisplayObject3D;
    
    private var vertices     : Array;
    private var faces        : Array;
    private var meshes       : Array;
    private var cur_vertices : Array;
    private var cur_faces    : Array;
    private var n_shapes     : int;
    private var n_vertices   : int;

    private var frame        : int;
    
    public function PS2Icon () {
    }
        
    public function load (data: ByteArray): Boolean {
        // データ初期化
        data.endian = "littleEndian";
        frame = 0;
        
        // ヘッダチェック
        if (0x00010000 != data.readInt()) {
            trace("invalid header");
            return false;
        }
        
        // 頂点読み込み
        if (!loadVertices(data)) {
            trace("vertices error");
            return false;
        }
        if (!loadLines()) {
            trace("lines error");
            return false;
        }
        return loadMesh();
    }
    
    public function loadVertices (data: ByteArray): Boolean {
        particles = new Particles();

        var material     : ParticleMaterial = new ParticleMaterial(0x4444ff, 1);
        var n_attributes : int;
        var n_back_faces : Number;

        n_shapes     = data.readInt();
        n_attributes = data.readInt();
        n_back_faces = data.readFloat();
        n_vertices   = data.readInt();

        trace("shapes: " + n_shapes);
        trace("attr.s: " + n_attributes);
        trace("faces : " + n_back_faces);
        trace("vertex: " + n_vertices);

        vertices     = new Array(n_shapes);
        faces        = new Array(n_shapes);
        mesh         = new DisplayObject3D();

        var i : int;
        var j : int;
        var n : int = n_vertices / 3;
        var m : int;
        for (i = 0; i < n_shapes; i++) {
            vertices[i]  = new Array(n);
            faces[i]     = new Array(n);
            cur_vertices = new Array(n);
            cur_faces    = new Array(n);
            for (j = 0; j < n; j++) {
                vertices[i][j]  = new Array(3);
                faces[i][j]     = new Array(1);
                cur_vertices[j] = new Array(3);
                cur_faces[j]    = new Array(1);
            }
        }
        
        for (i = 0; i < n_vertices; i++) {
            n = i / 3;
            m = i % 3;
            for (j = 0; j < n_shapes; j++) {
                vertices[j][n][m] = new Vertex3D(data.readShort() /  100.0,
                                                 data.readShort() / -100.0,
                                                 data.readShort() /  100.0);
                data.readShort(); // null
                if (2 == m) {
                    faces[j][n][0] = new Triangle3D(mesh, vertices[j][n]);
                }
                if (0 != j) continue;
                cur_vertices[n][m] = vertices[0][n][m];
                if (2 == m) {
                    cur_faces[n] = faces[0][n];
                }

                particles.addParticle(new Particle(material,
                                                   1,
                                                   cur_vertices[n][m].x,
                                                   cur_vertices[n][m].y,
                                                   cur_vertices[n][m].z));
                //trace(shapes[j][n][m].toString());
            }
            data.readShort(); // norm.x
            data.readShort(); // norm.y
            data.readShort(); // norm.z
            data.readShort(); // null
            data.readShort(); // texture x
            data.readShort(); // texture y
            data.readInt();   // color
        }
        trace("load vertices done.");
        return true;
    }
    
    public function loadLines (): Boolean {
        wireframes = new Lines3D();

        var material : LineMaterial = new LineMaterial(0x4444ff, 1);
        for (var i : int = 0; i < n_vertices; i++) {
            var k : int = i / 3;
            var n : int = i % 3;
            var m : int = (n + 1) % 3;
            var line : Line3D = new Line3D(null,
                                           material,
                                           1,
                                           cur_vertices[k][n],
                                           cur_vertices[k][m]);
            wireframes.addLine(line);
        }
        trace("load wireframes done.");
        return true;
    }
    
    public function loadMesh (): Boolean {
        var material : ColorMaterial = new ColorMaterial(0x4444ff, .9);
		var n : int = n_vertices / 3;
		meshes = new Array(n_shapes);
		for (var i : int = 0; i < n_shapes; i++) {
			meshes[i] = new DisplayObject3D();
			for (var j : int = 0; j < n; j++) {
				meshes[i].addChild(new TriangleMesh3D(material, vertices[i][j], faces[i][j]));
			}
		}
		mesh.addChild(meshes[0]);
        trace("load mesh done.");
        return true;
    }
    
    public function animeVertices (): void {
        frame++;
        var k : int = frame >> 2;
        if (k >= n_shapes) {
            frame = 0;
            k = 0;
        }
        for (var i : int = 0; i < n_vertices; i++) {
            var n : int = i / 3;
            var m : int = i % 3;
            particles.particles[i].x = vertices[k][n][m].x;
            particles.particles[i].y = vertices[k][n][m].y;
            particles.particles[i].z = vertices[k][n][m].z;
        }
    }

    public function animeLines (): void {
        frame++;
        var k : int = frame >> 2;
        if (k >= n_shapes) {
            frame = 0;
            k = 0;
        }
        for (var i : int = 0; i < n_vertices; i++) {
            var l : int = i / 3;
            var m : int = i % 3;
            var n : int = (m + 1) % 3;
            wireframes.lines[i].v0.x = vertices[k][l][m].x;
            wireframes.lines[i].v0.y = vertices[k][l][m].y;
            wireframes.lines[i].v0.z = vertices[k][l][m].z;
            wireframes.lines[i].v1.x = vertices[k][l][n].x;
            wireframes.lines[i].v1.y = vertices[k][l][n].y;
            wireframes.lines[i].v1.z = vertices[k][l][n].z;
        }
    }
    
    public function animeMesh (): void {
        mesh.removeChild(meshes[frame >> 2]);
        frame++;
        var k : int = frame >> 2;
        if (k >= n_shapes) {
            frame = 0;
            k = 0;
        }
        mesh.addChild(meshes[k]);
    }
}

Forked