In case Flash no longer exists; a copy of this site is included in the Flashpoint archive's "ultimate" collection.

Dead Code Preservation :: Archived AS3 works from wonderfl.net

shadow[PV3D]

セルフシャドウ

ほんとは影をグルグルまわしたかったけど生成が重い。
Get Adobe Flash player
by kuma360 05 Sep 2010
    Embed
/**
 * Copyright kuma360 ( http://wonderfl.net/user/kuma360 )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/uShh
 */

package {
    
    import flash.display.*;
    import flash.events.*;
    import flash.filters.*;
    import flash.geom.*;
    import flash.media.*;
    import flash.net.*;
    import flash.system.*;
    import flash.utils.*;
    import org.papervision3d.core.geom.renderables.*;
    import org.papervision3d.core.math.*;
    import org.papervision3d.materials.*;
    import org.papervision3d.objects.primitives.*;
    import org.papervision3d.view.*;
    
    [SWF(width = "465", height = "465", frameRate = "60", backgroundColor = "#000000")]
    public class Main extends BasicView {
        
        private var BD:BitmapData = new BitmapData ( 200 , 200 , false , 0 ) ;
        private var TEX:BitmapData = new BitmapData ( 200 , 200 , false , 0 ) ;
        private var P:Plane ;
        public function Main() {
            
            //地面
            var M:BitmapMaterial = new BitmapMaterial ( TEX , true ) ;
            P = new Plane ( M , 100 , 100 , MAX , MAX ) ;
            scene.addChild ( P ) ;
            P.rotationX = 90 ;
            
            Create( ) ;
            
            camera.x = 30 ;
            camera.y = 70 ;
            camera.z = - 40 ;
            startRendering() ;
            
            stage.addEventListener (
                MouseEvent.CLICK ,
                function ( ) :void {
                    Create ( ) ;
                }
            );
            
        }
        
        
        
        public function Create ( ) :void {
            
            //ポリゴンに凹凸を作る
            var TF:Triangle3D ;
            var TV:Vertex3D ;
            
            var NNN:Number = 20 ;
            for each ( TV in P.geometry.vertices ) {
                TV.z = 40 ;
            }
            
            for ( var II:int = 0 ; II < 10 ; ++ II ) {
                TV = P.geometry.vertices [ Math.floor ( Math.random ( ) * MAX * MAX ) ] ;
                TV.z = Math.random ( ) * 35 ;
            }
            
            for each ( TF in P.geometry.faces ) {
                TF.createNormal () ;
            }
            
            for each ( TV in P.geometry.vertices ) {
                TV.calculateNormal () ;
            }
            
            
            
            //テクスチャに凹凸の高さを書き込む
            for ( var X:int = 0 ; X < BD.width ; ++ X ) {
                
                for ( var Y:int = 0 ; Y < BD.height ; ++ Y ) {
                    
                    var TX:int = ( X ) * MAX / BD.width  ;
                    var TY:int = ( BD.height - Y ) * MAX / BD.height ;
                    TY *= 2 ;
                    if ( X % ( BD.width / MAX ) >= Y % ( BD.height / MAX ) ) {
                        TY += 1 ;
                    }
                    
                    var I:int = TX * ( MAX * 2 ) + TY ;
                    TF = P.geometry.faces[ I ] as Triangle3D ;
                    
                    if ( TF ) {
                        
                        var N:Number3D  = TF.faceNormal ;
                        var P0:Vertex3D = TF.v0 ;
                        var RX:Number = X * 100 / BD.width  - 50 ;
                        var RY:Number = ( BD.height - Y ) * 100 / BD.height - 50 ;
                        var Z:Number = - ( N.x * ( RX - P0.x ) + N.y * ( RY - P0.y ) ) / N.z + P0.z ;
                        
                        if ( 0 < Z ) {
                            BD.setPixel ( X , Y , 255 - Z ) ;
                        } else {
                            BD.setPixel ( X , Y , 0 ) ;
                        }
                        
                    }
                    
                }
                
            }
            
            
            //影を作る
            for ( X = 0 ; X < TEX.width ; ++ X ) {
                
                for ( Y = 0 ; Y < TEX.height ; ++ Y ) {
                    
                    TX = X * BD.width / TEX.width ;
                    TY = Y * BD.width / TEX.width ;
                    var D1:uint = BD.getPixel ( TX , TY ) ;
                    
                    //ライト方向をチェック ( 簡易 )
                    var LCHK:Boolean = true ;
                    for ( var LX:int = TX ; LX < BD.width ; LX ++ ) {
                        
                        var D2:uint = BD.getPixel ( LX , TY ) ;
                        if ( D1 + 1/3 * ( LX - TX ) < D2 ) {
                            LCHK = false ;
                            break ;
                        }
                        
                    }
                    
                    
                    if ( LCHK ) {
                        TEX.setPixel32 ( X , Y , 0xFFFF6050 ) ;
                    } else {
                        TEX.setPixel32 ( X , Y , 0xFF403020 ) ;
                    }
                    
                }
                
            }
            
            //ごまかし & ソフトシャドウ
            TEX.applyFilter ( TEX , TEX.rect , new Point , new BlurFilter ( 8, 8 , 2 ) ) ;
            
        }
        
        override protected function onRenderTick(event:Event = null):void 
        {
            super.onRenderTick ( event ) ;
            
            camera.x = Math.cos ( getTimer() * 0.001 ) * 100 ;
            camera.z = Math.sin ( getTimer() * 0.001 ) * 100 ;
            
        }
        
    }
    
}


const MAX:int = 15 ;