no, not yet, writing a tutorial takes time, (witch I do not have atm...)
But since its very easy, here a quick intro.

for the lights settings and the use of Dot3Material, look at Rob's statue sources into the trunk

I'll cover here only very fast the way you can use the generator:

first you need to import it

import away3d.materials.utils.NormalMapGenerator;
import away3d.events.TraceEvent; --> import this one only if you want to see/add a processbar

you can see this process here:
http://www.closier.nl/playground/normalmaps_after.html


var colorsource:BitmapData = somecool_color_source_from_your_lib_or_embed;
                        //the generator needs geometry, here just a primitive
var sphere: Sphere = new Sphere({radius:3000, segmentsH:35, segmentsW:35, material:null});
                        // make an instance of the generator and pass the mesh
//1200x1200 is width and height of the map. the higher the setting, the higher quality you get, the longer it takes to render
                        //default is 512x512, but for a sphere a 256x256 should 
do just fine
var mapgen:NormalMapGenerator = new NormalMapGenerator(sphere, 1200, 1200);
                        //if you want that process monitoring, its time to add 
your listeners
                        //
                        mapgen.addOnTraceProgress(traceProgress);
mapgen.addOnTraceComplete(traceComplete); --> see handlers bellow, they assume here that you have added some movieclip as processbar
                        // Its time to pass the map, even not traced to the 
Dot3Material
var mat:Dot3BitmapMaterial = new Dot3BitmapMaterial(colorsource, mapgen.normalmap);
                        // set the material to the mesh
                        (sphere as Mesh).material = mat;
                        view.scene.addChild(sphere);

at this point you are actually done.

                private function traceComplete(e:TraceEvent):void
                {
                        removeChild(_bar);
                        _bar = null;
                }
                
                private function traceProgress(e:TraceEvent):void
                {
_bar.process_txt.text = "Processing normalmap "+Math.round(e.procent)+"%";
                        _bar.processcolor_mc.scaleX = e.procent/100;
                }
        

the generator supports an optional bumpmap, that will be post processed after the generation of the normal map.
to pass it to the class just:

                        var bump:BitmapData = 
some_black&white_source_with_contrast;
                        // here I set size to 256x256, pass the bumpmap source
//sometimes, if you want to soften the finish an additional blur can be postprocessed as well, in this case value 4. var mapgen:NormalMapGenerator = new NormalMapGenerator(sphere, 256, 256, bump, 4, 100); // the 100 is there for models with lots of faces. It represent the amount of faces that will be processes per interation. dfault is 100. // if no limit would be set, in large models, it would trigger the "this cript as run too long" // its made to allow third party Air apps for instance, where you can write an app that generate the maps and output the result as jpg on disc, then simply load it
                        // into your project. This is what I've done here:  
http://www.closier.nl/playground/normalmaps3.html


now imagine you have that map prerendered and you want add just a bump:
so in this case, normalmap == your prerendered normalmap
var mapgen:NormalMapGenerator = new NormalMapGenerator(null);
normalmap = nmg.applyBump(bumpmap, normalmap);


mmm, looks like that tut is almost done afterall :)

Fabrice


On Jan 21, 2009, at 11:44 PM, Ryan Clemens wrote:


Are there any tutorials on proper use of the generator class available?

thx,

Ryan

On Tue, Jan 20, 2009 at 1:45 PM, Fabrice <[email protected]> wrote:

Are you sure you are outputing a objectspace normalmap?

Try the generator class, to make your normalmap.
If it looks good, that's probably because you export your map as tangent
normalmaps.
the z information is used/applied another way, and I think that's what is
happening here.
not sure tho...

note that tangent maps will be supported soon

Fabrice




On Jan 20, 2009, at 9:28 PM, zhil wrote:


Hi there!
I have created simple application, which load normal map, simple
texture and shirt model, but for some reasons it looks pretty strange
- like if normal map was inverted for some reason (showing dark
instead of light and vice verse)

Online demo here
http://files.rightinpoint.com/tailor_65s6d562/tailor2.html

Source model
http://files.rightinpoint.com/tailor_65s6d562/shirt4.jpg

Source code

package {
      import flash.display.*;
      import flash.events.*;
      import flash.net.*;
      import away3d.core.*;
      import away3d.events.*;
      import fl.controls.List;
      import fl.data.DataProvider;

      import away3d.core.base.*;
      import away3d.containers.*;
      import away3d.primitives.*;
      import away3d.materials.*;
      import away3d.loaders.*;
      import away3d.cameras.*;
      import away3d.core.utils.Cast;
      import away3d.events.*;
      import away3d.lights.*;

      public class Tailor2 extends Sprite {
              var view:View3D;
              var scene:Scene3D;
              var camera:HoverCamera3D;
              var objLoader:Object3DLoader;
              var obj:ObjectContainer3D;
              var objLoader2:Object3DLoader;
              var obj2:ObjectContainer3D;
              var material:Dot3BitmapMaterial;
              var _loader:Loader;
              var _loader2:Loader;
              var _bitmapData:BitmapData;
              var light:DirectionalLight3D;
              var move:Boolean = false;
              var lastPanAngle:Number;
              var lastTiltAngle:Number;
              var lastMouseX:Number;
              var lastMouseY:Number;

              var selectGroup:Sprite;
              var selectMiddle:List;

              function Tailor2() {
                      stage.frameRate=60;
                      away3dcreate();
//                      initSelect();
              }
              function initSelect() {
                      selectMiddle = new List();
                      selectGroup.addChild(selectMiddle);
              }
              function away3dcreate():void {
                      scene = new Scene3D();
                      camera = new HoverCamera3D({zoom:3, focus:200,
distance:10000});
                      camera.targetpanangle = camera.panangle = -10;
camera.targettiltangle = camera.tiltangle = 20;
                      camera.yfactor = 1;
                      view=new
View3D({scene:scene,camera:camera,x:450,y:450});
                      addChild(view);
                      _loader = new Loader();

_loader.contentLoaderInfo.addEventListener(Event.COMPLETE,
onLoadTextureComplete);
                      _loader.load(new URLRequest("assets/t.jpg"));
              }
              function onLoadTextureComplete(e:Event):void {
                      trace("onLoadTextureComplete");
_bitmapData = Bitmap(_loader.content).bitmapData;
                      _loader2 = new Loader();

_loader2.contentLoaderInfo.addEventListener(Event.COMPLETE,
onLoadNormalComplete);
//                      _loader2.load(new
URLRequest("assets/wp/normal.jpg"));
                      _loader2.load(new
URLRequest("assets/normal_from_Zbrush6.jpg"));
              }
              function onLoadNormalComplete(e:Event):void {
                      trace("onLoadNormalComplete");
// light = new DirectionalLight3D({color: 0xFFFFFF,
ambient:0.25,
diffuse:0.85, specular:0.95});
light = new DirectionalLight3D({color: 0xFFFFFF,
ambient:0.15,
diffuse:0.95, specular:0.95});
                      light.x = 10;
                      light.z = 1;
                      light.y = 1;
                      scene.addChild( light );
                      material = new
Dot3BitmapMaterial(_bitmapData,Bitmap
(_loader2.content).bitmapData,{});
                      //material = new
Dot3BitmapMaterial(Cast.bitmap(TorsoImage),
Cast.bitmap(TorsoNormal));
//                      objLoader =
Max3DS.load("assets/wp/men_normal_fit.3DS",
{material:material, ownCanvas:true, name:"torso", centerMeshes:true}); objLoader = Max3DS.load("assets/ 2009_01_20v2.3DS", {material:material, ownCanvas:true, name:"torso", centerMeshes:true});
                      objLoader.addOnSuccess(objOnSuccess);
                      //objLoader2 =
Max3DS.load("assets/collar.3DS",{material:material,
ownCanvas:true, name:"torso", centerMeshes:true});
                      //objLoader2.addOnSuccess(obj2OnSuccess);
              }
              function objOnSuccess(e:Event):void {
                      trace("objOnSuccess");
                      obj = (objLoader.handle as ObjectContainer3D);
                      autoAdjust(obj);
                      view.scene.addChild(obj);
                      camera.lookAt(obj.position);
                      initListeners();
              }
              function autoAdjust(obj:ObjectContainer3D) {
                      trace(obj.minX);
                      trace(obj.maxX);
                      trace(obj.minY);
                      trace(obj.maxY);
                      trace(obj.minZ);
                      trace(obj.maxZ);

obj.movePivot((obj.minX+obj.maxX)/2,(obj.minY+obj.maxY)/2,(obj.minZ
+obj.maxZ)/2);

obj.scale(10000/Math.max(Math.abs(obj.minX-obj.maxX),Math.abs
(obj.minY-obj.maxY),Math.abs(obj.minZ-obj.maxZ)));
                      obj.rotationX = 90;
              }
              function initListeners():void {
addEventListener( Event.ENTER_FRAME, onEnterFrame
);
                      stage.addEventListener(MouseEvent.MOUSE_DOWN,
onMouseDown);
                      stage.addEventListener(MouseEvent.MOUSE_UP,
onMouseUp);
              }

              /**
               * Navigation and render loop
               */
              function onEnterFrame(event:Event):void {
                      view.camera.moveTo(obj.x,obj.y,obj.z);
                      view.camera.rotationY=mouseX/2;
                      view.camera.rotationX=mouseY/2;
                      view.camera.moveBackward(5);
                      //obj.rotationY+=1;
                      view.render();

                      if (move) {
camera.targetpanangle = 0.3*(stage.mouseX -
lastMouseX) +
lastPanAngle;
camera.targettiltangle = 0.3*(stage.mouseY
- lastMouseY) +
lastTiltAngle;
                      }
                      camera.hover();
                      view.render();
              }

              /**
               * Mouse down listener for navigation
               */
              function onMouseDown(event:MouseEvent):void {
                      lastPanAngle = camera.targetpanangle;
                      lastTiltAngle = camera.targettiltangle;
                      lastMouseX = stage.mouseX;
                      lastMouseY = stage.mouseY;
                      move = true;
                      stage.addEventListener(Event.MOUSE_LEAVE,
onStageMouseLeave);
              }

              /**
               * Mouse up listener for navigation
               */
              function onMouseUp(event:MouseEvent):void {
                      move = false;
                      stage.removeEventListener(Event.MOUSE_LEAVE,
onStageMouseLeave);
              }

              /**
               * Mouse stage leave listener for navigation
               */
              function onStageMouseLeave(event:Event):void {
                      move = false;
                      stage.removeEventListener(Event.MOUSE_LEAVE,
onStageMouseLeave);
              }
      }
}

Location of the models the same as in the source.

Any ideas what could be the reason?
- problems in 3ds model (it was created in Maya, exported as obj,
imported into 3dmax, exported as 3ds)?
- problems in normal map?
- problems in lights settings in action script? I have played with
different settings, but was failed to locate reason.
- bug in away3d?

Right now I dont have any ideas how I can move forward with this bug,
so any help are welcome.



Reply via email to