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 ]
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!
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.
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
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!
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.
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
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:Number, h:Number, d:Number):Mesh { cube = new Plane(materialsVect[0], w, h) as Mesh; cube.z = -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 = 1; cubeFaceNum < 6; cubeFaceNum++) { subGeometry = SubGeometry(Mesh(cube).geometry.subGeometries[0]).clone(); vtd = new Vector.<Number> vnd = new Vector.<Number> rotM.identity();
if (cubeFaceNum == 1) rotM.appendRotation(180, new Vector3D(0, 1, 0));
if (cubeFaceNum == 2) rotM.appendRotation(90, new Vector3D(0, 1, 0));
if (cubeFaceNum == 3) rotM.appendRotation(270, new Vector3D(0, 1, 0));
if (cubeFaceNum == 4) rotM.appendRotation(90, new Vector3D(1, 0, 0));
if (cubeFaceNum == 5) rotM.appendRotation(-90, new Vector3D(1, 0, 0));
for (var i:int = 0; i < subGeometry.vertexData.length; i = i + 3) { v.setTo(subGeometry.vertexData[i], subGeometry.vertexData[i + 1], subGeometry.vertexData[i + 2]) vr = rotM.deltaTransformVector(v);
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"; } } }
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.
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?
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;
/** * 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=0; i<6; i++ ) { //_materials.push( new ColorMaterial(0xFF0000, 1) ); buildFace( i ); } }
/** * 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.z = -_depth/2; break;
case 1: cubeFace = new Plane( _materials[index], _width, _height, _segmentsW, _segmentsH ); cubeFace.rotationY = 180; cubeFace.z = _depth/2; break;
/** * Expand out each face */ public function expand( amount:Number ):void { for( var i:int=0; i<faces.length; i++ ) { setFaceExpand( amount, i ); } }
/** * Expand the face away from centre, by amount specified */ private function setFaceExpand( amount:Number, index:int ):void { var face:Plane = faces[index]; if( amount < 0 ) amount = 0; switch( index ) {
case 0: face.z = -_depth/2 - amount; break;
case 1: face.z = _depth/2 + amount; break;
case 2: face.y = _height/2 + amount; break;
case 3: face.y = -_height/2 - amount; break;
case 4: face.x = -_width/2 - amount; break;
case 5: face.x = _width/2 + 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?
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:
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.