How to use away3d.materials.utils.MultipleMaterials?

Software: Away3D 4.x

andylaw, Newbie
Posted: 22 September 2011 09:38 AM   Total Posts: 8

Hi all,

I’m trying to get different BitmapMaterials onto each face of a cube in Away3D Broomstick, and I’m guessing that this should be done using the MultipleMaterials class, applying a different BitmapMaterial to front, back, left, right….

I’m a bit confused on this front though, as I’d expect the MultipleMaterials class to extend MaterialBase, as this is what the Cube constructor expects as a Material. The MultipleMaterials class extend Object though, and even if I cast the object to MaterialBase, the MultipleMaterials object isn’t applied to the cube.

I know I can get this working by creating my own BitmapData to apply to a single BitmapMaterial, which contains all the images I want to apply, but was hoping that this class might help me save some time. Any help much appreciated!

   

andylaw, Newbie
Posted: 22 September 2011 11:24 AM   Total Posts: 8   [ # 1 ]

Update:

I tried to use a single BitmapMaterial containing all sides of the cube, but I have come up against the same issue as listed here: http://groups.google.com/group/away3d-dev/browse_thread/thread/14c2edc231ab121d

Is there any update on this issue? I can implement a simple fix for my purposes, as I actually only need to have materials on 2 faces of the cube (front and right), by amending lines 388-391 of the Cube class from:
if (_tile6) {
u_tile_dim = u_tile_step = 1/3;
v_tile_dim = v_tile_step = 1/2;
}
to
if (_tile6) {
u_tile_dim = u_tile_step = 1/2;
v_tile_dim = v_tile_step = 1/2;
}

This then gives at least a full material on each face, but I’m aware that this is a quick and (very) dirty fix!

   

Avatar
80prozent, Sr. Member
Posted: 22 September 2011 12:05 PM   Total Posts: 430   [ # 2 ]

hi

i dont know about useing multiplematerials on cube primitive.
could be that my away3d source is outdated (didnt update for about a week), but for me it looks like the cube-primitive only supports single material.

i provided a fix for the cube.as in this thread:
http://away3d.com/forum/viewthread/476/

its working like supposed (tile6), the only problem is, that my fix maps the bitmap as a 3x2 grid while the documentation says it should be a 2x3 grid…

hope that helps

 Signature 

sorry…i hope my actionscript is better than my english…

   

andylaw, Newbie
Posted: 22 September 2011 12:19 PM   Total Posts: 8   [ # 3 ]

Thanks 80prozent,

I’ll give that a go, but if I can’t get that to work I think I’m going to build my own cube class, which will essentially be 6 planes.

The reason for this is that I my primitives aren’t actually cubes, rather cuboids - rectangular rather than square. I can foresee that I’m going to have issues mapping dynamically loaded bitmaps, and bitmapdata taken from Sprites into tile6 without each side being of equal height/width/depth.

Thanks very much for your help though!

   

Avatar
80prozent, Sr. Member
Posted: 22 September 2011 01:02 PM   Total Posts: 430   [ # 4 ]

i understand what you mean.

when building a cube out of 6 planes, you end up having 6 different meshes each one with one submesh. i think it would be better to build a mesh with 6 submeshes (each submesh in plane-shape). you could go into a 3d editor and figure out the best way to map the uvs to this planes.

hope that makes sense.

 Signature 

sorry…i hope my actionscript is better than my english…

   

andylaw, Newbie
Posted: 22 September 2011 01:31 PM   Total Posts: 8   [ # 5 ]

Thanks, I think that makes sense to me! I’ve got an example working with 6 planes at the moment, but will look into setting up an object with a single mesh.

I’m only going to be needing 2 sides of the cube (probably, although quite possible that that changes further down the road on the project), and will likely have a maximum of 20-30 cubes on stage at any one time, so I don’t think that the machine will be struggling with the multiple planes route. I will certainly look down the route of a single mesh object though as really want to make this so that it’s able to take more objects being thrown on to the stage if it is needed.

Thanks again for your help. Will try to post up any code once I’ve got it working.

   

John Brookes, Moderator
Posted: 22 September 2011 02:29 PM   Total Posts: 732   [ # 6 ]

A hacky version I did a while back may help/hinder.
Just for learning wink

package
{
 import away3d
.core.base.SubGeometry;
 
import away3d.entities.Mesh;
 
import away3d.materials.MaterialBase;
 
import away3d.primitives.Plane;
 
import away3d.tools.MeshHelper;
 
import flash.geom.Matrix3D;
 
import flash.geom.Vector3D;
 public class 
Cube6
 {
  
private var cube:Mesh;
  private var 
subGeometry:SubGeometry;
  private var 
vtd:Vector.<Number>;
  private var 
vnd:Vector.<Number>;
  
/*Creates a cube (single mesh) with separate materials for each side.
   * eg
   * var materialsVct:Vector.<MaterialBase> = new Vector.<MaterialBase>;
   * materialsVct.push(new ColorMaterial(0xff0000)); //front
   * materialsVct.push(new ColorMaterial(0xffff00)); //back
   * materialsVct.push(new ColorMaterial(0xffffff)); //left
   * materialsVct.push(new ColorMaterial(0x0000ff)); //right
   * materialsVct.push(new ColorMaterial(0x00ff00)); //top
   * materialsVct.push(new ColorMaterial(0x00ffff)); //bottom
   *
   * cube = new Cube6().createCube6(materialsVct,400,300,400) as Mesh;
   * scene.addChild(cube);
   * 
   * replace materials
   * eg
   * cube.replaceFrontMaterial(new colorMaterial(0x000000));
   */
  
public function Cube6()
  
{
  }
   
  
public function createCube6(materialsVect:Vector.<MaterialBase>, w:Numberh:Numberd:Number):Mesh
  {
   cube 
= new Plane(materialsVect[0]wh) as Mesh;
   
cube.= -d/2
   
var vr:Vector3D;
   var 
vn:Vector3D;
   var 
v:Vector3D = new Vector3D()
   var 
n:Vector3D = new Vector3D()
   var 
rotM:Matrix3D = new Matrix3D();
   
   for (var 
cubeFaceNum:int 1cubeFaceNum 6cubeFaceNum++)
   
{
    subGeometry 
SubGeometry(Mesh(cube).geometry.subGeometries[0]).clone();
    
vtd = new Vector.<Number>
    
vnd = new Vector.<Number>
    
rotM.identity();
    
    if (
cubeFaceNum == 1rotM.appendRotation(180, new Vector3D(010));
    
    if (
cubeFaceNum == 2rotM.appendRotation(90, new Vector3D(010));
    
    if (
cubeFaceNum == 3rotM.appendRotation(270, new Vector3D(010));
    
    if (
cubeFaceNum == 4rotM.appendRotation(90, new Vector3D(100));
    
    if (
cubeFaceNum == 5rotM.appendRotation(-90, new Vector3D(100));
    
    
    for (var 
i:int 0subGeometry.vertexData.length3)
    

     v
.setTo(subGeometry.vertexData[i]subGeometry.vertexData[i 1]subGeometry.vertexData[i 2])
     
vr rotM.deltaTransformVector(v);
     
     
n.setTo(subGeometry.vertexNormalData[i]subGeometry.vertexNormalData[i+1]subGeometry.vertexNormalData[i+2])
     
vn rotM.deltaTransformVector(n);
     
vn.normalize();
     
     if (
cubeFaceNum == 1
     
{
      vr
.incrementBy(new Vector3D00d));
     
}
     
if (cubeFaceNum == 2
     
{
      vr
.*= w;
      
vr.incrementBy(new Vector3D( -202));
     
}
     
if (cubeFaceNum == 3
     
{
      vr
.*= w;
      
vr.incrementBy(new Vector3D202));
     
}
     
if (cubeFaceNum == 4
     
{
      vr
.*= h;
      
vr.incrementBy(new Vector3D0h/22));
     
}
     
if (cubeFaceNum == 5
     
{
      vr
.*= h;
      
vr.incrementBy(new Vector3D0, -h/22));
     
}
     vtd
.push(vr.x);
     
vtd.push(vr.y);
     
vtd.push(vr.z);
     
     
vnd.push(vn.x);
     
vnd.push(vn.y);
     
vnd.push(vn.z);
     
    
}
    subGeometry
.updateVertexData(vtd);
    
subGeometry.updateVertexNormalData(vnd);
    
Mesh(cube).geometry.addSubGeometry(subGeometry);
    
Mesh(cube).subMeshes[cubeFaceNum].material materialsVect[cubeFaceNum];
   
}
   cube
.0
   MeshHelper
.recenter(cube);
   
   
cube.subMeshes[0].material.name "frontMaterial";
   
cube.subMeshes[1].material.name "backMaterial";
   
cube.subMeshes[2].material.name "leftMaterial";
   
cube.subMeshes[3].material.name "rightMaterial";
   
cube.subMeshes[4].material.name "topMaterial";
   
cube.subMeshes[5].material.name "bottomMaterial";
   
   
   
//cube.subMeshes[1].subGeometry.updateVertexNormalData(cube.geometry.subGeometries[1].vertexNormalData);
   
   
   
return cube;
  
}
  
  
public function replaceFrontMaterial(value:MaterialBase):void
  {
   cube
.subMeshes[0].material.dispose(true);
   
cube.subMeshes[0].material value;
   
cube.subMeshes[0].material.name "frontMaterial";
  
}
  
  
public function replaceBackMaterial(value:MaterialBase):void
  {
   cube
.subMeshes[1].material.dispose(true);
   
cube.subMeshes[1].material value;
   
cube.subMeshes[1].material.name "backMaterial";
  
}
  
  
public function replaceLeftMaterial(value:MaterialBase):void
  {
   cube
.subMeshes[2].material.dispose(true);
   
cube.subMeshes[2].material value;
   
cube.subMeshes[2].material.name "leftMaterial";
  
}
  
  
public function replaceRightMaterial(value:MaterialBase):void
  {
   cube
.subMeshes[3].material.dispose(true);
   
cube.subMeshes[3].material value;
   
cube.subMeshes[3].material.name "rightMaterial";
  
}
  
  
public function replaceTopMaterial(value:MaterialBase):void
  {
   cube
.subMeshes[4].material.dispose(true);
   
cube.subMeshes[4].material value;
   
cube.subMeshes[4].material.name "topMaterial";
  
}
  
  
public function replaceBottomMaterial(value:MaterialBase):void
  {
   cube
.subMeshes[5].material.dispose(true);
   
cube.subMeshes[5].material value;
   
cube.subMeshes[5].material.name "bottomMaterial";
  
}
 }
   

Avatar
80prozent, Sr. Member
Posted: 22 September 2011 03:04 PM   Total Posts: 430   [ # 7 ]

@john:

looks like a good solution for this cupe-mapping issue. i acctually dont need it, but since people ask for this quite often, maybe the devs should consider adding your fix to the library, or merge it with the current cube class.

 Signature 

sorry…i hope my actionscript is better than my english…

   

andylaw, Newbie
Posted: 22 September 2011 03:04 PM   Total Posts: 8   [ # 8 ]

Thank you John, that’s awesome!

I also hacked together the version with 6 planes earlier for anyone who’s interested (even though it’s since been proven that it’s not the most efficient way of doing it). I’d added in the functionality to expand out the faces of the cube as well, which might be useful to someone - not sure how easy it would be to do this from a single mesh?

package
{
 import away3d
.containers.ObjectContainer3D;
 
import away3d.materials.ColorMaterial;
 
import away3d.materials.MaterialBase;
 
import away3d.primitives.Plane;
 
 public class 
PlaneCube extends ObjectContainer3D
 {
  
  
private var _materials:Vector.<MaterialBase>;
  private var 
_width:Number;
  private var 
_height:Number;
  private var 
_depth:Number;
  private var 
_segmentsW:uint;
  private var 
_segmentsH:uint;
  private var 
_segmentsD:uint;
  
  private var 
faces:Vector.<Plane>;
  
  public function 
PlaneCube(materials:Vector.<MaterialBase>=nullwidth:Number=100height:Number=100depth:Number=100segmentsW uint 1segmentsH uint 1segmentsD uint 1)
  
{
   super
();
   
_materials materials;
   if( 
_materials == null _materials = new Vector.<MaterialBase>()
   
_width width;
   
_height height;
   
_depth depth;
   
_segmentsW segmentsW;
   
_segmentsH segmentsH;
   
_segmentsD segmentsD;
   
   
init();
  
}
  
  
/**
   * Order of materials = 1: Front, 2: Back, 3: Top, 4: Bottom, 5: Left, 6: Right
   */
  
private function init():void {
   faces 
= new Vector.<Plane>();
   for( var 
i:int=0i<6i++ ) {
    
//_materials.push( new ColorMaterial(0xFF0000, 1) );
    
buildFace);
   
}
  }
  
  
/**
   * Build a plane for each face
   */
  
private function buildFace(index:int):void {
   
var cubeFace:Plane;// = new Plane(testMaterial, width, height, segmentsW, segmentsH);
   
switch( index {
    
    
case 0:
     
cubeFace = new Plane_materials[index]_width_height_segmentsW_segmentsH );
     
cubeFace.= -_depth/2;
     break;
    
    case 
1:
     
cubeFace = new Plane_materials[index]_width_height_segmentsW_segmentsH );
     
cubeFace.rotationY 180;
     
cubeFace._depth/2;
     break;
    
    case 
2:
     
cubeFace = new Plane_materials[index]_width_depth_segmentsW_segmentsD );
     
cubeFace.rotationX 90;
     
cubeFace._height/2;
     
cubeFace.0;
     break;
    
    case 
3:
     
cubeFace = new Plane_materials[index]_width_depth_segmentsW_segmentsD );
     
cubeFace.rotationX = -90;
     
cubeFace.= -_height/2;
     
cubeFace.0;
     break;
    
    case 
4:
     
cubeFace = new Plane_materials[index]_depth_height_segmentsW_segmentsD );
     
cubeFace.rotationY 90;
     
cubeFace.= -_width/2;
     
cubeFace.0;
     break;
    
    case 
5:
     
cubeFace = new Plane_materials[index]_depth_height_segmentsW_segmentsD );
     
cubeFace.rotationY = -90;
     
cubeFace._width/2;
     
cubeFace.0;
     break;
   
}
   
   
if( cubeFace != null {
    this
.addChild(cubeFace);
    
faces.pushcubeFace );
   
}
   
  }
  
  
/**
   * Expand out each face
   */
  
public function expandamount:Number ):void {
   
for( var i:int=0i<faces.lengthi++ ) {
    setFaceExpand
amount);
   
}
  }
  
  
/**
   * Expand the face away from centre, by amount specified
   */
  
private function setFaceExpandamount:Numberindex:int ):void {
   
var face:Plane faces[index];
   if( 
amount amount 0;
   switch( 
index {
    
    
case 0:
     
face.= -_depth/amount;
     break;
    
    case 
1:
     
face._depth/amount
     break;
    
    case 
2:
     
face._height/amount;
     break;
    
    case 
3:
     
face.= -_height/amount;
     break;
    
    case 
4:
     
face.= -_width/amount;
     break;
    
    case 
5:
     
face._width/amount;
     break;
   
}
   
  }
  
 }

 

 

   

andylaw, Newbie
Posted: 22 September 2011 03:09 PM   Total Posts: 8   [ # 9 ]

Sorry, last post should have read explode out the cube rather than expand.

Have to say, the performance that we’re getting with Away3D and AIR 3.0 is pretty amazing. Anyone got any idea when full release for FP11 and AIR 3.0 will be? Can we assume it’s going to be at MAX in October?

   

Avatar
80prozent, Sr. Member
Posted: 22 September 2011 03:22 PM   Total Posts: 430   [ # 10 ]

hi

you are right that it isnt as easy to move subgeometry as it is moving a whole mesh. you would have to modify all the verticles of a submesh to have it moving. (hope that is right)

here is a thread that might answer your question about release date:

http://away3d.com/forum/viewthread/811/

 Signature 

sorry…i hope my actionscript is better than my english…

   

andylaw, Newbie
Posted: 22 September 2011 03:36 PM   Total Posts: 8   [ # 11 ]

Cool, that’s great the the full release will be before this project goes live - slightly relieved at that smile

I ran a few tests between the Cube6 class and the Cube made of Planes that I hacked together and there’s some serious differences there:

20 Cubes on Stage:
- Poly count Cube6: 240
- Memory Cube6: 13.5mb
- Poly count PlaneCube: 23600
- Memory PlaneCube: 15.7mb

100 Cubes
- Poly count Cube6: 1200
- Memory Cube6: 15.6mb
- Poly count PlaneCube: 118000
- Memory PlaneCube: 26.8mb

So I will definitely be using something along the lines of the class that John provided (thanks again John) if we don’t need to move faces of the cube independently, otherwise I may have to use something along the lines of the ‘planes’ cube.

Thanks guys, you’ve been more than helpful!

   

John Brookes, Moderator
Posted: 22 September 2011 03:38 PM   Total Posts: 732   [ # 12 ]

If you do the 6 planes you could always merge them to give you a single mesh/transform with 6 changable materials.

   
   

X

Away3D Forum

Member Login

Username

Password

Remember_me



X