protected override bool _OnRegister(TorqueObject owner)
        {
            if (!base._OnRegister(owner))
                return false;

            // keep track of the owning scene object
            _platform = owner as T2DSceneObject;

            // grab a reference to the owner's platform component
            _platformComponent = owner.Components.FindComponent<SolidPlatformComponent>();

            Assert.Fatal(_platform != null && _platformComponent != null, "PlatformBehavior - Invalid owner or missing PlatformComponent on owner.");

            return true;
        }
        /// <summary>
        /// Update whether or not the Actor is on some sort of "ground" (specifically, any type of platform).
        /// </summary>
        /// <param name="elapsed">Elapsed time passed from _postUpdate.</param>
        /// <returns>True if the Actor is standing on a ground surface. This value can also be accessed via the public OnGround property.</returns>
        private bool _updateOnGround(float elapsed)
        {
            // make sure we're alive
            if (!_alive)
                return false;

            // run pickGround
            _pickGround(elapsed);

            // init vars
            float groundMinY = 0;
            float groundLowestDot = 0;
            T2DSceneObject newGroundObject = null;
            SolidPlatformComponent newPlatformComponent = null;
            Vector2 platformVel = Vector2.Zero;
            float velMod = 0;

            // clear the active platforms list
            _activePlatforms.Clear();

            // check pick results
            foreach (ISceneObject sobj in _containerQueryResults)
            {
                // skip if the object is not a platform object type
                if (!(sobj as T2DSceneObject).TestObjectType(PlatformerData.PlatformObjectType))
                    continue;

                // grab the platform component of this object
                SolidPlatformComponent platComp = (sobj as T2DSceneObject).Components.FindComponent<SolidPlatformComponent>();

                // skip if it doesn't have a platform component
                // or it's platform component is marked as disabled
                if (platComp == null || !platComp.PlatformEnabled)
                    continue;

                // do extra checks for normal one-way platforms
                if (platComp is OneWayPlatformComponent)
                {
                    // skip this platform if we're jumping down
                    if (!CanActivatePlatforms)
                        continue;

                    // skip this platform if the actor is climbing -and- it's possible to climb through this platform
                    if (_Climbing && (platComp as OneWayPlatformComponent).CanClimbThrough)
                        continue;
                }

                // do a poly check against this ground object
                _testGroundPolyMove(sobj as T2DSceneObject);

                // if there were no collisions with this object, skip it
                if (_groundCollisionList.Count == 0)
                    continue;

                // chose a ground object and activate all platforms
                for (int i = 0; i < _groundCollisionList.Count; i++)
                {
                    // skip vertical walls.. duh >_<
                    if (_groundCollisionList[i].Normal.Y > _maxGroundNormalY)
                        continue;

                    // get the ground object's velocity
                    if ((sobj as T2DSceneObject).Physics != null)
                        platformVel = (sobj as T2DSceneObject).Physics.Velocity;
                    else
                        platformVel = Vector2.Zero;

                    // get the dot product of the actor's velocity relative to the platform's velocity
                    Vector2 ourVel = _actor.Physics.Velocity - platformVel;

                    // normalize the velocity only if it's not zero
                    //(this avoids "divide by zero" errors)
                    if (ourVel != Vector2.Zero)
                        ourVel.Normalize();

                    float dot = Vector2.Dot(ourVel, _groundCollisionList[i].Normal);

                    // skip platforms we are moving away from
                    // (allows us to move through one-ways! because we ignore them here they
                    // are omitted from the active platforms list, which is checked in TestEarlyOut)
                    if (dot > Epsilon.Value)
                        continue;

                    // if we are on a slope, make sure to find an exact ground contact position
                    if (Math.Abs(_groundCollisionList[i].Normal.X) > Epsilon.Value)
                    {
                        // get the offset based on direction
                        float directionOffset = 0;

                        if (_groundCollisionList[i].Normal.X > 0)
                        {
                            if (_actor.FlipX)
                                directionOffset = _ActorMaxX;
                            else
                                directionOffset = -_ActorMinX;
                        }
                        else
                        {
                            if (_actor.FlipX)
                                directionOffset = _ActorMinX;
                            else
                                directionOffset = -_ActorMaxX;
                        }

                        // get the X difference
                        float xDiff = _groundCollisionList[i].Position.X - (_actor.Position.X - directionOffset);

                        // get an appropriate y difference along the surface
                        float yDiff = xDiff * (_groundCollisionList[i].Normal.X / _groundCollisionList[i].Normal.Y);

                        // modify the ground contact position
                        T2DCollisionInfo newInfo = _groundCollisionList[i];
                        newInfo.Position = newInfo.Position + new Vector2(xDiff, yDiff);
                        _groundCollisionList[i] = newInfo;
                    }

                    // choose a velocity modifier to use when checking one-way platforms
                    // (if on the ground, use X velocity; if in the air, use Y velocity)
                    if (_onGround)
                        velMod = Math.Abs(_actor.Physics.VelocityX) * elapsed;
                    else
                        velMod = Math.Abs(_actor.Physics.VelocityY) * elapsed;

                    velMod += _groundCheckYThreshold;

                    // make sure we are above the potential ground object's collision point
                    // (some leeway is given based on penetration and ground check threshold)
                    if (platComp is OneWayPlatformComponent
                        && _actor.Position.Y + _actorMaxY - _groundCheckYThreshold - velMod > _groundCollisionList[i].Position.Y)
                        continue;

                    // add the one-way platform component to the list of currently active platforms
                    // (if the platform reached this point it's a platform that we might collide with
                    // .. in other words, it is either a solid platform or a one-way platform and
                    // we are moving either parallel to the surface or towards the surface in some way)
                    if (platComp is OneWayPlatformComponent && CanActivatePlatforms)
                    {
                        (platComp as OneWayPlatformComponent).PlatformActive = true;
                        _activePlatforms.Add(platComp.SceneObject);
                    }

                    // modify the dot product to force the following platform selection to favor angled
                    // platforms a litle more than they would otherwise
                    // (this is done specifically to avoid a terrible and obnoxious case where you are
                    // falling down towards the intersection of a flat one-way plat and a sloped one-way plat
                    // and the actor chooses the flat one, causing you to run straight through the slope.
                    // this happens because at the time that you hit the ground your velocity is more
                    // directly towards the flat platform than the sloped one. it's extremely annoying.
                    // this bug still prevails sometimes, despite my best efforts. the only other solution
                    // I can think of would be to support multiple ground objects - WNF for initial release)
                    float fancyDot = dot - (1 + (_groundCollisionList[i].Normal.Y / 1.1f));

                    // if our velocity is more directly into this platform than the last
                    // or it's the first platform we got to, grab its info
                    // (note that if dot is equal, this check will always prefer the
                    // current ground object over a new one to avoid needless assignments
                    // later on in this method)
                    if (newGroundObject == null
                        || (_groundCollisionList[i].Position.Y < groundMinY)
                        || (_onGround && (fancyDot < groundLowestDot
                                        || ((!_moveLeft && !_moveRight) || fancyDot == groundLowestDot) && sobj == _groundObject)))
                    {
                        // grab highest point so far if this is the first ground object
                        if (newGroundObject == null)
                            groundMinY = _groundCollisionList[i].Position.Y;

                        // store values for this ground object
                        newGroundObject = sobj as T2DSceneObject;
                        newPlatformComponent = platComp;
                        groundLowestDot = fancyDot;
                        _groundSurfaceNormal = _groundCollisionList[i].Normal;
                        _groundContactPosition = _groundCollisionList[i].Position;
                        _groundPenetration = _groundCollisionList[i].Penetration;
                    }

                    // record the highest ground contact position found
                    if (_groundCollisionList[i].Position.Y < groundMinY)
                        groundMinY = _groundCollisionList[i].Position.Y;
                }
            }

            // deactivate all unused platforms
            for (int i = 0; i < _previouslyActivePlatforms.Count; i++)
            {
                if (!_activePlatforms.Contains(_previouslyActivePlatforms[i]))
                {
                    OneWayPlatformComponent platComp = _previouslyActivePlatforms[i].Components.FindComponent<OneWayPlatformComponent>();
                    platComp.PlatformActive = false;
                    _previouslyActivePlatforms.Remove(_previouslyActivePlatforms[i]);
                    i--;
                }
            }

            // update previously active platforms list
            for (int i = 0; i < _activePlatforms.Count; i++)
            {
                if (!_previouslyActivePlatforms.Contains(_activePlatforms[i]))
                    _previouslyActivePlatforms.Add(_activePlatforms[i]);
            }

            // if no valid ground objects found...
            if (newGroundObject == null)
            {
                // notify current ground component that we are leaving (if newly airborne)
                if (_onGround && _groundObjectComponent != null)
                    _groundObjectComponent.ActorLeft(this);

                // set onGround flag to false
                _previouslyOnGround = _onGround;
                _onGround = false;

                // return false
                return false;
            }

            // set the onGround flag to true
            _onGround = true;

            // if this is a new ground object -and- we were on the ground before
            // (we ran from one platform to another without leaving the ground)
            if (newGroundObject != _previousGroundObject && _previouslyOnGround)
            {
                // notify the previous ground component we're leaving
                // (this would not get called otherwise)
                if (_groundObjectComponent != null)
                    _groundObjectComponent.ActorLeft(this);
            }

            // if this is a new ground component -or- we just landed
            // (either running from one to the other, or just landing on a new one)
            // (in other words: every platform we use and only when we first get it)
            if (newGroundObject != _previousGroundObject || !_previouslyOnGround)
            {
                // update previous ground object for next check
                _previousGroundObject = _groundObject;

                // record the ground object that we found
                _groundObject = newGroundObject;

                // find the new ground component
                _groundObjectComponent = newPlatformComponent;

                // set the ground force and friction based on the ground component
                // (note: PlatformFriction property pulls friction value from owner's T2DPhysicsMaterial)
                if (_groundObjectComponent != null)
                {
                    _groundSurfaceForce = _groundObjectComponent.SurfaceForce;
                    _groundFriction = _groundObjectComponent.PlatformFriction;
                }
                else
                {
                    // no ground object component..
                    // just init them to normal values
                    _groundSurfaceForce = 0;
                    _groundFriction = 1;
                }

                // notify the new ground component we arrived
                if (_groundObjectComponent != null)
                    _groundObjectComponent.ActorLanded(this);

                // notify the controller of this actor that it landed on something
                if (Controller != null)
                    (Controller as ActorController).ActorLanded(this, _groundObject);

                // instantly remove any inherited velocity directly toward or away from the surface of the ground object
                float dot = Vector2.Dot(_inheritedVelocity - platformVel, _groundSurfaceNormal);
                _inheritedVelocity = _inheritedVelocity - dot * _groundSurfaceNormal;

                // make sure Climbing is set to false
                if (_Climbing)
                    _Climbing = false;

                // zero out platform error
                // (this can accumulate over a series of collisions with the same platform.
                // must be cleared so each platform can be corrected properly, if neccesary.
                // this value will remain zero for the vast majority of all actor movement.)
                if (_platformError != Vector2.Zero)
                    _platformError = Vector2.Zero;

                // modify the process list so we get physics updates after the ground object we're standing on
                ProcessList.Instance.SetProcessOrder(_actor, _groundObject);
            }

            // if we wound up with a Y value beneath the highest found
            // modify the one we have to be match the highest
            // (sounds crazy, but happens a lot when running between sloped platforms)
            if (_groundContactPosition.Y > groundMinY)
            {
                // get the y difference
                float yDiff = groundMinY - _groundContactPosition.Y;

                // init xDiff to zero
                float xDiff = 0.0f;

                // get an appropriate x difference along the surface
                if (_groundSurfaceNormal.X != 0.0f)
                    xDiff = yDiff * (_groundSurfaceNormal.Y / _groundSurfaceNormal.X);

                // flip the x difference based on the direction we are going
                if (_groundSurfaceNormal.X < 0)
                    xDiff *= -1;

                // modify the ground contact position
                _groundContactPosition += new Vector2(xDiff, yDiff);
            }

            // get the previous position for move clamping
            Vector2 prevPos = _previousPosition;

            // factor in platform movement in the Y direction
            if (_groundObject.Physics != null && Math.Abs(_groundObject.Physics.VelocityY) > Epsilon.Value)
            {
                // get the vel diff this tick
                Vector2 velDiff = _groundObject.Physics.Velocity * elapsed;

                // modify contact position and previous position by vel diff
                _groundContactPosition += velDiff;
                prevPos += velDiff;
            }

            // get the new position on the ground
            Vector2 newPosition = new Vector2(_actor.Position.X, _groundContactPosition.Y - _ActorMaxY) + _platformError;

            // if the platform is slanted, get a more exact offset
            if (_previouslyOnGround && newPosition.X != prevPos.X
                && _groundSurfaceNormal == _previousSurfaceNormal && Math.Abs(_groundSurfaceNormal.X) > Epsilon.Value)
            {
                // get the desired move vector
                Vector2 desiredMoveVector = newPosition - prevPos;

                // get the dot product of the move vector and the ground normal
                float moveDot = Vector2.Dot(desiredMoveVector, _groundSurfaceNormal);

                // get the move vector corrected by the surface normal
                Vector2 correctedMoveVector = desiredMoveVector - (moveDot * _groundSurfaceNormal);

                // modify newPosition's Y component by the difference
                newPosition = new Vector2(newPosition.X, newPosition.Y + (correctedMoveVector.Y - desiredMoveVector.Y));
            }

            // snap to the ground
            _actor.Position = newPosition;

            // record several states at the end of this update
            _previouslyOnGround = _onGround;
            _previousPosition = newPosition;
            _previousSurfaceNormal = _groundSurfaceNormal;

            // record the last known onGround time
            // (which is.. right now!)
            _lastOnGroundTime = TorqueEngineComponent.Instance.TorqueTime;

            // record the current offset from the platform
            // (this is just useful to have sometimes)
            _platformOffset = _actor.Position - _groundObject.Position;

            // return true
            return true;
        }