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?

Reply via email to