スポンサーサイト

-------- | --:--

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

PV3Dで人型ロボット2

2008-01-26 | 18:12

マウスクリックで屈伸運動。
package {
    import flash.display.*;
    import flash.events.*;

    import org.papervision3d.core.*;
    import org.papervision3d.core.geom.*;
    import org.papervision3d.core.math.*;
    import org.papervision3d.scenes.* ;
    import org.papervision3d.objects.*;
    import org.papervision3d.objects.primitives.*;
    import org.papervision3d.cameras.*;
    import org.papervision3d.materials.*;
    import org.papervision3d.materials.shadematerials.* ;
    import org.papervision3d.materials.utils.*;
    import org.papervision3d.view.*;
    import org.papervision3d.render.*;
    import org.papervision3d.lights.*;
    import org.papervision3d.materials.special.LineMaterial ;

    import caurina.transitions.Tweener;

    [SWF(width="600", height="400", frameRate="10", backgroundColor="#ffffff")]
        public class Robot6 extends Sprite{
            private var renderer:BasicRenderEngine = new BasicRenderEngine();
            private var viewport:Viewport3D = new Viewport3D(600, 800, false, true);
            private var scene:Scene3D = new Scene3D();
            private var camera:FreeCamera3D = new FreeCamera3D();
            private var pointLight:PointLight3D;

            private var lines:Array = null;

            private    var leftArm2:LinkFrame;
            private    var leftArm:LinkFrame;
            private    var rightArm2:LinkFrame;
            private    var rightArm:LinkFrame;
            private    var body:LinkFrame;
            private    var head:LinkFrame;
            private    var waist:LinkFrame;

            private    var leftLeg2:LinkFrame;
            private    var leftLeg:LinkFrame;
            private    var rightLeg2:LinkFrame;
            private    var rightLeg:LinkFrame;

            private var W:int = 600;
            private var H:int = 400;

            public function Robot6():void
            {
                stage.align = StageAlign.TOP_LEFT ;
                stage.scaleMode = StageScaleMode.NO_SCALE;

                addChild(viewport);

                camera.y = -300;
                camera.z = -500;
                camera.x = 0;
                camera.focus = 1100;
                camera.zoom = 1;

                pointLight = new PointLight3D();
                pointLight.y = 300;
                pointLight.z = -100;

                createBody();

                renderer.renderScene(scene, camera, viewport);

                stage.addEventListener(KeyboardEvent.KEY_DOWN, keydown);
                stage.addEventListener(MouseEvent.MOUSE_DOWN, onClick);
            }

            private function onClick(e:MouseEvent):void{
                var t:Number = 2;
                Tweener.addTween(leftArm2, 
                        {rx:Math.PI/2, time:t, onUpdate: updateAndRender, transition:"easeOutBack"});
                Tweener.addTween(rightArm2, 
                        {rx:Math.PI/2, time:t, onUpdate: updateAndRender, transition:"easeOutBack"});
                Tweener.addTween(body, {rx:-Math.PI/2, time:t, 
                        transition:"easeOutBack",
                        onUpdate: updateAndRender, 
                        onComplete:pose1});
            }

            private function pose1():void{
                var t:Number = 3;
                Tweener.addTween(leftArm2, 
                        {rx:Math.PI, time:t, onUpdate: updateAndRender, transition:"easeOutBack"});
                Tweener.addTween(leftArm, 
                        {rx:0.3, time:t, onUpdate: updateAndRender, transition:"easeOutBack"});
                Tweener.addTween(rightArm2, 
                        {rx:Math.PI, time:t, onUpdate: updateAndRender, transition:"easeOutBack"});
                Tweener.addTween(rightArm, 
                        {rx:0.3, time:t, onUpdate: updateAndRender, transition:"easeOutBack"});
                Tweener.addTween(body, {rx:1, time:t, 
                        transition:"easeOutBack",
                        onUpdate: updateAndRender, 
                        onComplete:pose2});
            }
            private function pose2():void{
                Tweener.addTween(leftArm2, 
                        {rx:0, time:1, onUpdate: updateAndRender, transition:"easeOutBack"});
                Tweener.addTween(rightArm2, 
                        {rx:0, time:1, onUpdate: updateAndRender, transition:"easeOutBack"});
                Tweener.addTween(body, {rx:0, time:1, 
                        transition:"easeOutBack",
                        onUpdate: updateAndRender});
            }

            private function updateAndRender():void{
                waist.update();
                renderer.renderScene(scene, camera, viewport);
            }

            private function createBody():void{
                var param:Object = {};
                param.legWidth2 = 50;
                param.legWidth = 40;
                param.legLen2 = 120;
                param.legLen = 120;

                waist = new LinkFrame(scene,
                            new Cube(new MaterialsList({
                           all:new PhongMaterial(pointLight, 0x88ffff, 0x111111, 1)} ), 120, 50, 60));
                waist.direction = new Number3D(0, -1, 0);
                waist.len = 60;

                body= new LinkFrame(scene,
                        new Cube(new MaterialsList(
                                {all:new PhongMaterial(pointLight, 0x88ffff, 0x111111, 1)} ), 120, 50, 140));
                body.len = 140;
                body.offset = new Number3D(0, 0, 0);
                body.direction = new Number3D(0, 1, 0);
                body.ryMax = Math.PI *(1/3);
                body.ryMin = -Math.PI * (1/3);
                body.rxMax = Math.PI /2;
                body.rxMin = -Math.PI /2;
                waist.addChild(body);

                head = new LinkFrame(scene,
                            new Cube(new MaterialsList({
                           all:new PhongMaterial(pointLight, 0x88ffff, 0x111111, 1)} ), 50, 30, 60));
                head.len = 60;
                head.offset = new Number3D(0, body.len, 0);
                head.direction = new Number3D(0, 1, 0);
                body.addChild(head);

                leftArm2= new LinkFrame(scene,
                            new Cube(new MaterialsList({
                           all:new PhongMaterial(pointLight, 0x88ffff, 0x111111, 1)} ), 30, 30, 100));
                leftArm2.len = 100;
                leftArm2.offset = new Number3D(75, body.len, 0);
                leftArm2.direction = new Number3D(0, -1, 0);
                leftArm2.rxMax = Math.PI ;
                leftArm2.rxMin = -Math.PI /2;
                body.addChild(leftArm2);
                
                leftArm= new LinkFrame(scene,
                            new Cube(new MaterialsList({
                           all:new PhongMaterial(pointLight, 0x88ffff, 0x111111, 1)} ), 30, 30, 100));
                leftArm.len = 100;
                leftArm.offset = new Number3D(0, -100, 0);
                leftArm.direction = new Number3D(0, -1, 0);
                leftArm.rxMax = Math.PI ;
                leftArm2.addChild(leftArm);
               
                rightArm2= new LinkFrame(scene,
                            new Cube(new MaterialsList({
                           all:new PhongMaterial(pointLight, 0x88ffff, 0x111111, 1)} ), 30, 30, 100));
                rightArm2.len = 100;
                rightArm2.offset = new Number3D(-75, body.len, 0);
                rightArm2.direction = new Number3D(0, -1, 0);
                rightArm2.rxMax = Math.PI ;
                rightArm2.rxMin = -Math.PI /2;
                body.addChild(rightArm2);
                
                rightArm= new LinkFrame(scene,
                            new Cube(new MaterialsList({
                           all:new PhongMaterial(pointLight, 0x88ffff, 0x111111, 1)} ), 30, 30, 100));
                rightArm.len = 100;
                rightArm.offset = new Number3D(0, -100, 0);
                rightArm.direction = new Number3D(0, -1, 0);
                rightArm.rxMax = Math.PI ;
                rightArm2.addChild(rightArm);

                leftLeg2= new LinkFrame(scene,
                            new Cube(new MaterialsList({
                           all:new PhongMaterial(pointLight, 0x88ffff, 0x111111, 1)} ), 
                                param.legWidth2, param.legWidth2, param.legLen2));
                leftLeg2.len = param.legLen;
                leftLeg2.offset = new Number3D(param.legWidth2/2 + 10, -waist.len, 0);
                leftLeg2.direction = new Number3D(0, -1, 0);
                leftLeg2.rxMax = Math.PI /2;
                leftLeg2.rxMin = -Math.PI /2;
                waist.addChild(leftLeg2);
                
                leftLeg= new LinkFrame(scene,
                            new Cube(new MaterialsList({
                           all:new PhongMaterial(pointLight, 0x88ffff, 0x111111, 1)} ), 
                                param.legWidth, param.legWidth, param.legLen));
                leftLeg.len = param.legLen;
                leftLeg.offset = new Number3D(0, -param.legLen2, 0);
                leftLeg.direction = new Number3D(0, -1, 0);
                leftLeg.rxMax = 0;
                leftLeg.rxMin = -Math.PI /2;
                leftLeg2.addChild(leftLeg);
               
                rightLeg2= new LinkFrame(scene,
                            new Cube(new MaterialsList({
                           all:new PhongMaterial(pointLight, 0x88ffff, 0x111111, 1)} ), 
                                param.legWidth2, param.legWidth2, param.legLen2));
                rightLeg2.len = param.legLen2;
                rightLeg2.offset = new Number3D(-param.legWidth2/2 - 10, -waist.len, 0);
                rightLeg2.direction = new Number3D(0, -1, 0);
                rightLeg2.rxMax = Math.PI /2;
                rightLeg2.rxMin = -Math.PI /2;
                waist.addChild(rightLeg2);
                
                rightLeg= new LinkFrame(scene,
                            new Cube(new MaterialsList({
                           all:new PhongMaterial(pointLight, 0x88ffff, 0x111111, 1)} ), 
                                param.legWidth, param.legWidth, param.legLen));
                rightLeg.len = param.legLen;
                rightLeg.offset = new Number3D(0, -param.legLen2, 0);
                rightLeg.direction = new Number3D(0, -1, 0);
                rightLeg.rxMax = 0;
                rightLeg.rxMin = -Math.PI /2;
                rightLeg2.addChild(rightLeg);

                renderer.renderScene(scene, camera, viewport);


                waist.update();
            }

            private function keydown(e:KeyboardEvent):void{

                switch (e.keyCode){
                    case 37 :// ←
                        body.ry += 0.1;
                        break;
                    case 39 :// →
                        body.ry -= 0.1;
                        break;
                    case 38 :// ↑
                        body.rx += 0.1;
                        break;
                    case 40 :// ↓
                        body.rx -= 0.1;
                        break;
                    case 65 :// A
                        leftArm2.rx += 0.1;
                        break;
                    case 83 :// S
                        leftArm.rx += 0.1;
                        break;
                    case 68 :// D
                        leftLeg2.rx += 0.1;
                        break;
                    case 70 :// F
                        leftLeg.rx += 0.1;
                        break;
                    case 81 :// Q
                        leftArm2.rx -= 0.1;
                        break;
                    case 87 :// W
                        leftArm.rx -= 0.1;
                        break;
                    case 69 :// E
                        leftLeg2.rx -= 0.1;
                        break;
                    case 82 :// R
                        leftLeg.rx -= 0.1;
                        break;
                    case 72 :// H
                        rightArm2.rx += 0.1;
                        break;
                    case 74 :// J
                        rightArm.rx += 0.1;
                        break;
                    case 75 :// K
                        rightLeg2.rx += 0.1;
                        break;
                    case 76 :// L
                        rightLeg.rx += 0.1;
                        break;
                    case 89 :// Y
                        rightArm2.rx -= 0.1;
                        break;
                    case 85 :// U
                        rightArm.rx -= 0.1;
                        break;
                    case 73 :// I
                        rightLeg2.rx -= 0.1;
                        break;
                    case 79 :// O
                        rightLeg.rx -= 0.1;
                        break;
                }
                waist.update();
                renderer.renderScene(scene, camera, viewport);
            }
        }
}

import org.papervision3d.objects.*;
import org.papervision3d.objects.primitives.*;
import org.papervision3d.scenes.* ;
import org.papervision3d.core.geom.*;
import org.papervision3d.core.math.*;
import org.papervision3d.materials.*;
import org.papervision3d.materials.shadematerials.* ;
import org.papervision3d.materials.special.LineMaterial ;
import org.papervision3d.materials.utils.* ;
internal class LinkFrame{
    public var center:Sphere;
    private var lines:Array = null;
    private var scene:Scene3D;

    // 前のフレームに対する回転角
    private var _rx:Number = 0;
    private var _ry:Number = 0;
    private var _rz:Number = 0;

    public var rxMax:Number = 0;
    public var rxMin:Number = 0;
    public var ryMax:Number = 0;
    public var ryMin:Number = 0;
    public var rzMax:Number = 0;
    public var rzMin:Number = 0;

    // 前のフレームからのオフセット
    public var offset:Number3D = new Number3D(0,0,0);;
    // フレームの中心を基準にしたアームの方向
    public var direction:Number3D = new Number3D(0,0,0);;
    private var arm:DisplayObject3D;

    public var len:int = 100;

    private var children:Array = [];
    public var parent:LinkFrame = null;

    public function LinkFrame(scene:Scene3D ,arm:DisplayObject3D=null){
        this.scene = scene;
        var greenwire:WireframeMaterial = new WireframeMaterial( 0xff00 );
        center = new Sphere(new ColorMaterial(0xff), 5);
        scene.addChild(center);

        if(arm != null){
            scene.addChild(arm);    
            this.arm = arm;
        }

        drawFrame();
    }

    public function addChild(child:LinkFrame):void{
        this.children.push(child);
        child.parent = this;
    }

    public function update():void{

        var mx:Matrix3D = Matrix3D.rotationMatrix(1,0,0,_rx);
        var my:Matrix3D = Matrix3D.rotationMatrix(0,1,0,_ry);
        var mz:Matrix3D = Matrix3D.rotationMatrix(0,0,1,_rz);

        var tr:Matrix3D = Matrix3D.translationMatrix (offset.x,offset.y,offset.z);

        var m:Matrix3D = Matrix3D.multiply(mx,my);
        m = Matrix3D.multiply(m, mz);
        m = Matrix3D.multiply(tr, m);

        // 前のフレームの姿勢行列 x 前のフレームに対する姿勢行列 = ワールド座標に対する姿勢行列
        if(parent != null)
            center.transform = Matrix3D.multiply( parent.center.transform, m);
        else
            center.transform = m;
        trace(center.y);
        arm.transform = Matrix3D.clone(center.transform);

        var dir:Number3D = direction.clone();
        // 姿勢行列の回転部分だけを取り出す
        var md:Matrix3D = Matrix3D.clone(arm.transform);
        md.n14 = md.n24 = md.n34 = 0;
        // アームの方向を求めて位置を調整
        Matrix3D.rotateAxis(md, dir);
        arm.x += dir.x*len/2;
        arm.y += dir.y*len/2;
        arm.z += dir.z*len/2;

        drawFrame();

        for each(var child:LinkFrame in children)
            child.update();
    }

    public function drawFrame():void{
        return ; // for debugging
        var llen:int = 100;
        if(lines != null){
            for each(var l:Lines3D in lines){
                scene.removeChild(l);
            }
        }
        lines = [];

        var m:Matrix3D = center.transform;
        var xl:Lines3D = new Lines3D(new LineMaterial());
        scene.addChild(xl);
        xl.addNewLine(1, center.x,center.y,center.z,
                center.x + m.n11*llen, center.y + m.n21*llen , center.z + m.n31*llen );
        lines.push(xl);

        var yl:Lines3D =  new Lines3D(new LineMaterial(0xff));
        scene.addChild(yl);
        yl.addNewLine(1, center.x ,center.y,center.z,
                center.x + m.n12*llen , center.y + m.n22*llen , center.z + m.n32*llen);
        lines.push(yl);

        var zl:Lines3D = new Lines3D(new LineMaterial(0xff00));
        scene.addChild (zl);
        zl.addNewLine(1, center.x,center.y ,center.z,
                center.x + m.n13*llen, center.y + m.n23*llen , center.z + m.n33*llen);
        lines.push(zl);

        var dir:Number3D = direction.clone();
        var md:Matrix3D = Matrix3D.clone(arm.transform);
        md.n14 = md.n24 = md.n34 = 0;
        Matrix3D.rotateAxis(md, dir);
        var dl:Lines3D = new Lines3D(new LineMaterial(0x0));
        scene.addChild (dl);
        dl.addNewLine(1, center.x,center.y ,center.z,
                center.x + dir.x*llen, center.y + dir.y*llen , center.z + dir.z*llen);
        lines.push(dl);
    }

    public function set rx(v:Number):void{
        if(v >= rxMin && v <= rxMax)
            _rx = v;
    }
    public function get rx():Number{
            return _rx;
    }
    public function set ry(v:Number):void{
        if(v >= ryMin && v <= ryMax)
            _ry = v;
    }
    public function get ry():Number{
            return _ry;
    }
    public function set rz(v:Number):void{
        if(v >= rzMin && v <= rzMax)
            _rz = v;
    }
    public function get rz():Number{
            return _rz;
    }
}
スポンサーサイト

Comment

Post a comment

Secret

上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。