I've made some changes to Line3D.as (using Particles.as ar reference)

_isClip = _screenZ < 0; //line added to function update
if (!visible || isClip) //line changed to function render

Now Lines behind the camera are correctly clipped, I don't know if
this is really correct but it seems to work for my app without side
effects.


package away3dlite.core.base
{
        import away3dlite.arcane;
        import away3dlite.containers.Lines;
        import away3dlite.core.IDestroyable;
        import away3dlite.materials.LineMaterial;

        import flash.display.BitmapData;
        import flash.display.Graphics;
        import flash.geom.Matrix3D;
        import flash.geom.Point;
        import flash.geom.Rectangle;
        import flash.geom.Utils3D;
        import flash.geom.Vector3D;

        use namespace arcane;

        /**
         * Line
         * @author katopz
         */
        public class Line3D implements IRenderable, IDestroyable
        {
                /** @private */
                protected var _isDestroyed:Boolean;

                public var id:String;
                public var visible:Boolean = true;
                protected var _isClip:Boolean = false;

                public function get isClip():Boolean
                {
                        return _isClip;
                }

                private var _screenZ:Number;
                public function get screenZ():Number
                {
                        return _screenZ;
                }

                // link list
                public var next:Line3D;
                public var prev:Line3D;

                public var parent:Lines;
                public var graphics:Graphics;
                public var bitmapData:BitmapData;

                // position
                private var _position:Vector3D;
                private var _beginPosition:Vector3D;
                private var _endPosition:Vector3D;

                private var _transformPosition:Vector3D;
                private var _beginTransformedPosition:Vector3D;
                private var _endTransformedPosition:Vector3D;

                private var _point:Point = new Point();
                private var _point0:Point = new Point();
                private var _rect:Rectangle = new Rectangle();

                public var material:LineMaterial;

                public function Line3D(beginPosition:Vector3D, 
endPosition:Vector3D,
material:LineMaterial)
                {
                        // middle of line
                        _position = beginPosition.add(endPosition);
                        _position.scaleBy(.5);

                        _beginPosition = beginPosition;
                        _endPosition = endPosition;
                        _transformPosition = beginPosition.length < 
_endPosition.length ?
beginPosition : _endPosition;

                        this.material = material;
                        updateMaterial();
                }

                private function updateMaterial():void
                {
                        material.isDirty = false;

                        if (parent)
                                parent.isDirty = true;
                }

                public function get transformPosition():Vector3D
                {
                        return _transformPosition;
                }

                public function update(viewMatrix3D:Matrix3D,
transformMatrix3D:Matrix3D = null):void
                {
                        // dirty
                        if (material.isDirty)
                                updateMaterial();

                        // bypass
                        var Utils3D_projectVector:Function = 
Utils3D.projectVector;

                        _beginTransformedPosition = 
Utils3D_projectVector(viewMatrix3D,
Utils3D_projectVector(transformMatrix3D, _beginPosition));
                        _endTransformedPosition = 
Utils3D_projectVector(viewMatrix3D,
Utils3D_projectVector(transformMatrix3D, _endPosition));

                        // update position
                        _transformPosition = Utils3D_projectVector(viewMatrix3D,
Utils3D_projectVector(transformMatrix3D, _position));
                        _screenZ = _transformPosition.w;

                        _isClip = _screenZ < 0; //line added
                }

                public function render(x:Number, y:Number, graphics:Graphics,
zoom:Number, focus:Number):void
                {
                        if (!visible || isClip) //line changed
                                return;

                        // draw to bitmap?
                        if (bitmapData)
                        {
                                drawLine(x, y);
                                return;
                        }

                        // or draw to parent or child canvas?
                        if (!this.graphics)
                                this.graphics = graphics;

                        // draw
                        graphics.lineStyle(material.thickness, material.color);
                        graphics.moveTo(_beginTransformedPosition.x,
_beginTransformedPosition.y);
                        graphics.lineTo(_endTransformedPosition.x,
_endTransformedPosition.y);
                        graphics.endFill();
                }

                protected function drawLine(x:Number, y:Number):void
                {
                        var color:int = int(material.color);

                        var deltaY:int = _endTransformedPosition.y -
_beginTransformedPosition.y;
                        var deltaX:int = _endTransformedPosition.x -
_beginTransformedPosition.x;
                        var isYLonger:Boolean = false;

                        x += _beginTransformedPosition.x;
                        y += _beginTransformedPosition.y;

                        if ((deltaY ^ (deltaY >> 31)) - (deltaY >> 31) > 
(deltaX ^ (deltaX
>> 31)) - (deltaX >> 31))
                        {
                                deltaY ^= deltaX;
                                deltaX ^= deltaY;
                                deltaY ^= deltaX;

                                isYLonger = true;
                        }

                        var inc:int = deltaX < 0 ? -1 : 1;
                        var multDiff:Number = deltaX == 0 ? deltaY : deltaY / 
deltaX;

                        bitmapData.lock();

                        if (isYLonger)
                        {
                                for (var i:int = 0; i != deltaX; i += inc)
                                        bitmapData.setPixel32(int(x + i * 
multDiff), int(y + i), color);
                        }
                        else
                        {
                                for (i = 0; i != deltaX; i += inc)
                                        bitmapData.setPixel32(int(x + i), int(y 
+ i * multDiff), color);
                        }

                        bitmapData.unlock();
                }

                public function get destroyed():Boolean
                {
                        return _isDestroyed;
                }

                public function destroy():void
                {
                        _isDestroyed = true;

                        next = null;
                        prev = null;

                        parent = null;

                        if (graphics)
                                graphics.clear();
                        graphics = null;

                        if (bitmapData)
                                bitmapData.dispose();
                        bitmapData = null;

                        _beginPosition = null;
                        _endPosition = null;

                        _transformPosition = null;
                        _beginTransformedPosition = null;
                        _endTransformedPosition = null;

                        _point = null;
                        _point0 = null;
                        _rect = null;

                        if (material)
                                material.destroy();
                        material = null;
                }
        }
}

Reply via email to