예제 #1
0
        private static SceneGraph pickClosestObject(SceneGraph Root, Matrix ViewProj, Ray ViewRay2)
        {
            // TODO KAM: This totally isn't working.
            // (1) If the node we're looking at may be picked, select it
            //var toWorld = Matrix.Invert(Camera.GetViewMatrix() * ProjMatrix);

            //viewRay = new Ray(Vector3.TransformCoordinate(viewRay.Position, toWorld), Vector3.TransformNormal(viewRay.Direction, toWorld));
            //viewRay.Direction.Normalize();

            var invWorld = Matrix.Invert(Root.WorldTransform);
            var oVR2     = new Ray(ViewRay2.Position, ViewRay2.Direction);

            oVR2.Direction = Vector3.TransformNormal(oVR2.Direction, invWorld);
            oVR2.Position  = Vector3.TransformCoordinate(oVR2.Position, invWorld);
            oVR2.Direction.Normalize();

            var   boundingBox = Root.GetBoundingBox();
            float dist;

            if (boundingBox != null)
            {
                boundingBox = (Ray.Intersects(oVR2, boundingBox.Value, out dist)) ? boundingBox : null;
            }
            var element = (boundingBox == null) ? null : Root;

            // (2) Find all children picked
            foreach (var child in Root.Children)
            {
                BoundingBox?childbox;
                var         childret = pickClosestObject(child.Value, ViewProj, ViewRay2);
                if (childret == null)
                {
                    childbox = null;
                }
                else
                {
                    childbox = childret.GetBoundingBox();
                }

                if (boundingBox == null)
                {
                    boundingBox = childbox;
                    element     = childret;
                }
                else if (childbox != null)
                {
                    float currDist, otherDist;
                    Ray.Intersects(oVR2, boundingBox.Value, out currDist);

                    var oVR3      = new Ray(ViewRay2.Position, ViewRay2.Direction);
                    var cInvWorld = Matrix.Invert(childret.WorldTransform);
                    oVR3.Direction = Vector3.TransformNormal(oVR3.Direction, cInvWorld);
                    oVR3.Position  = Vector3.TransformCoordinate(oVR3.Position, cInvWorld);

                    Ray.Intersects(oVR3, childbox.Value, out otherDist);

                    // (3) Take the smallest of the list and return it
                    if (otherDist < currDist)
                    {
                        boundingBox = childbox;
                        element     = child.Value;
                    }
                }
            }

            return(element);
        }