Hi,
well quite not far from success (optimistic...)
here is the process:

>>>we create a CenterLightingMaterialCache instance that implement IUVMaterial:
var backer:CenterLightingMaterialCache = new
CenterLightingMaterialCache
(sourceObj:Mesh,bitmap:BitmapData,view:View3D,directional:DirectionalLight3D,init:Object=null)

Mesh: the object we'll work with (only use it's geometry);
bitmap:the bitmapdata that will be used to render the shader, can be
any bitmapdata
the view: the view ...
directionnalLight: a light (here directionnal)

>>>then we call:
backer.renderBacker();

for each of the faces of the mesh, we create a new DrawTriangle and
calculate some values according to the light/geometry and pass it to
the drawTriangle
and call a "renderTri" like method :
renderTriBacked
(tri:DrawTriangle,session:AbstractRenderSession,kar:Number,kag:Number,kab:Number,kdr:Number,kdg:Number,kdb:Number,ksr:Number,ksg:Number,ksb:Number,smooth:Boolean
= true,repeat:Boolean = false);
that will draw each drawtriangle in a sprite depending on uv.

>>>then we can use this sprite to draw a new bitmapdata and apply as prebacked 
>>>material.

var btm:BitmapData = new BitmapData
(backer._mapCache.width,backer._mapCache.height) ;
btm.draw(backer._mapCache.height);

that's all !

but I'm really having some trouble, here they are:

line 193 -196 : I need to had a light in the lightArray of the
sourceMesh in order to calculate the line 307 loop.
line 503 -548 : they must be a prettier way to draw that with face or
draw primitive coords.
thay are also a lot of ugly things but it's a work in process.

Fabrice, do you think I'm right and would you help me correct and
achieve ???






the class:

package away3d.materials{
        import away3d.arcane;
        import away3d.containers.*;
        import away3d.core.base.*;
        import away3d.core.draw.*;
        import away3d.core.light.*;
        import away3d.core.math.*;
        import away3d.core.render.*;
        import away3d.core.utils.*;
        import away3d.events.*;
        import away3d.lights.*;

        import flash.display.*;
        import flash.filters.*;
        import flash.events.*;
        import flash.utils.*;
        import flash.geom.*;

        use namespace arcane;

        /**
            * Abstract class for materials that calculate lighting for the
face's center
            * Not intended for direct use - use <code>ShadingColorMaterial</
code> or <code>WhiteShadingBitmapMaterial</code>.
            */
        public class CenterLightingMaterialCache extends EventDispatcher
implements IUVMaterial {
                /** @private */
                arcane var v0:ScreenVertex;
                /** @private */
                arcane var v1:ScreenVertex;
                /** @private */
                arcane var v2:ScreenVertex;
                /** @private */
                arcane var session:AbstractRenderSession;
                /** @private */
                arcane function notifyMaterialUpdate():void {
                        _materialDirty=false;

                        if (! hasEventListener(MaterialEvent.MATERIAL_UPDATED)) 
{
                                return;
                        }

                        if (_materialupdated==null) {
                                _materialupdated=new MaterialEvent
(MaterialEvent.MATERIAL_UPDATED,this);
                        }

                        dispatchEvent(_materialupdated);
                }

                private var point:PointLight;
                private var directional:DirectionalLight;
                private var global:AmbientLight;
                private var focus:Number;
                private var zoom:Number;
                private var v0x:Number;
                private var v0y:Number;
                private var v0z:Number;
                private var v1x:Number;
                private var v1y:Number;
                private var v1z:Number;
                private var v2x:Number;
                private var v2y:Number;
                private var v2z:Number;
                private var d1x:Number;
                private var d1y:Number;
                private var d1z:Number;
                private var d2x:Number;
                private var d2y:Number;
                private var d2z:Number;
                private var pa:Number;
                private var pb:Number;
                private var pc:Number;
                private var pdd:Number;
                private var c0x:Number;
                private var c0y:Number;
                private var c0z:Number;
                private var kar:Number;
                private var kag:Number;
                private var kab:Number;
                private var kdr:Number;
                private var kdg:Number;
                private var kdb:Number;
                private var ksr:Number;
                private var ksg:Number;
                private var ksb:Number;
                private var red:Number;
                private var green:Number;
                private var blue:Number;
                private var dfx:Number;
                private var dfy:Number;
                private var dfz:Number;
                private var df:Number;
                private var nx:Number;
                private var ny:Number;
                private var nz:Number;
                private var fade:Number;
                private var amb:Number;
                private var nf:Number;
                private var diff:Number;
                private var rfx:Number;
                private var rfy:Number;
                private var rfz:Number;
                private var spec:Number;
                private var rf:Number;
                private var graphics:Graphics;
                private var cz:Number;
                private var cx:Number;
                private var cy:Number;
                private var ncz:Number;
                private var ncx:Number;
                private var ncy:Number;
                private var sum:Number;
                private var ffz:Number;
                private var ffx:Number;
                private var ffy:Number;
                private var fz:Number;
                private var fx:Number;
                private var fy:Number;
                private var rz:Number;
                private var rx:Number;
                private var ry:Number;
                private var draw_normal:Boolean=false;
                private var draw_fall:Boolean=false;
                private var draw_fall_k:Number=1;
                private var draw_reflect:Boolean=false;
                private var draw_reflect_k:Number=1;
                private var _diffuseTransform:Matrix3D;
                private var _specularTransform:Matrix3D;
                private var _viewPosition:Number3D;
                private var _source:Mesh;
                private var _view:View3D;
                private var _materialDirty:Boolean;
                private var _materialupdated:MaterialEvent;
                private var render:Boolean=true;
                //
                public var _mapCache:Sprite;
                private var _bitmap:BitmapData;
                private var colorTransform:ColorMatrixFilter = new 
ColorMatrixFilter
();
                private var cache:Dictionary=new Dictionary(true);
                private var step:int=1;
                private var mapping:Matrix;
                private var br:Number;
                private var _texturemapping:Matrix;
                private var _faceMaterialVO:FaceMaterialVO;
                private var _faceDictionary:Dictionary=new Dictionary(true);
                private var blackrender:Boolean;
                private var whiterender:Boolean;
                private var whitek:Number=0.2;
                private var bitmapPoint:Point=new Point(0,0);
                private var _light:DirectionalLight3D;

                private var session:AbstractRenderSession;
                private var i:int;

                /**
                        * Instance of the Init object used to hold and parse 
default
property values
                        * specified by the initialiser object in the 3d object
constructor.
                        */
                protected var ini:Init;

                /** @private */
                protected function renderTri
(tri:DrawTriangle,session:AbstractRenderSession,kar:Number,kag:Number,kab:Number,kdr:Number,kdg:Number,kdb:Number,ksr:Number,ksg:Number,ksb:Number):void
{
                        throw new Error("Not implemented");
                }

                /**
                        * Coefficient for ambient light level
                        */
                public var ambient_brightness:Number=1;

                /**
                        * Coefficient for diffuse light level
                        */
                public var diffuse_brightness:Number=1;

                /**
                        * Coefficient for specular light level
                        */
                public var specular_brightness:Number=1;

                /**
                        * Coefficient for shininess level
                        */
                public var shininess:Number=20;

                /**
                 * @private
                 */
                public function CenterLightingMaterialCache
(sourceObj:Mesh,bitmap:BitmapData,view:View3D,directional:DirectionalLight3D,init:Object=null)
{
                        ini=Init.parse(init);
                        _bitmap=bitmap;
                        _light=directional;
                        _source=sourceObj;
                        var directionalLight:DirectionalLight = new 
DirectionalLight();
                        directionalLight.light=_light;
                        _source.lightarray.directionals=new Array[_light  
];///read only
                        trace(_source.lightarray.directionals);

                        //_source.lightarray.directionalLight(directionalLight)
                        //_source.lightarray.directionals[0].light = _light;
                        _view=view;
                        _mapCache = new Sprite();

                        shininess=ini.getColor("shininess",20);
                }

                /**
                 * @inheritDoc
                 */
                public function 
updateMaterial(source:Object3D,view:View3D):void {
                        for each (directional in 
source.lightarray.directionals) {
                                if (! directional.diffuseTransform[source]||
view.scene.updatedObjects[source]) {
                                        directional.setDiffuseTransform(source);
                                        _materialDirty=true;
                                }

                                if (! directional.specularTransform[source]) {
                                        
directional.specularTransform[source]=new Dictionary(true);
                                }

                                if (! 
directional.specularTransform[source][view]||
view.scene.updatedObjects[source]||view.updated) {
                                        
directional.setSpecularTransform(source,view);
                                        _materialDirty=true;
                                }
                        }

                        for each (point in source.lightarray.points) {
                                if (! 
point.viewPositions[view]||view.scene.updatedObjects
[source]||view.updated) {
                                        point.setViewPosition(view);
                                        _materialDirty=true;
                                }
                        }

                        if (_materialDirty) {
                                clearFaces(source,view);
                        }
                }

                public function clearFaces
(source:Object3D=null,view:View3D=null):void {
                        notifyMaterialUpdate();
                }

                /**
                 * @inheritDoc
                 */
                public function renderBacker():void {//replace the 
tri:DrawTriangle
loop

                        trace(_source.faces.length);
                        for(i= 0;i<_source.faces.length;i++);
                        {
                                var faceDrawed:FaceVO=_source.faces[i].faceVO 
as FaceVO;

                                var tri:DrawTriangle=new DrawTriangle();
                                DrawPrimitive(tri).source=_source;
                                tri.faceVO=faceDrawed;
                                tri.uv0=faceDrawed.uv0;
                                tri.uv1=faceDrawed.uv1;
                                tri.uv2=faceDrawed.uv2;
                                tri.v0 = new ScreenVertex(faceDrawed.v0.x, 
faceDrawed.v0.y,
faceDrawed.v0.z);
                                tri.v1 = new ScreenVertex(faceDrawed.v1.x, 
faceDrawed.v1.y,
faceDrawed.v1.z);
                                tri.v2 = new ScreenVertex(faceDrawed.v2.x, 
faceDrawed.v2.y,
faceDrawed.v2.z);

                                session=tri.source.session;

                                v0=tri.v0;
                                v1=tri.v1;
                                v2=tri.v2;
                                focus=_view.camera.focus;
                                zoom=_view.camera.zoom;

                                v0x=v0.vx;
                                v0y=v0.vy;
                                v0z=v0.z;

                                v1x=v1.vx;
                                v1y=v1.vy;
                                v1z=v1.z;

                                v2x=v2.vx;
                                v2y=v2.vy;
                                v2z=v2.z;

                                d1x=v1x-v0x;
                                d1y=v1y-v0y;
                                d1z=v1z-v0z;

                                d2x=v2x-v0x;
                                d2y=v2y-v0y;
                                d2z=v2z-v0z;

                                pa=d1y*d2z-d1z*d2y;
                                pb=d1z*d2x-d1x*d2z;
                                pc=d1x*d2y-d1y*d2x;
                                pdd=Math.sqrt(pa*pa+pb*pb+pc*pc);

                                pa/=pdd;
                                pb/=pdd;
                                pc/=pdd;

                                c0x=v0x+v1x+v2x/3;
                                c0y=v0y+v1y+v2y/3;
                                c0z=v0z+v1z+v2z/3;

                                kar=kag=kab=kdr=kdg=kdb=ksr=ksg=ksb=0;

                                //_source=tri.source as Mesh;
                                //_view=tri.view;
                                for each (directional in 
tri.source.lightarray.directionals) {
                                        
_diffuseTransform=directional.diffuseTransform[_source];

                                        red=directional.red;
                                        green=directional.green;
                                        blue=directional.blue;

                                        dfx=_diffuseTransform.szx;
                                        dfy=_diffuseTransform.szy;
                                        dfz=_diffuseTransform.szz;

                                        nx=tri.faceVO.face.normal.x;
                                        ny=tri.faceVO.face.normal.y;
                                        nz=tri.faceVO.face.normal.z;

                                        
amb=directional.ambient*ambient_brightness;
                                        trace(amb);

                                        kar+=red*amb;
                                        kag+=green*amb;
                                        kab+=blue*amb;

                                        nf=dfx*nx+dfy*ny+dfz*nz;

                                        if (nf<0) {
                                                continue;
                                        }

                                        
diff=directional.diffuse*nf*diffuse_brightness;

                                        kdr+=red*diff;
                                        kdg+=green*diff;
                                        kdb+=blue*diff;

                                        
_specularTransform=directional.specularTransform[_source][_view];

                                        rfx=_specularTransform.szx;
                                        rfy=_specularTransform.szy;
                                        rfz=_specularTransform.szz;

                                        rf=rfx*nx+rfy*ny+rfz*nz;

                                        
spec=directional.specular*Math.pow(rf,shininess)
*specular_brightness;

                                        ksr+=red*spec;
                                        ksg+=green*spec;
                                        ksb+=blue*spec;
                                }

                                for each (point in 
tri.source.lightarray.points) {
                                        red=point.red;
                                        green=point.green;
                                        blue=point.blue;

                                        
_viewPosition=point.viewPositions[tri.view];

                                        dfx=_viewPosition.x-c0x;
                                        dfy=_viewPosition.y-c0y;
                                        dfz=_viewPosition.z-c0z;
                                        df=Math.sqrt(dfx*dfx+dfy*dfy+dfz*dfz);
                                        dfx/=df;
                                        dfy/=df;
                                        dfz/=df;
                                        fade=1/df/df;

                                        
amb=point.ambient*fade*ambient_brightness;

                                        kar+=red*amb;
                                        kag+=green*amb;
                                        kab+=blue*amb;

                                        nf=dfx*pa+dfy*pb+dfz*pc;

                                        if (nf<0) {
                                                continue;
                                        }

                                        
diff=point.diffuse*fade*nf*diffuse_brightness;

                                        kdr+=red*diff;
                                        kdg+=green*diff;
                                        kdb+=blue*diff;

                                        rfz=dfz-2*nf*pc;

                                        if (rfz<0) {
                                                continue;
                                        }

                                        rfx=dfx-2*nf*pa;
                                        rfy=dfy-2*nf*pb;

                                        
spec=point.specular*fade*Math.pow(rfz,shininess)
*specular_brightness;

                                        ksr+=red*spec;
                                        ksg+=green*spec;
                                        ksb+=blue*spec;


                                        //render = false;
                                }

                                
renderTriBacked(tri,session,kar,kag,kab,kdr,kdg,kdb,ksr,ksg,ksb);

                                if (draw_fall||draw_reflect||draw_normal) {
                                        
graphics=session.graphics,cz=c0z,cx=c0x*zoom/1+cz/
focus,cy=c0y*zoom/1+cz/focus;

                                        if (draw_normal) {
                                                
ncz=c0z+30*pc,ncx=c0x+30*pa*zoom*focus/focus+ncz,ncy=c0y
+30*pb*zoom*focus/focus+ncz;

                                                
graphics.lineStyle(1,0x000000,1);
                                                graphics.moveTo(cx,cy);
                                                graphics.lineTo(ncx,ncy);
                                                graphics.moveTo(cx,cy);
                                                graphics.drawCircle(cx,cy,2);
                                        }

                                        if (draw_fall||draw_reflect) {
                                                for each (point in 
tri.source.lightarray.points) {
                                                        red=point.red;
                                                        green=point.green;
                                                        blue=point.blue;
                                                        sum=red+green+blue/0xFF;
                                                        red/=sum;
                                                        green/=sum;
                                                        blue/=sum;

                                                        dfx=_viewPosition.x-c0x;
                                                        dfy=_viewPosition.y-c0y;
                                                        dfz=_viewPosition.z-c0z;
                                                        
df=Math.sqrt(dfx*dfx+dfy*dfy+dfz*dfz);
                                                        dfx/=df;
                                                        dfy/=df;
                                                        dfz/=df;

                                                        nf=dfx*pa+dfy*pb+dfz*pc;
                                                        if (nf<0) {
                                                                continue;
                                                        }

                                                        if (draw_fall) {
                                                                
ffz=c0z+30*dfz*1-draw_fall_k,ffx=c0x+30*dfx*1-
draw_fall_k*zoom*focus/focus+ffz,ffy=c0y+30*dfy*1-
draw_fall_k*zoom*focus/focus+ffz,fz=c0z+30*dfz,fx=c0x
+30*dfx*zoom*focus/focus+fz,fy=c0y+30*dfy*zoom*focus/focus+fz;

                                                                
graphics.lineStyle(1,int(red)*0x10000+int(green)*0x100+int
(blue),1);
                                                                
graphics.moveTo(ffx,ffy);
                                                                
graphics.lineTo(fx,fy);
                                                                
graphics.moveTo(ffx,ffy);
                                                        }

                                                        if (draw_reflect) {
                                                                rfx=dfx-2*nf*pa;
                                                                rfy=dfy-2*nf*pb;
                                                                rfz=dfz-2*nf*pc;

        
rz=c0z-30*rfz*draw_reflect_k,rx=c0x-30*rfx*draw_reflect_k*zoom*focus/
focus+rz,ry=c0y-30*rfy*draw_reflect_k*zoom*focus/focus+rz;

                                                                
graphics.lineStyle(1,int(red*0.5)*0x10000+int(green*0.5)
*0x100+int(blue*0.5),1);
                                                                
graphics.moveTo(cx,cy);
                                                                
graphics.lineTo(rx,ry);
                                                                
graphics.moveTo(cx,cy);
                                                        }
                                                }
                                        }
                                }
                        }
                }

                /**
                 * @private
                 */
                public function get visible():Boolean {
                        throw new Error("Not implemented");
                }

                /**
                 * @inheritDoc
                 */
                public function addOnMaterialUpdate(listener:Function):void {
                        //addEventListener(MaterialEvent.MATERIAL_UPDATED, 
listener, false,
0, true);
                }

                /**
                 * @inheritDoc
                 */
                public function removeOnMaterialUpdate(listener:Function):void {
                        
removeEventListener(MaterialEvent.MATERIAL_UPDATED,listener,false);
                }
                protected function renderTriBacked
(tri:DrawTriangle,session:AbstractRenderSession,kar:Number,kag:Number,kab:Number,kdr:Number,kdg:Number,kdb:Number,ksr:Number,ksg:Number,ksb:Number,smooth:Boolean
= true,repeat:Boolean = false):void {
                        br=kar+kag+kab+kdr+kdg+kdb+ksr+ksg+ksb/3;
                        //br=Math.random()*1;
                        trace(br);
                        //trace("renderTriBacked");

                        mapping=getMapping(tri);

                        var unfoldedX:Number=tri.faceVO.uv0.u*_bitmap.width;
                        var unfoldedY:Number=tri.faceVO.uv0.v*_bitmap.height;

                        v0=tri.v0;
                        v1=tri.v1;
                        v2=tri.v2;
                        trace(_mapCache);
                        /*
                        if (br<1&&blackrender||step<16&&! _bitmap.transparent) {
                        //session.renderTriangleBitmap
(_bitmap,mapping,v0,v1,v2,smooth,repeat);
                        //session.renderTriangleColor(0x000000,1-br,v0,v1,v2);
                        } else if (br>1&&whiterender) {
                        //session.renderTriangleBitmap
(_bitmap,mapping,v0,v1,v2,smooth,repeat);
                        
//session.renderTriangleColor(0xFFFFFF,br-1*whitek,v0,v1,v2);
                        } else {
                        */
                        if (step<64) {
                                if (Math.random()<0.01) {
                                        doubleStepTo(64);
                                }
                        }

                        var brightness:Number=ladder(br);
                        var bitmap:BitmapData=cache[brightness];
                        if (bitmap==null) {
                                bitmap=new 
BitmapData(_bitmap.width,_bitmap.height,true,
0x00000000);
                                
colorTransform.matrix=[brightness,0,0,0,0,0,brightness,
0,0,0,0,0,brightness,0,0,0,0,0,1,0];
                                bitmap.applyFilter
(_bitmap,bitmap.rect,bitmapPoint,colorTransform);
                                cache[brightness]=bitmap;
                        }

                        if (step%2==0) {
                                _mapCache.graphics.lineStyle();
                                _mapCache.graphics.beginBitmapFill(bitmap);
                                
//_mapCache.graphics.beginFill(0xFFFFFF*brightness);
                                _mapCache.graphics.moveTo(unfoldedX,unfoldedY);
                                
_mapCache.graphics.lineTo(unfoldedX+66,unfoldedY);
                                
_mapCache.graphics.lineTo(unfoldedX,unfoldedY+66);
                                _mapCache.graphics.endFill();
                        } else {
                                _mapCache.graphics.lineStyle();
                                _mapCache.graphics.beginBitmapFill(bitmap);
                                
//_mapCache.graphics.beginFill(0xFFFFFF*brightness);
                                
_mapCache.graphics.moveTo(unfoldedX+66,unfoldedY);
                                
_mapCache.graphics.lineTo(unfoldedX+66,unfoldedY+66);
                                
_mapCache.graphics.lineTo(unfoldedX,unfoldedY+66);
                                _mapCache.graphics.endFill();
                        }
                        //}
                }
                public function getMapping(tri:DrawTriangle):Matrix {
                        if (tri.generated) {
                                _texturemapping=tri.transformUV(this).clone();
                                _texturemapping.invert();

                                return _texturemapping;
                        }

                        
_faceMaterialVO=getFaceMaterialVO(tri.faceVO,tri.source,tri.view);

                        if (! _faceMaterialVO.invalidated) {
                                return _faceMaterialVO.texturemapping;
                        }

                        _texturemapping=tri.transformUV(this).clone();
                        _texturemapping.invert();

                        return _faceMaterialVO.texturemapping = _texturemapping;
                }
                public function getFaceMaterialVO(faceVO:FaceVO, 
source:Object3D =
null, view:View3D = null):FaceMaterialVO {
                        if ((_faceMaterialVO = _faceDictionary[faceVO])) {
                                return _faceMaterialVO;
                        }

                        return _faceDictionary[faceVO] = new FaceMaterialVO();
                }
                private function ladder(v:Number):Number {
                        if (v<1/0xFF) {
                                return 0;
                        }
                        if (v>0xFF) {
                                v=0xFF;
                        }
                        return Math.exp(Math.round(Math.log(v)*step)/step);
                }
                public function doubleStepTo(limit:int):void {
                        if (step<limit) {
                                step*=2;
                        }
                }
                public function get width():Number {
                        return _bitmap.width;
                }

                /**
                 * @inheritDoc
                 */
                public function get height():Number {
                        return _bitmap.height;
                }

                /**
                 * @inheritDoc
                 */
                public function get bitmap():BitmapData {
                        return _bitmap;
                }
                /**
                 * @inheritDoc
                 */
                public function getPixel32(u:Number, v:Number):uint {
                        return _bitmap.getPixel32(u*_bitmap.width, (1 - 
v)*_bitmap.height);
                }
                public function invalidateFaces(source:Object3D = null, 
view:View3D
= null):void {
                        for each (_faceMaterialVO in _faceDictionary) {
                                _faceMaterialVO.invalidated=true;
                        }
                }

        }
}

Reply via email to