Fitting all objects into the view

Jul 4, 2011 at 1:26 PM

Hi there

I would like to open up my application, 'fitting' the window to the objects in the scene.  Is there some way that I can calculate this?  My 'zoom' process moves the camera along a path (like a camera truck)... preferably, I'd like to determine at what point to place my camera so that all of the objects are visible to the user (given that I'm looking at the center of the Scene (0,0,0) and that I'd just move in the Z axis).

Is there a way to check that an object is visible in the Viewport?  If so, I'd just move the camera closer (decrease my Z-value) until it wasn't... then move back slightly.

Thanx,

Peter

 

Coordinator
Jul 10, 2011 at 11:54 AM

There are ways of calculating this - from the top of my head though, I can't give you a straight answer. 

But for checking wether or not something is within the view, there is a method on the Camera (IView) that is called IsInView(). That could be used for doing that. 

Basically, out of the box, when  you have defined a camera on the Game, you can go to Game.Camera.IsInView(....)

Jul 11, 2011 at 1:01 PM

That's excellent, that's the function I was looking for (just didn't know where to look for it or what it was called).

Do you know if this function returns true is ANY part of the boundingsphere is visible or only if ALL of the boundsphere is visible?  Or rather 'in view' as I assume this doesn't take the IsVisible property of the mesh into account.

Thanx,

Peter

 

Jul 11, 2011 at 2:56 PM

Maybe I am misunderstanding the use of the IsInView call, but whatever I pass it... it returns true.  I've tried passing it the boundingbox of my mesh and even when I'm zoomed in and the camera position and target are coincident, it tells me it's in view.

I wrote a couple return values on my mesh (LowestPoint and HighestPoint) and return the Lowest (X,Y) and the Highest (X,Y) sets and then I'm testing those and it tells me, yes, they're visible.

Even passing a ridiculously large value which is even beyond my FOV, it returns true.

Not sure if I've made an error in how I'm using this or if there's something in the library.  Any thoughts?

Jul 11, 2011 at 4:41 PM

OK, spent some time investigating this and I've gone as far as my 3D math abilities can take me.

Looking at the library... it seems that the Dot Product call to test if either the BoundingSphere or Point is in the plane, returns a distance of 0.  Not sure what that means, but that's what it is giving me.

The code from the library is:

public FrustumIntersection IsPointInFrustum(Vector vector)
        {
            for (var planeIndex = 0; planeIndex < _planes.Length; planeIndex++)
            {
                var plane = _planes[planeIndex];
                var distance = plane.GetDistanceFromVector(vector);
                if (distance < 0)
                {
                    return FrustumIntersection.Outside;
                }
            }
            return FrustumIntersection.Inside;

        }

        public FrustumIntersection IsSphereInFrustum(Vector vector, float radius)
        {
            float distance = 0;
            for (var planeIndex = 0; planeIndex < _planes.Length; planeIndex++)
            {
                var plane = _planes[planeIndex];
                distance = plane.GetDistanceFromVector(vector);

                if (distance < -radius)
                {
                    return FrustumIntersection.Outside;
                }
                else if (distance < radius)
                {
                    return FrustumIntersection.Intersect;
                }
            }
            return FrustumIntersection.Inside;
        }

Either one of these are falling out to return '.Inside' which may be true, but then this isn't what I'm trying to do. 

Thinking the issue was related to view-updates, I put a DispatcherTimer on my FloatingWindow to update the view every 10ms and zoom out a little more, checking to see if the object was in view.

       void _wireframe_OnMeshLoadCompleted(DNC2Mesh dnc2mesh, EventArgs e)
        {
            gameWireframe.Scene.AddNode(dnc2mesh);
            gameWireframe.Camera.Target = dnc2mesh.Centerpoint; // dnc2mesh.Centroid(dnc2mesh.Vertices.ToArray());

            dnc2mesh.PrepareBoundingSphere();
 
            // zoom in on the center of my mesh so we can pan backwards
            float currentz = 0;
            SetCameraAndTarget(new Coordinate(0, 0, currentz), 0, 180);
            int direction = 1;

            // create a timer which I can then use to pan back
            DispatcherTimer zoomtimer = new DispatcherTimer();
            zoomtimer.Tick += new EventHandler(zoomtimer_Tick);
            zoomtimer.Interval = new TimeSpan(0, 0, 0, 0, 10);
            zoomtimer.Start();

        }

        void zoomtimer_Tick(object sender, EventArgs e)
        {
            if ((gameWireframe.Camera.Frustum.IsSphereInFrustum(_wireframe.BoundingSphere.Center, _wireframe.BoundingSphere.Radius) != FrustumIntersection.Outside)
                && (_zoomSlider.Value >= (float)_zoomSlider.Maximum / 2))
                _zoomSlider.Value += 1;
            else
                ((DispatcherTimer)sender).Stop();
        }

Any help you can shed here would be appreciated.

Oh, and I also realized that I needed to explicitly PrepareBoundingSphere to get the values populated, that's why I do that after adding the item.

Peter

 


Coordinator
Aug 8, 2011 at 4:26 PM

Thanks for the details. 

I'm bogged down with work these days - but I'll put it up as an issue to look at. I'm using these same methods for the frustum clipping, so I'm really hoping they work. :) 

 

Sorry for not being able to jump straight at this problem.

Coordinator
Aug 8, 2011 at 4:26 PM
This discussion has been copied to a work item. Click here to go to the work item and continue the discussion.