Well, I didn't like that functionality. It hurt my brain. ;) So I've written some of my own methods for it, borrowing a little from what was in the Mirror class...
Here are my additions if anyone else wants them: Addition to Object3D.as: public static const MIRROR_X:int = 1; public static const MIRROR_Y:int = 2; public static const MIRROR_Z:int = 4; /** * Mirrors the object about an origin * * @param _flags Any combination of MIRROR_X, MIRROR_Y, and MIRROR_Z which states which axis to mirror along * @param _origin [optional] The origin to mirror about. Defaults to 0,0,0 * @param _duplicate [optional] When true any container objects are not manipulated. Instead underlying objects such as 'Mesh' physically duplicate their geometry in the mirrored position. Defaults to true. * */ public function mirror(_flags:int, _origin:Number3D = null, _duplicate:Boolean = true):void { if (!_duplicate) { if (_origin == null) { _origin = new Number3D(); } if ((_flags & MIRROR_X) != 0) { _transform.tx = -_transform.tx + ((_origin.x - _transform.tx)); } if ((_flags & MIRROR_Y) != 0) { _transform.ty = -_transform.ty + ((_origin.y - _transform.ty)); } if ((_flags & MIRROR_Z) != 0) { _transform.tz = -_transform.tz + ((_origin.z - _transform.tz)); } } } Addition to ObjectContainer3D.as: public override function mirror(_flags:int, _origin:Number3D = null, _duplicate:Boolean = true):void { for each (var child:Object3D in _children) { child.mirror(_flags, _origin, _duplicate); } super.mirror(_flags, _origin, _duplicate); } Addition to Mesh.as: public override function mirror(_flags:int, _origin:Number3D = null, _duplicate:Boolean = true):void { var aFaces:Array = faces; var facecount:int = aFaces.length; var face:Face; var va:Vertex; var vb:Vertex; var vc:Vertex; var v0:Vertex; var v1:Vertex; var v2:Vertex; var uvTemp:UV; var offset:Number3D; var vax:Number = 0; var vbx:Number = 0; var vcx:Number = 0; var vay:Number = 0; var vby:Number = 0; var vcy:Number = 0; var vaz:Number = 0; var vbz:Number = 0; var vcz:Number = 0; var flipNormals:Boolean = false; if (_duplicate) { if (_origin == null) { _origin = new Number3D(); } var pos:Number3D = scenePosition; offset = new Number3D((_origin.x - pos.x) * 2, (_origin.y - pos.y) * 2, (_origin.z - pos.z) * 2); } for (var i:int = 0; i < facecount; i++) { flipNormals = false; face = aFaces[i]; va = face._v0; vb = face._v1; vc = face._v2; if (_duplicate) { if ((_flags & MIRROR_X) != 0) { vax = -va.x + offset.x; vbx = -vb.x + offset.x; vcx = -vc.x + offset.x; flipNormals = !flipNormals; } else { vax = va.x; vbx = vb.x; vcx = vc.x; } if ((_flags & MIRROR_Y) != 0) { vay = -va.y + offset.y; vby = -vb.y + offset.y; vcy = -vc.y + offset.y; flipNormals = !flipNormals; } else { vay = va.y; vby = vb.y; vcy = vc.y; } if ((_flags & MIRROR_Z) != 0) { vaz = -va.z + offset.z; vbz = -vb.z + offset.z; vcz = -vc.z + offset.z; flipNormals = !flipNormals; } else { vaz = va.z; vbz = vb.z; vcz = vc.z; } v0 = new Vertex( vax, vay, vaz); v1 = new Vertex( vbx, vby, vbz); v2 = new Vertex( vcx, vcy, vcz); if (flipNormals) { addFace(new Face(v1, v0, v2, face.material, face.uv1, face.uv0, face.uv2 ) ); } else { addFace(new Face(v0, v1, v2, face.material, face.uv0, face.uv1, face.uv2 ) ); } } else { if ((_flags & MIRROR_X) != 0) { vax = -va.x; vbx = -vb.x; vcx = -vc.x; flipNormals = !flipNormals; } else { vax = va.x; vbx = vb.x; vcx = vc.x; } if ((_flags & MIRROR_Y) != 0) { vay = -va.y; vby = -vb.y; vcy = -vc.y; flipNormals = !flipNormals; } else { vay = va.y; vby = vb.y; vcy = vc.y; } if ((_flags & MIRROR_Z) != 0) { vaz = -va.z; vbz = -vb.z; vcz = -vc.z; flipNormals = !flipNormals; } else { vaz = va.z; vbz = vb.z; vcz = vc.z; } v0 = new Vertex( vax, vay, vaz); v1 = new Vertex( vbx, vby, vbz); v2 = new Vertex( vcx, vcy, vcz); // perhaps have a mirror method in face as well if (flipNormals) { face.v0 = v1; face.v1 = v0; face.v2 = v2; uvTemp = face.uv0; face.uv0 = face.uv1; face.uv1 = uvTemp; } else { face.v0 = v0; face.v1 = v1; face.v2 = v2; } } } super.mirror(_flags, _origin, _duplicate); } The usage is pretty simple: // X Mirror about the origin myObject.mirror(Object3D.MIRROR_X); // Y Mirror about 0,30,0 myObject.mirror(Object3D.MIRROR_Y, new Number3D(0, 30, 0)); // X and Z Mirror about 10,0,10 myObject.mirror(Object3D.MIRROR_X | Object3D.MIRROR_Z, new Number3D(10, 0, 10)); // X Mirror about 20,0,0 with no duplication myObject.mirror(Object3D.MIRROR_X, new Number3D(20, 0, 0), false); It's recursive and seems to work on any containers, loaded meshes, and primitives. Having it work on a specified origin also allows for greater flexibility. I don't mean to state that the Mirror class is wrong; it just didn't exhibit the behaviour I expected. Hope this helps someone else out too. -Wex On Mar 4, 3:54 pm, Fabrice3D <fabric...@gmail.com> wrote: > these example is exact in terms of functionality > x+ will test the outmost maxX fopund as offset for the mirror, same nut > reversed for x- > > using mirror x is also correct, but that doesn't mean your model is. > let me explain: if you plan for instance to mirror on x, at 0,0,0 > then because model will be exactly mirrored at that point, it means that your > model should be excenter in your modeler so that x 0 is at side of your model. > plus , if you do not set the mirror mesh duplicate to false, you will get an > additive result. the mirrored part become part of the original model. > > your "i" comfirms the above, by looking at the shared space at the base 0,0,0 > of the geometry. > > play around with the settings in Prefab, it's not having the unique mesh > option there yet, but you should be able to test > > Fabrice > > On Mar 4, 2010, at 4:29 PM, Wex wrote: > > > Okay, some Mirror testing; this is the scene creation code: > > > private function buildMirrorTest():void > > { > > var mat:ShadingColorMaterial = new > > ShadingColorMaterial(0xFFFF00); > > var sphere:Sphere = new Sphere( { radius:4, material:mat > > } ); > > m_view.scene.addChild(sphere); > > > mesh = Max3DS.load("axis.3DS"); > > mesh.addOnSuccess(flip); > > m_view.scene.addChild(mesh); > > } > > > private function flip(_event:Loader3DEvent):void > > { > > var cube:LoaderCube = _event.target as LoaderCube; > > > cube.handle.x = 0; > > cube.handle.y = 0; > > cube.handle.z = 0; > > } > > > This just loads a basic multiple-mesh model as seen here: > >http://www.creativenorth.co.uk/post-content/away003.png > > > There are 4 meshes in this model, one for the main three bars and one > > each for the three end-cubes. All have the same material applied. > > > If I then apply a Mirror be making the following change: > > > private function flip(_event:Loader3DEvent):void > > { > > var cube:LoaderCube = _event.target as LoaderCube; > > > cube.handle.x = 0; > > cube.handle.y = 0; > > cube.handle.z = 0; > > > Mirror.apply(cube.handle, "x", true, true); > > } > > > I get the correct, expected, result: > >http://www.creativenorth.co.uk/post-content/away004.png > > > However using either x+ or x- gives the following respectivly: > >http://www.creativenorth.co.uk/post-content/away005.png > >http://www.creativenorth.co.uk/post-content/away006.png > > > In addition; if I do: > > cube.handle.x = -40; > > Mirror.apply(cube.handle, "x", true, true); > > > It should mirror about the world origin, but I get (yellow sphere is > > at 0,0,0): > >http://www.creativenorth.co.uk/post-content/away007.png > > > It's worth noting that the same results are seen if the Mirror's > > recenter parameter is set to be false. > > > -Wex > > > On Mar 4, 1:16 pm, Fabrice3D <fabric...@gmail.com> wrote: > >> Mirror with prop "x", if the model is at 0,0,0 AND recentered AND > >> duplicate mesh is false, will perfectly mirror. > >> The class doesn't recenter the mesh for you, simply because you might no > >> want it to do it. > > >> Fabrice > > >> On Mar 4, 2010, at 1:44 PM, Wex wrote: > > >>> Indeed, after further debugging I determined that it was Mirroring the > >>> LoaderCube and not the final mesh. > > >>> I've added an event handler via addOnSuccess() and now I manage to > >>> flip the right mesh. Not 100% about how it's flipping right now as it > >>> doesn't seem to flip about the world origin and the +/- options don't > >>> seem to do the right thing as I would expect. However, I'll do some > >>> more looking into the issue before making a formal query about it. > > >>> Thanks for the help. > > >>> -Wex > > >>> On Mar 4, 12:18 pm, Fabrice3D <fabric...@gmail.com> wrote: > >>>> then you do not target the right mesh... > >>>> Drop your model in Prefab, select your mesh and open mirror panel.. > >>>> just to see whats happening... > > >>>> Fabrice > > >>>> On Mar 4, 2010, at 1:03 PM, Wex wrote: > > >>>>> Cheers for replying. I've tried all the flips. Just done x+ and x- > >>>>> again to be sure; still nothing. > > >>>>> Also, the object isn't at 0,0,0. I move it as shown in the posted > >>>>> code. > > >>>>> -Wex > > >>>>> On Mar 4, 11:23 am, Fabrice3D <fabric...@gmail.com> wrote: > >>>>>> it might do it, but no being obvious... especially if your model is at > >>>>>> 0,0,0 and symetrical > >>>>>> try x+ or x- just to see. > > >>>>>> Fabrice > > >>>>>> On Mar 4, 2010, at 12:08 PM, Wex wrote: > > >>>>>>> Been banging my head against this for a few hours now... for some > >>>>>>> reason when I mirror a mesh loaded from a 3DS file, it doesn't do > >>>>>>> anything. Here's the code I'm testing with: > > >>>>>>> var mat:ShadingColorMaterial = new ShadingColorMaterial(0x00FF00); > >>>>>>> var sphere:Sphere = new Sphere( { material:mat, segmentsH:6, > >>>>>>> segmentsW:6, radius:10 } ); > >>>>>>> sphere.x = -20; > >>>>>>> sphere.z = -200; > >>>>>>> m_view.scene.addChild(sphere); > >>>>>>> Mirror.apply(sphere, "x"); > > >>>>>>> var mesh:Loader3D = Max3DS.load("wall.3DS"); > >>>>>>> mesh.x = -20; > >>>>>>> mesh.z = -200; > >>>>>>> m_view.scene.addChild(mesh); > >>>>>>> Mirror.apply(mesh, "x"); > > >>>>>>> The sphere mirrors wonderfully, but the 3DS just shows up as normal. > >>>>>>> I've dumped a load of trace-ouputs in Mirror.as to see if it's doing > >>>>>>> anything, and it does reach the obj.addFace call; all the verts seem > >>>>>>> to be mirrored as expected... so I'm at a loss at to what's going on. > > >>>>>>> I'm running v3.4.0 of Away. > > >>>>>>> Any ideas?