[vtkusers] How to use backface culling with polylines
Aashish Chaudhary
aashish.chaudhary at kitware.com
Sat Nov 20 16:00:59 EST 2010
Jim, Donny, Gobbi
This is nice! I think we can put this inside the geovis as vtkGeoClip or
something along the lines? I will talk to Jeff about it. Would you be
interested in making this addition?
Thanks,
On Sat, Nov 20, 2010 at 1:31 PM, Jim Peterson <jimcp at cox.net> wrote:
> Donny, just to be sure we have a true normalized vector for the rest of the
> calcs, I think I would make the clop position an array, and then use
> vtkMath::Normalize(clipPos); to be sure we have a normal that has a length
> 1. soSo I think the normal calculation should probably be change from:
>
>
> double dx = earthcenter[0] - camerapos [0];
> double dy = earthcenter[1] - camerapos [1];
> double dz = earthcenter[2] - camerapos [2];
> double distance = sqrt(dx*dx + dy*dy + dz*dz);
>
> double nx = -(dx/distance);
> double ny = -(dy/distance);
> double nz = -(dz/distance);
>
> to something like this so that all of the point locations and vectors keep
> their parts together:
>
> double dv[] = {0.,0.,0.,}
> dv[0] = camerapos[0] - earthcenter[0]; // subtract earthcenter from
> camera pos
> dv[1] = camerapos[1] - earthcenter[1];
> dv[2] = camerapos[2] - earthcenter[2];
> double distance = sqrt(dv[0]*dv[0] + dv[1]*dv[1] + dv[2]*dv[2]);
>
> double nv[] = {0.,0.,0.,};
> nv[0] = (dv[0]/distance); // no inversion with the above subtract
> nv[1] = (dv[1]/distance);
> nv[2] = (dv[2]/distance); vtkMath::Normalize(nv); // assert
> normalize to unit length
> Also, if Altitude is greater than earth radius, we would just use the earth
> center as the clip plane location.
>
> Glad I could help.
> Jim
>
>
> Donny wrote:
>
>> THANKS JIM!!! That worked. I had to change one more bug, the element
>> number
>> of earthcenter was element 0 for each dimension. Here is what I have now:
>>
>> double altitude = distance - vtkGeoMath::EarthRadiusMeters();
>> double clipdist = vtkGeoMath::EarthRadiusMeters() - altitude;
>> double pox = earthcenter[0]+(clipdist*nx);
>> double poy = earthcenter[1]+(clipdist*ny);
>> double poz = earthcenter[2]+(clipdist*nz);
>>
>> You are correct in that the dolly out zoom in affect was happening
>> previously. It just appeared at first glance that it was inverse.
>>
>> It is amazing how precise the horizon clips now. It is right on the money.
>> You made my day. I can't thank all of you enough for your help.
>>
>> Maybe this could be incorporated into vtk. I just don't know where.
>>
>> Thanks.
>>
>> -----Original Message-----
>> From: Jim Peterson [mailto:jimcp at cox.net] Sent: Saturday, November 20,
>> 2010 11:18 AM
>> To: Donny
>> Cc: 'David Gobbi'; 'Aashish Chaudhary'; 'Sebastien Jourdain';
>> vtkusers at vtk.org
>> Subject: Re: [vtkusers] How to use backface culling with polylines
>>
>> Sorry, I did say untested.... this
>>
>> double pox = earthcenter[0]+(clipdist*nx);
>> double poy = earthcenter[0]+(altitude*ny);
>> double poz = earthcenter[0]+(altitude*nz);
>>
>>
>> should have been:
>>
>> double pox = earthcenter[0]+(clipdist*nx);
>> double poy = earthcenter[0]+(clipdist*ny);
>> double poz = earthcenter[0]+(clipdist*nz);
>>
>> I am not sure I understand going higher shortens the horizon. This is
>> contrary to the real geometry like
>> http://en.wikipedia.org/wiki/Horizon#Approximate_formulas explains the
>> calculations for the real world. It sounds like you want to change the
>> camera viewangle in proportion to the altitude to "zoom in" in the target
>> feature as you move away. I think I would call that a dolly-out-zoom-in
>> video effect. Camera angle would not affect the visible horizon distance,
>> just how much of it is in the field of view, in my opinion.
>>
>> Hope that helped,
>> Jim
>>
>> Donny wrote:
>>
>>
>>> Ok, I am close. The plane is acting just opposite of what I want though.
>>>
>>>
>> The
>>
>>
>>> higher up on the horizon I go the less of the horizon I see, and the
>>> lower
>>> on the horizon I go the more I see (including past the horizon).
>>>
>>> Here is the code:
>>>
>>> double dx = earthcenter[0] - camerapos [0];
>>> double dy = earthcenter[1] - camerapos [1];
>>> double dz = earthcenter[2] - camerapos [2];
>>> double distance = sqrt(dx*dx + dy*dy + dz*dz);
>>>
>>> double nx = -(dx/distance);
>>> double ny = -(dy/distance);
>>> double nz = -(dz/distance); double altitude
>>> = distance - vtkGeoMath::EarthRadiusMeters();
>>> double clipdist = vtkGeoMath::EarthRadiusMeters() - altitude;
>>> double pox = earthcenter[0]+(clipdist*nx);
>>> double poy = earthcenter[0]+(altitude*ny);
>>> double poz = earthcenter[0]+(altitude*nz);
>>> m_horizonplane->SetOrigin(pox,poy,poz);
>>> m_horizonplane->SetNormal(nx,ny,nz);
>>>
>>> Thanks.
>>>
>>> -----Original Message-----
>>> From: Jim Peterson [mailto:jimcp at cox.net] Sent: Saturday, November 20,
>>> 2010 10:52 AM
>>> To: Donny
>>> Cc: 'David Gobbi'; 'Aashish Chaudhary'; 'Sebastien Jourdain';
>>> vtkusers at vtk.org
>>> Subject: Re: [vtkusers] How to use backface culling with polylines
>>>
>>> Donny,
>>> assuming all your coordinates are in meters,
>>> What I was trying to say was project the altitude of the camera into the
>>> earth sphere to locate the clipping plane.
>>> so with the normal calculation you have :
>>>
>>> altitude = distance - vtkGeoMath::EarthRadiusMeters();
>>> clipdist = vtkGeoEarth::EarthRadiusMeters() - altitude;
>>> pox = earthcenter[0]+(clipdist*nx);
>>> poy = earthcenter[0]+(altitude*ny);
>>> poz = earthcenter[0]+(altitude*nz);
>>>
>>> Untested of course....
>>>
>>> Jim
>>>
>>> Donny wrote:
>>>
>>>
>>>> Does this look correct to calculate the horizon clipping plane?
>>>>
>>>> double dx = earthcenter[0] - camerapos[0];
>>>> double dy = earthcenter[1] - camerapos[1];
>>>> double dz = earthcenter[2] - camerapos[2];
>>>> double distance = sqrt(dx*dx + dy*dy + dz*dz);
>>>>
>>>> double nx = -(dx/distance);
>>>> double ny = -(dy/distance);
>>>> double nz = -(dz/distance);
>>>>
>>>> //(2 (abs(camera position - globeposition) minus globe radius))
>>>> double pox = 2.0 * (abs(camerapos [0] - earthcenter [0]) -
>>>> vtkGeoMath::EarthRadiusMeters());
>>>>
>>>> double poy = 2.0 * (abs(camerapos [1] - earthcenter [1]) -
>>>> vtkGeoMath::EarthRadiusMeters());
>>>>
>>>> double poz = 2.0 * (abs(camerapos [2] - earthcenter [2]) -
>>>> vtkGeoMath::EarthRadiusMeters());
>>>>
>>>> m_horizonplane->SetOrigin(pox,poy,poz);
>>>> m_horizonplane->SetNormal(nx,ny,nz);
>>>>
>>>> I am not getting the results I expected (the clipping plane is way off).
>>>>
>>>> -----Original Message-----
>>>> From: Jim Peterson [mailto:jimcp at cox.net] Sent: Saturday, November 20,
>>>> 2010 9:03 AM
>>>> To: Donny
>>>> Cc: 'David Gobbi'; 'Aashish Chaudhary'; vtkusers at vtk.org
>>>> Subject: Re: [vtkusers] How to use backface culling with polylines
>>>>
>>>> Donny,
>>>>
>>>> I haven't really tried to get this thought into code, but in a soid
>>>> geometry kind of sense, the horizon from a point of view is generally
>>>> described by a clip somewhere between the observer and the center of the
>>>> sphere, depending on the altitude. the direction of view should not be a
>>>> factor, and how close the clip plane is to the center of the globe depends
>>>> on the altitude. if the observer is at a height of 100' the horizon
>>>> (Excluding other terrain elevation) is 12.25 miles along the surface of the
>>>> sphere. the clip throught the center of the sphere would make the horizon at
>>>> about 6000 miles.
>>>>
>>>> I would expect the clip normal to be the normalized difference between
>>>> the camera position and the globe position, and the approximate clip plane
>>>> position to be the point that is (2 (abs(camera position - globe position)
>>>> minus globe radius)) from the camera toward the globe position.
>>>>
>>>> If the globe happens to be at 0,0,0 that would simplify the calculation
>>>> to just the globe radius and the camera position, but Copernicus changed all
>>>> that....
>>>>
>>>> I haven't really studied the GEOVIS classes, but I would have thought
>>>> visible horizon clipping would be one of the tools. Maybe this should evolve
>>>> into a contribution.
>>>>
>>>> Sounds like an interesting project.
>>>>
>>>> Jim
>>>>
>>>> Donny wrote:
>>>>
>>>>
>>>>> Hello again. I decided to try David's approach with clipping planes.
>>>>>
>>>>>
>>>> Mainly
>>>>
>>>>
>>>>> because I will have quite a few lines when including the county lines
>>>>> in
>>>>> addition to the state lines and I did not want to create that many
>>>>> triangles. I was afraid it would slow down the performance.
>>>>>
>>>>> I have centered the clipping plane at the center of the earth and the
>>>>>
>>>>>
>>>> normal
>>>>
>>>>
>>>>> is always the view normal. This works great when the focus point is on
>>>>>
>>>>>
>>>> the
>>>
>>>
>>>> surface of the earth and I rotate around it. The problem occurs when I
>>>>>
>>>>>
>>>> pan.
>>>>
>>>>
>>>>> This moves the camera focal point and when it is no longer on the
>>>>>
>>>>>
>>>> surface
>>
>>
>>>
>>>>>
>>>> of
>>>>
>>>>
>>>>> the earth the clipping plane will show some details on the other side
>>>>> of
>>>>>
>>>>>
>>>> the
>>>>
>>>>
>>>>> horizon. How can I force a pan operation to pan the focal point on the
>>>>> surface of the earth?
>>>>> Here is the pan code, I am using .NET delegates because of the static
>>>>> function pointer limitation for AddObserver:
>>>>>
>>>>> void OnVtkMiddleMouseDown(unsigned long eventId, System::Object^
>>>>>
>>>>>
>>>> clientData)
>>>>
>>>>
>>>>> {
>>>>> this->m_interactorstyle->StartPan();
>>>>> }
>>>>>
>>>>> void OnVtkMiddleMouseUp(unsigned long eventId, System::Object^
>>>>>
>>>>>
>>>> clientData)
>>>
>>>
>>>> { this->m_interactorstyle->EndPan();
>>>>> }
>>>>>
>>>>> void OnVtkMouseMove(unsigned long eventId, System::Object^ clientData)
>>>>> { switch
>>>>> (this->m_interactorstyle->GetState())
>>>>> {
>>>>> case 1: //VTKIS_ROTATE
>>>>> this->Rotate();
>>>>> break;
>>>>>
>>>>> case 2: //VTKIS_PAN
>>>>> this->Pan();
>>>>> break;
>>>>>
>>>>> case 4: //VTKIS_DOLLY
>>>>> this->Dolly();
>>>>> break;
>>>>> }
>>>>> }
>>>>>
>>>>> void Pan()
>>>>> {
>>>>> // Get the vector of motion
>>>>>
>>>>> double focalPoint[3];
>>>>> double v[3];
>>>>> double p1[4];
>>>>> double p2[4];
>>>>>
>>>>>
>>>>> double* pos = m_camera->GetPosition();
>>>>> double* fp = m_camera->GetFocalPoint();
>>>>>
>>>>> vtkInteractorStyleUser::ComputeWorldToDisplay(m_backgroundrenderer,
>>>>> fp[0], fp[1], fp[2], focalPoint);
>>>>>
>>>>> vtkInteractorStyleUser::ComputeDisplayToWorld(m_backgroundrenderer,
>>>>> m_iren->GetEventPosition()[0], m_iren->GetEventPosition()[1],
>>>>> focalPoint[2], p1);
>>>>>
>>>>> vtkInteractorStyleUser::ComputeDisplayToWorld(m_backgroundrenderer,
>>>>> m_iren->GetLastEventPosition()[0], m_iren->GetLastEventPosition()[1],
>>>>> focalPoint[2], p2);
>>>>>
>>>>> double npos[3];
>>>>> double nfp[3];
>>>>>
>>>>> for (int i = 0; i < 3; i++)
>>>>> {
>>>>> v[i] = p2[i] - p1[i];
>>>>> npos[i] = pos[i] + v[i];
>>>>> nfp[i] = fp[i] + v[i];
>>>>> }
>>>>>
>>>>> m_camera->SetPosition(npos);
>>>>> m_camera->SetFocalPoint(nfp);
>>>>> this->m_iren->Render();
>>>>>
>>>>> }
>>>>>
>>>>> Thanks.
>>>>>
>>>>> -----Original Message-----
>>>>> From: David Gobbi [mailto:david.gobbi at gmail.com] Sent: Thursday,
>>>>> November 18, 2010 9:07 PM
>>>>> To: Donny
>>>>> Cc: vtkusers at vtk.org
>>>>> Subject: Re: [vtkusers] How to use backface culling with polylines
>>>>>
>>>>> You could also add a clipping plane to your vtk mapper that cuts the
>>>>> globe in half, back to front. By adding this plane only to the mapper
>>>>> that renders the lines, you can remove any lines that are past the
>>>>> horizon.
>>>>>
>>>>> David
>>>>>
>>>>>
>>>>> On Thu, Nov 18, 2010 at 7:13 PM, Jim Peterson <jimcp at cox.net> wrote:
>>>>>
>>>>>
>>>>>> Donny,
>>>>>> I think I would run the state lines through a ribbon filter making
>>>>>> them
>>>>>>
>>>>>>
>>>>> into
>>>>>
>>>>>
>>>>>> a triangle strip of some width. the strip would have a backface.
>>>>>>
>>>>>> Jim
>>>>>>
>>>>>> Donny wrote:
>>>>>>
>>>>>>
>>>>>>> Thanks guys for the feedback. I have attached two images to visualize
>>>>>>>
>>>>>>>
>>>>>> what
>>>>>
>>>>>
>>>>>> follows. I hope I can explain this clearly.
>>>>>>>
>>>>>>> I have three renderers that I am adding to the render window.
>>>>>>>
>>>>>>> The first is to contain a textured vtkGlobeSource actor and is called
>>>>>>>
>>>>>>>
>>>>>> the
>>>>
>>>>
>>>>> background renderer.
>>>>>>>
>>>>>>> The second contains several vtkPolyData actors and are lines (State
>>>>>>>
>>>>>>>
>>>>>> and
>>
>>
>>> county boundaries, roads, rivers…), this is called the map renderer.
>>>>>>>
>>>>>>> The Third contains an actor visualizing a weather radar volume, this
>>>>>>>
>>>>>>>
>>>>>> is
>>
>>
>>> called the radar renderer.
>>>>>>>
>>>>>>> The background renderer is always set as layer 0 and so is always
>>>>>>>
>>>>>>>
>>>>>> rendered
>>>>>
>>>>>
>>>>>> first.
>>>>>>>
>>>>>>> The map renderer and radar renderer will alternate between the 1^st
>>>>>>>
>>>>>>>
>>>>>> and
>>
>>
>>> 2^nd layers depending on the view angle of the camera.
>>>>>>>
>>>>>>> If the camera is more than 45 degrees above the horizon then the
>>>>>>> radar
>>>>>>> renderer is layer 1 and the map renderer is layer 2 so that the user
>>>>>>>
>>>>>>>
>>>>>> can
>>>
>>>
>>>>
>>>>>>>
>>>>>> see
>>>>>
>>>>>
>>>>>> the features below the radar volume.
>>>>>>>
>>>>>>> If the camera is less than or equal to 45 degrees above the horizon
>>>>>>>
>>>>>>>
>>>>>> then
>>>
>>>
>>>> the map renderer is layer 1 and the radar renderer is layer 2 so that
>>>>>>>
>>>>>>>
>>>>>> the
>>>>
>>>>
>>>>> radar volume is always in front of the map features.
>>>>>>>
>>>>>>> This works fine until I draw all state lines for the entire US.
>>>>>>>
>>>>>>>
>>>>>> Because
>>
>>
>>> the vtkGlobeSource simulates the curvature of the earth I see the
>>>>>>>
>>>>>>>
>>>>>> backside
>>>>>
>>>>>
>>>>>> of the state lines where they are over the view horizon.
>>>>>>>
>>>>>>> Is there a way I can put the map features and radar volume on the
>>>>>>> same
>>>>>>> renderer and accomplish the same thing?
>>>>>>>
>>>>>>> Thanks.
>>>>>>>
>>>>>>> -----Original Message-----
>>>>>>> *From:* Aashish Chaudhary [mailto:aashish.chaudhary at kitware.com]
>>>>>>> *Sent:* Thursday, November 18, 2010 8:37 AM
>>>>>>> *To:* David Gobbi
>>>>>>> *Cc:* vtkusers at vtk.org; Donny
>>>>>>> *Subject:* Re: [vtkusers] How to use backface culling with polylines
>>>>>>>
>>>>>>> Donny,
>>>>>>>
>>>>>>> Were you talking about hidden lines removal may be?
>>>>>>>
>>>>>>> Thanks,
>>>>>>>
>>>>>>> On Thu, Nov 18, 2010 at 9:03 AM, David Gobbi <david.gobbi at gmail.com
>>>>>>> <mailto:david.gobbi at gmail.com>> wrote:
>>>>>>>
>>>>>>> Jerome is correct, OpenGL culls faces according to the polygon
>>>>>>> winding. So wireframe polygons can be culled, but polylines cannot,
>>>>>>> even if they have normals assigned to them. There are some details in
>>>>>>> the OpenGL FAQ:
>>>>>>> http://www.opengl.org/resources/faq/technical/clipping.htm
>>>>>>>
>>>>>>> David
>>>>>>>
>>>>>>>
>>>>>>> On Wed, Nov 17, 2010 at 11:47 PM, Jérôme <jerome.velut at gmail.com
>>>>>>> <mailto:jerome.velut at gmail.com>> wrote:
>>>>>>>
>>>>>>>
>>>>>>>> Hi Donny,
>>>>>>>>
>>>>>>>> My feeling is that backface culling should not work with polylines
>>>>>>>> because they
>>>>>>>> have actually no face.
>>>>>>>>
>>>>>>>> Jerome
>>>>>>>>
>>>>>>>> 2010/11/18 Donny <donnyz at charter.net <mailto:donnyz at charter.net>>:
>>>>>>>>
>>>>>>>>
>>>>>>>>> I am drawing polylines using vtkPolyData and cannot get backface
>>>>>>>>> culling to
>>>>>>>>> work with them.
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> I ran into this subject
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>
>> http://public.kitware.com/pipermail/vtkusers/2003-January/065023.html
>>
>>
>>>
>>>>>>>>>
>>>>>>>> ,
>>>>>
>>>>>
>>>>>> but
>>>>>>>>> did not help.
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> Any solutions?
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> Donny Zimmerman
>>>>>>>>>
>>>>>>>>> donnyz at charter.net <mailto:donnyz at charter.net>
>>>>>>>>>
>>>>>>>>> 308-227-1756
>>>>>>>>>
>>>>>>>>>
>>>>>>>> _______________________________________________
>>>>>>> Powered by www.kitware.com <http://www.kitware.com>
>>>>>>>
>>>>>>> Visit other Kitware open-source projects at
>>>>>>> http://www.kitware.com/opensource/opensource.html
>>>>>>>
>>>>>>> Please keep messages on-topic and check the VTK FAQ at:
>>>>>>> http://www.vtk.org/Wiki/VTK_FAQ
>>>>>>>
>>>>>>> Follow this link to subscribe/unsubscribe:
>>>>>>> http://www.vtk.org/mailman/listinfo/vtkusers
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> --
>>>>>>> | Aashish Chaudhary
>>>>>>> | R&D Engineer
>>>>>>> | Kitware Inc.
>>>>>>> | www.kitware.com <http://www.kitware.com>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>
>>> ------------------------------------------------------------------------
>>>
>>>
>>>> _______________________________________________
>>>>>>> Powered by www.kitware.com
>>>>>>>
>>>>>>> Visit other Kitware open-source projects at
>>>>>>> http://www.kitware.com/opensource/opensource.html
>>>>>>>
>>>>>>> Please keep messages on-topic and check the VTK FAQ at:
>>>>>>> http://www.vtk.org/Wiki/VTK_FAQ
>>>>>>>
>>>>>>> Follow this link to subscribe/unsubscribe:
>>>>>>> http://www.vtk.org/mailman/listinfo/vtkusers
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>
>>>>>>
>>>>>
>>>>>
>>>>
>>>>
>>>
>>>
>>
>>
>>
>>
>
>
--
| Aashish Chaudhary
| R&D Engineer
| Kitware Inc.
| www.kitware.com
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.vtk.org/pipermail/vtkusers/attachments/20101120/fd99c2e0/attachment.htm>
More information about the vtkusers
mailing list