﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-OpenGL</title><link>http://www.cppblog.com/zmj/</link><description /><language>zh-cn</language><lastBuildDate>Fri, 05 Dec 2008 06:44:59 GMT</lastBuildDate><pubDate>Fri, 05 Dec 2008 06:44:59 GMT</pubDate><ttl>60</ttl><item><title>The Mechanics of Robust Stencil Shadows</title><link>http://www.cppblog.com/zmj/archive/2008/12/04/68559.html</link><dc:creator>zmj</dc:creator><author>zmj</author><pubDate>Thu, 04 Dec 2008 06:23:00 GMT</pubDate><guid>http://www.cppblog.com/zmj/archive/2008/12/04/68559.html</guid><wfw:comment>http://www.cppblog.com/zmj/comments/68559.html</wfw:comment><comments>http://www.cppblog.com/zmj/archive/2008/12/04/68559.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/zmj/comments/commentRss/68559.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/zmj/services/trackbacks/68559.html</trackback:ping><description><![CDATA[<a href="http://www.gamasutra.com/features/20021011/lengyel_01.htm">http://www.gamasutra.com/features/20021011/lengyel_01.htm</a><br>
<h1>The Mechanics of Robust Stencil Shadows</h1>
<!-- #EndEditable --><!-- #BeginEditable "main%20content" -->
<p>The idea of using the stencil buffer to generate shadows has been around for over a decade, but only recently has 3D graphics hardware advanced to the point where using the stencil algorithm on a large scale has become practical. Not long ago, there existed some unsolved problems pertaining to stencil shadows that prevented the algorithm from working correctly under various conditions. Advances have now been made, however, so that stencil shadows can be robustly implemented to handle arbitrarily positioned point lights and infinite directional lights having any desired spatial relationship with the camera. This article presents the intricacies of the entire stencil shadow algorithm and covers every mathematical detail of its efficient implementation.
<h2>Algorithm Overview</h2>
<p>The basic concept of the stencil shadow algorithm is to use the stencil buffer as a masking mechanism to prevent pixels in shadow from being drawn during the rendering pass for a particular light source. This is accomplished by rendering an invisible shadow volume for each shadow-casting object in a scene using stencil operations that leave nonzero values in the stencil buffer wherever light is blocked. Once the stencil buffer has been filled with the appropriate mask, a lighting pass only illuminates pixels where the value in the stencil buffer is zero.
<p>As shown in Figure 1, an object&#8217;s shadow volume encloses the region of space for which light is blocked by the object. This volume is constructed by finding the edges in the object&#8217;s triangle mesh representing the boundary between lit triangles and unlit triangles and extruding those edges away from the light source. Such a collection of edges is called the object&#8217;s silhouette with respect to the light source. The shadow volume is rendered into the stencil buffer using operations that modify the stencil value at each pixel depending on whether the depth test passes or fails. Of course, this requires that the depth buffer has already been initialized to the correct values by a previous rendering pass. Thus, the scene is first rendered using a shader that applies surface attributes that do not depend on any light source, such as ambient illumination, emission, and environment mapping.
<p>&nbsp;
<table height=274 cellSpacing=0 cellPadding=0 width=74 align=center border=0>
    <tbody>
        <tr>
            <td vAlign=top width=5 bgColor=#ccc999 height=3 rowSpan=2>
            <div align=right><img height=11 src="http://www.gamasutra.com/redesign/images/corner_top_left.gif" width=10 align=top> </div>
            </td>
            <td vAlign=top bgColor=#ccc999 colSpan=3 height=3 rowSpan=2><br><img height=315 src="http://www.gamasutra.com/features/20021011/fig_01.gif" width=472> </td>
            <td vAlign=top align=right width=5 bgColor=#ccc999 height=3><img height=11 src="http://www.gamasutra.com/redesign/images/corner_top_right.gif" width=10 align=top></td>
        </tr>
        <tr>
            <td vAlign=bottom align=right width=15 bgColor=#ccc999 rowSpan=2><img height=11 src="http://www.gamasutra.com/redesign/images/corner_bottom_right.gif" width=10 align=bottom></td>
        </tr>
        <tr vAlign=top>
            <td vAlign=bottom align=left width=10 bgColor=#ccc999 height=16><img height=11 src="http://www.gamasutra.com/redesign/images/corner_bottom_left.gif" width=10 align=bottom></td>
            <td vAlign=top bgColor=#ccc999 colSpan=3 height=16>
            <p align=center><font face="Verdana, Arial, Helvetica, sans-serif" size=-1><strong><font face="Verdana, Arial, Helvetica, sans-serif" size=-1>Figure 1. An object&#8217;s shadow volume encloses the region of space for which light is blocked by the object.<br></font></strong></font></p>
            </td>
        </tr>
    </tbody>
</table>
<p>The original stencil algorithm renders the shadow volume in two stages. In the first stage, the front faces of the shadow volume (with respect to the camera) are rendered using a stencil operation that increments the value in the stencil buffer whenever the depth test passes. In the second stage, the back faces of the shadow volume are rendered using a stencil operation that decrements the value in the stencil buffer whenever the depth test passes. As illustrated in Figure 2, this technique leaves nonzero values in the stencil buffer wherever the shadow volume intersects any surface in the scene, including the surface of the object casting the shadow.
<p>&nbsp;
<table height=274 cellSpacing=0 cellPadding=0 width=74 align=center border=0>
    <tbody>
        <tr>
            <td vAlign=top width=5 bgColor=#ccc999 height=3 rowSpan=2>
            <div align=right><img height=11 src="http://www.gamasutra.com/redesign/images/corner_top_left.gif" width=10 align=top> </div>
            </td>
            <td vAlign=top bgColor=#ccc999 colSpan=3 height=3 rowSpan=2><br><img height=479 src="http://www.gamasutra.com/features/20021011/fig_02.gif" width=400> </td>
            <td vAlign=top align=right width=5 bgColor=#ccc999 height=3><img height=11 src="http://www.gamasutra.com/redesign/images/corner_top_right.gif" width=10 align=top></td>
        </tr>
        <tr>
            <td vAlign=bottom align=right width=15 bgColor=#ccc999 rowSpan=2><img height=11 src="http://www.gamasutra.com/redesign/images/corner_bottom_right.gif" width=10 align=bottom></td>
        </tr>
        <tr vAlign=top>
            <td vAlign=bottom align=left width=10 bgColor=#ccc999 height=16><img height=11 src="http://www.gamasutra.com/redesign/images/corner_bottom_left.gif" width=10 align=bottom></td>
            <td vAlign=top bgColor=#ccc999 colSpan=3 height=16>
            <p align=center><font face="Verdana, Arial, Helvetica, sans-serif" size=-1><strong><font face="Verdana, Arial, Helvetica, sans-serif" size=-1>Figure 2. Numbers at the ends of rays emanating from the camera position C represent the values left in the stencil buffer for a variety of cases. The stencil value is incremented when front faces of the shadow volume pass the depth test, and the stencil value is decremented when back faces of the shadow volume pass the depth test. The stencil value does not change when the depth test fails.<br></font></strong></font></p>
            </td>
        </tr>
    </tbody>
</table>
<p>There are two major problems with the method just described. The first is that no matter what finite distance we extrude an object&#8217;s silhouette away from a light source, it is still possible that it is not far enough to cast a shadow on every object in the scene that should intersect the shadow volume. The example shown in Figure 3 demonstrates how this problem arises when a light source is very close to a shadow-casting object. Fortunately, this problem can be elegantly solved by using a special projection matrix and extruding shadow volumes all the way to infinity.
<p>&nbsp;
<table height=274 cellSpacing=0 cellPadding=0 width=74 align=center border=0>
    <tbody>
        <tr>
            <td vAlign=top width=5 bgColor=#ccc999 height=3 rowSpan=2>
            <div align=right><img height=11 src="http://www.gamasutra.com/redesign/images/corner_top_left.gif" width=10 align=top> </div>
            </td>
            <td vAlign=top bgColor=#ccc999 colSpan=3 height=3 rowSpan=2><br><img height=399 src="http://www.gamasutra.com/features/20021011/fig_03.gif" width=150> </td>
            <td vAlign=top align=right width=5 bgColor=#ccc999 height=3><img height=11 src="http://www.gamasutra.com/redesign/images/corner_top_right.gif" width=10 align=top></td>
        </tr>
        <tr>
            <td vAlign=bottom align=right width=15 bgColor=#ccc999 rowSpan=2><img height=11 src="http://www.gamasutra.com/redesign/images/corner_bottom_right.gif" width=10 align=bottom></td>
        </tr>
        <tr vAlign=top>
            <td vAlign=bottom align=left width=10 bgColor=#ccc999 height=16><img height=11 src="http://www.gamasutra.com/redesign/images/corner_bottom_left.gif" width=10 align=bottom></td>
            <td vAlign=top bgColor=#ccc999 colSpan=3 height=16>
            <p align=center><font face="Verdana, Arial, Helvetica, sans-serif" size=-1><strong><font face="Verdana, Arial, Helvetica, sans-serif" size=-1>Figure 3. No matter what finite distance an object&#8217;s silhouette is extruded away from a light source, moving the light close enough to the object can result in a shadow volume that cannot reach other objects in the scene.<br></font></strong></font></p>
            </td>
        </tr>
    </tbody>
</table>
<p>The second problem shows up when the camera lies inside the shadow volume or the shadow volume is clipped by the near plane. Either of these occurrences can leave incorrect values in the stencil buffer causing the wrong surfaces to be illuminated. The solution to this problem is to add caps to the shadow volume geometry, making it a closed surface, and using different stencil operations. The two caps added to the shadow volume are derived from the object&#8217;s triangle mesh as follows. A front cap is constructed using the unmodified vertices of triangles facing toward the light source. A back cap is constructed by projecting the vertices of triangles facing away from the light source to infinity. For the resulting closed shadow volume, we render back faces (with respect to the camera) using a stencil operation that increments the stencil value whenever the depth test fails, and we render front faces using a stencil operation that decrements the stencil value whenever the depth test fails. As shown in Figure 4, this technique leaves nonzero values in the stencil buffer for any surface intersecting the shadow volume for arbitrary camera positions. Rendering shadow volumes in this manner is more expensive than using the original technique, but we can determine when it&#8217;s safe to use the less-costly depth-pass method without having to worry about capping our shadow volumes.
<p>&nbsp;
<table height=112 cellSpacing=0 cellPadding=0 width=74 align=center border=0>
    <tbody>
        <tr>
            <td vAlign=top width=5 bgColor=#ccc999 height=3 rowSpan=2>
            <div align=right><img height=11 src="http://www.gamasutra.com/redesign/images/corner_top_left.gif" width=10 align=top> </div>
            </td>
            <td vAlign=top bgColor=#ccc999 colSpan=3 height=3 rowSpan=2><br><img height=377 src="http://www.gamasutra.com/features/20021011/fig_04.gif" width=450> </td>
            <td vAlign=top align=right width=5 bgColor=#ccc999 height=3><img height=11 src="http://www.gamasutra.com/redesign/images/corner_top_right.gif" width=10 align=top></td>
        </tr>
        <tr>
            <td vAlign=bottom align=right width=15 bgColor=#ccc999 rowSpan=2><img height=11 src="http://www.gamasutra.com/redesign/images/corner_bottom_right.gif" width=10 align=bottom></td>
        </tr>
        <tr vAlign=top>
            <td vAlign=bottom align=left width=10 bgColor=#ccc999 height=16><img height=11 src="http://www.gamasutra.com/redesign/images/corner_bottom_left.gif" width=10 align=bottom></td>
            <td vAlign=top bgColor=#ccc999 colSpan=3 height=16>
            <p align=center><font face="Verdana, Arial, Helvetica, sans-serif" size=-1><strong><font face="Verdana, Arial, Helvetica, sans-serif" size=-1>Figure 4. Using a capped shadow volume and depth-fail stencil operations allows the camera to be inside the shadow volume. The stencil value is incremented when back faces of the shadow volume fail the depth test, and the stencil value is decremented when front faces of the shadow volume fail the depth test. The stencil value does not change when the depth test passes.<br></font></strong></font></p>
            </td>
        </tr>
    </tbody>
</table>
<p>The details of everything just described are discussed throughout the remainder of this article. In summary, the rendering algorithm for a single frame runs through the following steps.
<blockquote><strong>A</strong> Clear the frame buffer and perform an ambient rendering pass. Render the visible scene using any surface shading attribute that does not depend on any particular light source.</blockquote>
<blockquote><strong>B</strong> Choose a light source and determine what objects may cast shadows into the visible region of the world. If this is not the first light to be rendered, clear the stencil buffer.</blockquote>
<blockquote><strong>C</strong> For each object, calculate the silhouette representing the boundary between triangles facing toward the light source and triangles facing away from the light source. Construct a shadow volume by extruding the silhouette away from the light source.</blockquote>
<blockquote><strong>D</strong> Render the shadow volume using specific stencil operations that leave nonzero values in the stencil buffer where surfaces are in shadow.</blockquote>
<blockquote><strong>E</strong> Perform a lighting pass using the stencil test to mask areas that are not illuminated by the light source.</blockquote>
<blockquote><strong>F</strong> Repeat steps B through E for every light source that may illuminate the visible region of the world.</blockquote>
<p>For a scene illuminated by <em>n</em> lights, this algorithm requires at least <em>n</em>+1 rendering passes. More than <em>n</em>+1 passes may be necessary if surface shading calculations for a single light source cannot be accomplished in a single pass. To efficiently render a large scene containing many lights, one must be careful during each pass to render only objects that could potentially be illuminated by a particular light source. An additional optimization using the scissor rectangle can also save a significant amount of rasterization work -- this optimization is discussed in the last section of this article.
<div align=center>
<p>______________________________________________________</p>
<p align=right><font face="Verdana, Arial, Helvetica, sans-serif" size=-2><img height=9 src="http://www.gamasutra.com/db_area/images/layout/99_icon_arrow.gif" width=6></font><font face="Verdana, Arial, Helvetica, sans-serif" color=#0000ff><strong><a href="http://www.gamasutra.com/features/20021011/lengyel_02.htm"><u>Infinite View Frustums</u></a></strong></font></p>
</div>
<blockquote></blockquote>
<div align=right></div>
<blockquote></blockquote><!-- #EndEditable -->
<img src ="http://www.cppblog.com/zmj/aggbug/68559.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/zmj/" target="_blank">zmj</a> 2008-12-04 14:23 <a href="http://www.cppblog.com/zmj/archive/2008/12/04/68559.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Inside Direct3D: Stencil Buffers</title><link>http://www.cppblog.com/zmj/archive/2008/12/03/68438.html</link><dc:creator>zmj</dc:creator><author>zmj</author><pubDate>Wed, 03 Dec 2008 01:46:00 GMT</pubDate><guid>http://www.cppblog.com/zmj/archive/2008/12/03/68438.html</guid><wfw:comment>http://www.cppblog.com/zmj/comments/68438.html</wfw:comment><comments>http://www.cppblog.com/zmj/archive/2008/12/03/68438.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/zmj/comments/commentRss/68438.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/zmj/services/trackbacks/68438.html</trackback:ping><description><![CDATA[<p><a href="http://gamasutra.com/features/20000807/kovach_01.htm">http://gamasutra.com/features/20000807/kovach_01.htm</a><font face=Verdana size=5><br>Inside Direct3D: Stencil Buffers</font><br></p>
<p align=left><font face="Verdana, Arial, Helvetica, sans-serif" size=-1>One aspect of advanced rendering we haven't discussed yet is stenciling, a technique that can be useful for developing commercial applications. If you want your 3D applications to stand apart from the crowd, you'd be wise to combine stenciling with the texturing techniques you learned about in earlier chapters. This chapter will detail how to use stenciling and show you the different types of effects you can generate with it.<br><br>Many 3D games and simulations on the market use cinema-quality special effects to add to their dramatic impact. You can use stencil buffers to create effects such as composites, decals, dissolves, fades, outlines, silhouettes, swipes, and shadows. Stencil buffers determine whether the pixels in an image are drawn. To perform this function, stencil buffers let you enable or disable drawing to the render-target surface on a pixel-by-pixel basis. This means your software can "mask" portions of the rendered image so that they aren't displayed.<br><br>When the stenciling feature is enabled, Microsoft Direct3D performs a stencil test for each pixel that it plans to write to the render-target surface. The stencil test uses a stencil reference value, a stencil mask, a comparison function, and a pixel value from the stencil buffer that corresponds to the current pixel in the target surface. Here are the specific steps used in this test: </font>
<ol>
    <li><font face="Verdana, Arial, Helvetica, sans-serif" size=-1>Perform a bitwise AND operation of the stencil reference value with the stencil mask.</font>
    <li><font face="Verdana, Arial, Helvetica, sans-serif" size=-1>Perform a bitwise AND operation on the stencil-buffer value for the current pixel with the stencil mask.</font>
    <li><font face="Verdana, Arial, Helvetica, sans-serif" size=-1>Compare the results of Step 1 and Step 2 by using the comparison function. </font></li>
</ol>
<p><font face="Verdana, Arial, Helvetica, sans-serif" size=-1>By controlling the comparison function, the stencil mask, the stencil reference value, and the action taken when the stencil test passes or fails, you can control how the stencil buffer works. As long as the test succeeds, the current pixel will be written to the target. The default comparison behavior (the value that the D3DCMPFUNC enumerated type defines for D3DCMP_ALWAYS) is to write the pixel without considering the contents of the stencil buffer. You can change the comparison function to any function you want by setting the value of the D3DRENDERSTATE_STENCILFUNC render state and passing one of the members of the D3DCMPFUNC enumerated type.<br><br><strong>Creating a Stencil Buffer</strong><br><br>Before creating a stencil buffer, you need to determine what stenciling capabilities the target system supports. To do this, call the <em>IDirect3DDevice7::GetCaps</em> method. The <em>dwStencilCaps</em> flags specify the stencil-buffer operations that the device supports. The reported flags are valid for all three stencil-buffer operation render states: D3DRENDERSTATE_STENCILFAIL, D3DRENDERSTATE_STENCILPASS, and D3DRENDERSTATE_STENCILZFAIL. Direct3D defines the following flags for <em>dwStencilCaps: </em></font><font face="Arial, Helvetica, sans-serif">
<ul>
    <li><font face="Verdana, Arial, Helvetica, sans-serif" size=-1><strong>D3DSTENCILCAPS_DECR</strong> Indicates that the D3DSTENCILOP_DECR operation is supported<br><br></font>
    <li><font face="Verdana, Arial, Helvetica, sans-serif" size=-1><strong>D3DSTENCILCAPS_DECRSAT</strong> Indicates that the D3DSTENCILOP_DECRSAT operation is supported<br><br></font>
    <li><font face="Verdana, Arial, Helvetica, sans-serif" size=-1><strong>D3DSTENCILCAPS_INCR</strong> Indicates that the <br>D3DSTENCILOP_INCR operation is supported<br><br></font>
    <li><font face="Verdana, Arial, Helvetica, sans-serif" size=-1><strong>D3DSTENCILCAPS_INCRSAT</strong> Indicates that the D3DSTENCILOP_INCRSAT operation is supported<br><br></font>
    <li><font face="Verdana, Arial, Helvetica, sans-serif" size=-1><strong>D3DSTENCILCAPS_INVERT</strong> Indicates that the D3DSTENCILOP_INVERT operation is supported<br><br></font>
    <li><font face="Verdana, Arial, Helvetica, sans-serif" size=-1><strong>D3DSTENCILCAPS_KEEP</strong> Indicates that the D3DSTENCILOP_KEEP operation is supported<br><br></font>
    <li><font face="Verdana, Arial, Helvetica, sans-serif" size=-1><strong>D3DSTENCILCAPS_REPLACE</strong> Indicates that the D3DSTENCILOP_REPLACE operation is supported<br><br></font>
    <li><font face="Verdana, Arial, Helvetica, sans-serif" size=-1><strong>D3DSTENCILCAPS_ZERO</strong> Indicates that the D3DSTENCILOP_ZERO operation is supported<em><br></em></font></li>
</ul>
<p><font face="Verdana, Arial, Helvetica, sans-serif" size=-1>Direct3D embeds the stencil-buffer information with the depth-buffer data. To determine what formats of depth buffers and stencil buffers the target system's hardware supports, call the <em>IDirect3D7::EnumZBufferFormats</em> method, which has the following declaration:<br><br>HRESULT IDirect3D7::EnumZBufferFormats (<br>&nbsp;&nbsp;&nbsp;&nbsp;REFCLSID riidDevice,<br>&nbsp;&nbsp;&nbsp;&nbsp;LPD3DENUMPIXELFORMATSCALLBACK lpEnumCallback,<br>&nbsp;&nbsp;&nbsp;&nbsp;LPVOID lpContext<br>);</font></p>
<p></font>
<table cellSpacing=3 cellPadding=3 width="95%" align=center border=0>
    <tbody>
        <tr>
            <td bgColor=#000000>
            <div align=center><strong><font face="Arial, Helvetica, sans-serif" color=#ffffff size=-1>Parameter</font></strong></div>
            </td>
            <td bgColor=#000000>
            <div align=center><strong><font face="Arial, Helvetica, sans-serif" color=#ffffff size=-1>Description</font></strong></div>
            </td>
        </tr>
        <tr>
            <td bgColor=#cccc99><em><font face="Arial, Helvetica, sans-serif">riidDevice</font></em></td>
            <td bgColor=#cccc99><font face="Arial, Helvetica, sans-serif">A reference to a globally unique identifier (GUID) for the device whose depth-buffer formats you want enumerated</font></td>
        </tr>
        <tr>
            <td bgColor=#ffffff><em><font face="Arial, Helvetica, sans-serif">IpEnumCallback</font></em></td>
            <td bgColor=#ffffff><font face="Arial, Helvetica, sans-serif">The address of a <em>D3DEnumPixelFormatsCallback </em>function you want called for each supported depth-buffer format</font></td>
        </tr>
        <tr>
            <td bgColor=#cccc99><em><font face="Arial, Helvetica, sans-serif">IpContext</font></em></td>
            <td bgColor=#cccc99><font face="Arial, Helvetica, sans-serif">Application-defined data that is passed to the callback function</font></td>
        </tr>
    </tbody>
</table>
</p>
<p><font face="Verdana, Arial, Helvetica, sans-serif" size=-1>If the method succeeds, it returns the value D3D_OK. If it fails, the method returns one of these four values: </font>
<ul>
    <li><font face="Verdana, Arial, Helvetica, sans-serif" size=-1>DDERR_INVALIDOBJECT<br><br></font>
    <li><font face="Verdana, Arial, Helvetica, sans-serif" size=-1>DDERR_INVALIDPARAMS<br><br></font>
    <li><font face="Verdana, Arial, Helvetica, sans-serif" size=-1>DDER_NOZBUFFERHW<br><br></font>
    <li><font face="Verdana, Arial, Helvetica, sans-serif" size=-1>DDERR_OUTOFMEMORY</font> </li>
</ul>
<p><font face="Verdana, Arial, Helvetica, sans-serif" size=-1>The code in <a href="http://gamasutra.com/features/20000807/kovach_l1.htm"><u><font color=#0000ff>listing 1</font></u></a><a name=1></a> determines what stencil buffer formats are available and what operations are supported and then creates a stencil buffer. As you can see, this code notes whether the stencil buffer supports more than 1-bit -- some stenciling techniques must be handled differently if only a 1-bit stencil buffer is available.<br></font></p>
<p><font face="Verdana, Arial, Helvetica, sans-serif" size=-1><strong>Clearing a Stencil Buffer<br></strong><br>The<em> IDirect3DDevice7</em> interface includes the <em>Clear</em> method, which you can use to simultaneously clear the render target's color buffer, depth buffer, and stencil buffer. Here's the declaration for the <em>IDirect3DDevice7::Clear</em> method:</font></p>
<p><font face="Verdana, Arial, Helvetica, sans-serif" size=-1>&nbsp;&nbsp;&nbsp;&nbsp;HRESULT IDirect3DDevice7::Clear(<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DWORD dwCount,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; LPD3DRECT lpRects,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DWORD dwFlags, <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; D3DVALUE dvZ, <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DWORD dwStencil<br>&nbsp;&nbsp;&nbsp;&nbsp;); </font></p>
<p>&nbsp;</p>
<p>
<table cellSpacing=3 cellPadding=3 width="97%" align=center border=0>
    <tbody>
        <tr>
            <td bgColor=#000000>
            <div align=center><font color=#ffffff><strong><font face="Arial, Helvetica, sans-serif" size=-1>Parameter</font></strong></font></div>
            </td>
            <td bgColor=#000000>
            <div align=center><font color=#ffffff><strong><font face="Arial, Helvetica, sans-serif" size=-1>Description</font></strong></font></div>
            </td>
        </tr>
        <tr bgColor=#cccc99>
            <td><font face="Arial, Helvetica, sans-serif">dwCount</font></td>
            <td><font face="Arial, Helvetica, sans-serif">The number of rectangles in the array at lpRects.</font></td>
        </tr>
        <tr>
            <td bgColor=#ffffff>
            <div align=center><font face="Arial, Helvetica, sans-serif">IpRects</font></div>
            </td>
            <td bgColor=#ffffff><font face="Arial, Helvetica, sans-serif">An array of D3DRECT structures defining the rectangles to be cleared. You can set a rectangle to the dimensions of the render-target surface to clear the entire surface. Each of these rectangles uses screen coordinates that correspond to points on the render-target surface. The coordinates are clipped to the bounds of the viewport rectangle.</font></td>
        </tr>
        <tr bgColor=#cccc99>
            <td><font face="Arial, Helvetica, sans-serif">dwFlags</font></td>
            <td><font face="Arial, Helvetica, sans-serif">Flags indicating which surfaces should be cleared. This parameter can be any combination of the following flags, but at least one flag must be used:</font></td>
        </tr>
        <tr>
            <td bgColor=#ffffff>&nbsp;</td>
            <td bgColor=#ffffff><font face="Arial, Helvetica, sans-serif"><strong>D3DCLEAR_TARGET </strong>Clear the render-target surface to the color in the dwColor parameter. <strong>D3DCLEAR_STENCIL</strong> Clear the stencil buffer to the value in the dwStencil parameter.</font></td>
        </tr>
        <tr>
            <td bgColor=#cccc99>&nbsp;</td>
            <td bgColor=#cccc99><font face="Arial, Helvetica, sans-serif">D3DCLEAR_ZBUFFER Clear the depth buffer to the value in the dvZ parameter.</font></td>
        </tr>
        <tr>
            <td bgColor=#ffffff><font face="Arial, Helvetica, sans-serif">dwColor</font></td>
            <td bgColor=#ffffff><font face="Arial, Helvetica, sans-serif"><strong>D3DCLEAR_ZBUFFER</strong> Clear the depth buffer to the value in the dvZ parameter..</font></td>
        </tr>
        <tr>
            <td bgColor=#cccc99 height=25><font face="Arial, Helvetica, sans-serif">dvZ</font></td>
            <td bgColor=#cccc99 height=25><font face="Arial, Helvetica, sans-serif">A 32-bit RGBA color value to which the render-target surface will be cleared.</font></td>
        </tr>
        <tr>
            <td bgColor=#ffffff height=96><font face="Arial, Helvetica, sans-serif">dwStencil</font></td>
            <td bgColor=#ffffff height=96><font face="Arial, Helvetica, sans-serif">The new z value that this method stores in the depth buffer. This parameter can range from 0.0 to 1.0, inclusive. The value of 0.0 represents the nearest distance to the viewer, and 1.0 represents the farthest distance.</font></td>
        </tr>
        <tr>
            <td bgColor=#cccc99>&nbsp;</td>
            <td bgColor=#cccc99><font face="Arial, Helvetica, sans-serif">The integer value to store in each stencil-buffer entry. This parameter can range from 0 to 2n-1 inclusive, in which n is the bit depth of the stencil buffer.</font></td>
        </tr>
    </tbody>
</table>
</p>
<p><font face="Verdana, Arial, Helvetica, sans-serif" size=-1>The <em>IDirect3DDevice7::Clear</em> method still accepts the older D3DCLEAR_TARGET flag, which clears the render target using an RGBA color you provide in the <em>dwColor</em> parameter. This method also still accepts the D3DCLEAR_ZBUFFER flag, which clears the depth buffer to a depth you specify in <em>dvZ</em> (in which 0.0 is the closest distance and 1.0 is the farthest). DirectX 6 introduced the D3DCLEAR_STENCIL flag, which you can use to reset the stencil bits to the value you specify in the <em>dwStencil </em>parameter. This value can be an integer ranging from 0 to 2n-1, in which n is the bit depth of the stencil buffer. <br><br></font></p>
<h4 align=center><font face="Verdana, Arial, Helvetica, sans-serif" size=-1>________________________________________________________</font></h4>
<p align=right><font face="Verdana, Arial, Helvetica, sans-serif" size=-1><img height=9 src="http://gamasutra.com/db_area/images/layout/99_icon_arrow.gif" width=6><a href="http://gamasutra.com/features/20000807/kovach_02.htm"><strong><u><font color=#800080>Configuring the Stenciling State</font></u></strong></a></font></p>
<p><!-- #EndEditable --><br><font face=Verdana>Configuring the Stenciling State</font><br><font face=Verdana size=2>You control the various settings for the stencil buffer using the <em>IDirect3DDevice7::</em><br><em>SetRenderState</em> method. </font><a href="http://gamasutra.com/features/20000807/kovach_l2.htm"><u><font face=Verdana color=#0000ff size=2>Listing 2</font></u></a><a name=2></a><font face=Verdana size=2> shows the stencil-related members of the D3DRENDERSTATETYPE enumerated type. </font></p>
<p><font face=Verdana size=2>&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;These are the definitions for the stencil-related render states: </font><font face="Arial, Helvetica, sans-serif">
<ul>
    <li><font face="Verdana, Arial, Helvetica, sans-serif" size=-1><strong>D3DRENDERSTATE_STENCILENABLE </strong>Use this member to enable or disable stenciling. To enable stenciling, use this member with TRUE; to disable stenciling, use it with FALSE. The default value is FALSE.<br><br></font>
    <li><font face="Verdana, Arial, Helvetica, sans-serif" size=-1><strong>D3DRENDERSTATE_STENCILFAIL </strong>Use this member to indicate the stencil operation to perform if the stencil test fails. The stencil operation can be one of the members of the D3DSTENCILOP enumerated type. The default value is D3DSTENCILOP_KEEP.<br><br></font>
    <li><font face="Verdana, Arial, Helvetica, sans-serif" size=-1><strong>D3DRENDERSTATE_STENCILZFAIL </strong>Use this member to indicate the stencil operation to perform if the stencil test passes and the depth test (z-test) fails. The operation can be one of the members of the D3DSTENCILOP enumerated type. The default value is D3DSTENCILOP_KEEP.<br><br></font>
    <li><font face="Verdana, Arial, Helvetica, sans-serif" size=-1><strong>D3DRENDERSTATE_STENCILPASS </strong>Use this member to indicate the stencil operation to perform if both the stencil test and the depth test (z-test) pass. The operation can be one of the members of the D3DSTENCILOP enumerated type. The default value is D3DSTENCILOP_KEEP.<br><br></font>
    <li><font face="Verdana, Arial, Helvetica, sans-serif" size=-1><strong>D3DRENDERSTATE_STENCILFUNC </strong>Use this member to indicate the comparison function for the stencil test. The comparison function can be one of the members of the D3DCMPFUNC enumerated type. The default value is D3DCMP_ALWAYS. This function compares the reference value to a stencil-buffer entry and applies only to the bits in the reference value and stencil-buffer entry that are set in the stencil mask. (The D3DRENDERSTATE_STENCILMASK render state sets the stencil mask.) If the comparison is true, the stencil test passes.<br><br></font>
    <li><font face="Verdana, Arial, Helvetica, sans-serif" size=-1><strong>D3DRENDERSTATE_STENCILREF </strong>Use this member to indicate the integer reference value for the stencil test. The default value is 0.<br><br></font>
    <li><font face="Verdana, Arial, Helvetica, sans-serif" size=-1><strong>D3DRENDERSTATE_STENCILMASK </strong>Use this member to specify the mask to apply to the reference value and each stencil-buffer entry to determine the significant bits for the stencil test. The default mask is 0xFFFFFFFF.<br><br></font>
    <li><font face="Verdana, Arial, Helvetica, sans-serif" size=-1><strong>D3DRENDERSTATE_STENCILWRITEMASK </strong>Use this member to specify the mask to apply to values written into the stencil buffer. The default mask is 0xFFFFFFFF. <br><br></font></li>
</ul>
</font>
<p><font face="Verdana, Arial, Helvetica, sans-serif" size=-1>The D3DSTENCILOP enumerated type describes the stencil operations for the D3DRENDERSTATE_STENCILFAIL, D3DRENDERSTATE_STENCILZFAIL, and D3DRENDERSTATE_STENCILPASS render states. Here's the definition of D3DSTENCILOP: </font></p>
<font face="Arial, Helvetica, sans-serif">
<p><font face="Verdana, Arial, Helvetica, sans-serif" size=-1>&nbsp;&nbsp;typedef enum _D3DSTENCILOP {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;D3DSTENCILOP_KEEP &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;= 1,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;D3DSTENCILOP_ZERO &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;= 2,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;D3DSTENCILOP_REPLACE &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;= 3,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;D3DSTENCILOP_INCRSAT &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;= 4,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;D3DSTENCILOP_DECRSAT &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;= 5,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;D3DSTENCILOP_INVERT&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;= 6,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;D3DSTENCILOP_INCR &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;= 7,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;D3DSTENCILOP_DECR &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;= 8,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;D3DSTENCILOP_FORCE_DWORD &nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;= 0x7fffffff<br>&nbsp;&nbsp;} D3DSTENCILOP;</font></p>
<p><font face="Verdana, Arial, Helvetica, sans-serif" size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;These members serve the following purposes: </font>
<ul>
    <li><font face="Verdana, Arial, Helvetica, sans-serif" size=-1><strong>D3DSTENCILOP_KEEP</strong> Indicates that you don't want the entry in the stencil buffer updated. This is the default operation.<br><strong><br></strong></font>
    <li><font face="Verdana, Arial, Helvetica, sans-serif" size=-1><strong>D3DSTENCILOP_ZERO</strong> Sets the stencil-buffer entry to 0.<br><br></font>
    <li><font face="Verdana, Arial, Helvetica, sans-serif" size=-1><strong>D3DSTENCILOP_REPLACE</strong> Replaces the stencil-buffer entry with the reference value.<br><br></font>
    <li><font face="Verdana, Arial, Helvetica, sans-serif" size=-1><strong>D3DSTENCILOP_INCRSAT</strong> Increments the stencil-buffer entry, clamping to the maximum value.<br><br></font>
    <li><font face="Verdana, Arial, Helvetica, sans-serif" size=-1><strong>D3DSTENCILOP_DECRSAT </strong>Decrements the stencil-buffer entry, clamping to 0.<br><br></font>
    <li><font face="Verdana, Arial, Helvetica, sans-serif" size=-1><strong>D3DSTENCILOP_INVERT</strong> Inverts the bits in the stencil-buffer entry.<br><br></font>
    <li><font face="Verdana, Arial, Helvetica, sans-serif" size=-1><strong>D3DSTENCILOP_INCR</strong> Increments the stencil-buffer entry, wrapping to 0 if the new value exceeds the maximum value.<br><br></font>
    <li><font face="Verdana, Arial, Helvetica, sans-serif" size=-1><strong>D3DSTENCILOP_DECR</strong> Decrements the stencil-buffer entry, wrapping to the maximum value if the new value is less than 0.<br><br></font>
    <li><font face="Verdana, Arial, Helvetica, sans-serif" size=-1><strong>D3DSTENCILOP_FORCE_DWORD</strong> Forces this enumeration to be compiled to 32 bits; this value isn't used.</font> </li>
</ul>
<p><font face="Verdana, Arial, Helvetica, sans-serif" size=-1>Let's walk through some code that uses the stencil buffer while rendering a scene. This code is from a sample that shows how to draw shadows. For now, don't worry about how all this code generates shadows-the algorithm is described later in the chapter.</font></p>
<p><font face="Verdana, Arial, Helvetica, sans-serif" size=-1>The shadow-rendering code starts out by disabling the depth buffer and enabling the stencil buffer:</font></p>
</font>
<p><font face="Verdana, Arial, Helvetica, sans-serif" size=-1>&nbsp;&nbsp;&nbsp;&nbsp;//--------------------------------------------------<br>&nbsp;&nbsp;&nbsp;&nbsp;// Name: RenderShadow<br>&nbsp;&nbsp;&nbsp;&nbsp;// Desc: <br>&nbsp;&nbsp;&nbsp;&nbsp;//------------------------------------------------<br>&nbsp;&nbsp;&nbsp;&nbsp;HRESULT CMyD3DApplication::RenderShadow()<br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// Turn off depth buffer and turn on <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; stencil buffer.<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;m_pd3dDevice-&gt;SetRenderState(<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; D3DRENDERSTATE_ZWRITEENABLE,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FALSE );<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;m_pd3dDevice-&gt;SetRenderState(<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; D3DRENDERSTATE_STENCILENABLE,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TRUE );</font></p>
<p><font face="Verdana, Arial, Helvetica, sans-serif" size=-1>Next the code sets the comparison function that performs the stencil test by calling the <em>IDirect3DDevice7::SetRenderState</em> method and setting the first parameter to D3DRENDERSTATE_STENCILFUNC. The second parameter is set to a member of the D3DCMPFUNC enumerated type. In this code, we want to update the stencil buffer everywhere a primitive is rendered, so we use D3DCMP_ALWAYS:</font></p>
<p><font face="Verdana, Arial, Helvetica, sans-serif" size=-1>&nbsp;&nbsp;&nbsp;&nbsp; //<br>&nbsp;&nbsp;&nbsp;&nbsp;// Set up stencil comparison function, <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; reference value, and&nbsp;masks.<br>&nbsp;&nbsp;&nbsp;&nbsp;// Stencil test passes if ((ref &amp; mask) <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cmpfn (stencil &amp; mask))<br>&nbsp;&nbsp;&nbsp;&nbsp;// is true.<br>&nbsp;&nbsp;&nbsp;&nbsp;//<br>&nbsp;&nbsp;&nbsp;&nbsp;m_pd3dDevice-&gt;SetRenderState(<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; D3DRENDERSTATE_STENCILFUNC,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;D3DCMP_ALWAYS );<br></font></p>
<p><font face="Verdana, Arial, Helvetica, sans-serif" size=-1>In this sample, we don't want the stencil buffer to change if either the stencil buffer test or the depth buffer test fails, so we set the appropriate states to D3DSTENCILOP_KEEP:<br><br>&nbsp;&nbsp;&nbsp;&nbsp; m_pd3dDevice-&gt;SetRenderState(<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; D3DRENDERSTATE_STENCILZFAIL,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;D3DSTENCILOP_KEEP );<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;m_pd3dDevice-&gt;SetRenderState(<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; D3DRENDERSTATE_STENCILFAIL,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;D3DSTENCILOP_KEEP );<br><br>The settings in <a href="http://gamasutra.com/features/20000807/kovach_l3.htm"><u><font color=#0000ff>listing 3</font></u></a><a name=3></a> are different depending on whether a 1-bit or a multibit stencil buffer is present. If the stencil buffer has only 1 bit, the value 1 is stored in the stencil buffer whenever the stencil test passes. Otherwise, an increment operation (either D3DSTENCILOP_INCR or D3DSTENCILOP_INCRSAT) is applied if the stencil test passes. At this point, the stencil state is configured and the code is ready to render some primitives.</font></p>
<p>
<p align=center><font face="Verdana, Arial, Helvetica, sans-serif" size=-1>________________________________________________________</font></p>
<p align=right><font face="Verdana, Arial, Helvetica, sans-serif" size=-1><img height=9 src="http://gamasutra.com/db_area/images/layout/99_icon_arrow.gif" width=6><a href="http://gamasutra.com/features/20000807/kovach_03.htm"><strong><u><font color=#800080>Creating Effects</font></u></strong></a></font></p>
<p><!-- #EndEditable --><font face=Verdana>Creating Effects</font><br><font face=Verdana size=2>Now that you've seen how to create stencil buffers and configure how they work, let's look at some of the effects you can render with them. The following sections describe several ways Microsoft recommends using stencil buffers. Each of these approaches produces impressive results, but a few of them have drawbacks.<br></font><strong><br><em><font face=Verdana size=2>Composites</font></em></strong><br><br><font face=Verdana size=2>You can use stencil buffers for compositing 2D or 3D images onto a 3D scene. By using a mask in the stencil buffer to occlude a portion of the render-target surface, you can write stored 2D information (such as text or bitmaps). You can also render 3D primitives -- or for that matter a complete scene -- to the area of the render-target surface that you specify in a stencil mask.<br><br>Developers often use this effect to composite several scenes in simulations and games. Many driving games feature a rear view mirror that displays the scene behind the driver. You can composite this second 3D scene with the driver's view forward by using a stencil to block the portion to which you want the mirror image rendered. You can also use composites to create 2D "cockpits" for vehicle simulations by combining a 2D, bitmapped image of the cockpit with the final, rendered 3D scene.<br></font><em><strong><br><font face=Verdana size=2>Decals</font></strong></em><br><br><font face=Verdana size=2>You can use decals to control which pixels form a primitive image you draw to a render-target surface. When you apply a texture to an object (for example, applying scratch marks to a floor), you need the texture (the scratch marks) to appear immediately on top of the object (the floor). Because the z values of the scratch marks and the floor are equal, the depth buffer might not yield consistent results, meaning that some pixels in the back primitive might be rendered on top of those in the front primitive. This overlap, which is commonly known as z-fighting or flimmering, can cause the final image to shimmer as you animate from one frame to the next.<br><br>You can prevent flimmering by using a stencil to mask the section of the back primitive on which you want the decal to appear. You can then turn off z-buffering and render the image of the front primitive into the masked area of the render-target surface.<br></font><em><strong><br><font face=Verdana size=2>Dissolves</font></strong></em><br><br><font face=Verdana size=2>You can use dissolves to gradually replace an image by displaying a series of frames that transition from one image to another. In Chapter 8, you saw how to use multiple-texture blending to create this effect by gradually blending two textures together. Stencil buffers allow you to produce similar dissolves, except that a stencil-based dissolve looks more pixelated than a multiple-texture blending one. However, stencil buffers let you use texture-blending capabilities for other effects while performing a dissolve. This capability enables you to efficiently produce more complex effects than you could by using texture blending alone.<br><br>A stencil buffer can perform a dissolve by controlling which pixels you draw from two different images to the render-target surface. You can perform a dissolve by defining a base stencil mask for the first frame and altering it incrementally or by defining a series of stencil masks and copying them into the stencil buffer on successive frames.<br><br>To start a dissolve, set the stencil function and stencil mask so that most of the pixels from the starting image pass the stencil test and most of the ending image's pixels fail. For each subsequent frame, update the stencil mask to allow fewer pixels in the starting image to pass the test and more pixels in the ending image to pass. By controlling the stencil mask, you can create a variety of dissolve effects.<br><br>Although this approach can produce some fantastic effects, it can be a bit slow on some systems. You should test the performance on your target systems to verify that this approach works efficiently for your application.<br></font><em><strong><br><font face=Verdana size=2>Fades</font></strong></em><br><br><font face=Verdana size=2>You can fade in or out using a form of dissolving. To perform this effect, use any dissolve pattern you want. To fade in, use a stencil buffer to dissolve from a black or white image to a rendered 3D scene. To fade out, start with a rendered 3D scene and dissolve to black or white. As with dissolves, you should check the performance of fades on the target systems to verify that their speed and appearance is acceptable.<br></font><em><strong><br><font face=Verdana size=2>Outlines</font></strong></em><br><br><font face=Verdana size=2>You can apply a stencil mask to a primitive that's the same shape but slightly smaller than the primitive. The resulting image will contain only the primitive's outline. You can then fill this stencil-masked area of the primitive with a color or set of colors to produce an outline around the image.<br></font><em><strong><br><font face=Verdana size=2>Silhouettes</font></strong></em><br><br><font face=Verdana size=2>When you set the stencil mask to the same size and shape as the primitive you're rendering, Direct3D produces a final image containing a "black hole" where the primitive should be. By coloring this hole, you can produce a silhouette of the primitive.<br></font><em><strong><br><font face=Verdana size=2>Swipes</font></strong></em><br><br><font face=Verdana size=2>A swipe makes an image appear as though it's sliding into the scene over another image. You can use stencil masks to disable the writing of pixels from the starting image and enable the writing of pixels from the ending image. To perform a swipe, you can define a series of stencil masks that Direct3D will load into the stencil buffer in a succession of frames, or you can change the starting stencil mask for a series of successive frames. Both methods cause the final image to look as though it's gradually sliding on top of the starting image from right to left, left to right, top to bottom, and so on.<br><br>To handle a swipe, remember to read the pixels from the ending image in the reverse order in which you're performing the swipe. For example, if you're performing a swipe from left to right, you need to read pixels from the ending image from right to left. As with dissolves, this effect can render somewhat slowly. Therefore, you should test its performance on your target systems.<br></font><em><strong><br><font face=Verdana size=2>Shadows</font></strong></em><br><br><font face=Verdana size=2>Shadow volumes, which allow an arbitrarily shaped object to cast a shadow onto another arbitrarily shaped object, can produce some incredibly realistic effects. To create shadows with stencil buffers, take an object you want to cast a shadow. Using this object and the light source, build a set of polygonal faces (a shadow volume) to represent the shadow.<br><br>You can compute the shadow volume by projecting the vertices of the shadow-casting object onto a plane that's perpendicular to the direction of light from the light source, finding the 2D convex hull of the projected vertices (that is, a polygon that "wraps around" all the projected vertices), and extruding the 2D convex hull in the light direction to form the 3D shadow volume. The shadow volume must extend far enough so that it covers any objects that will be shadowed. To simplify computation, you might want the shadow caster to be a convex object.<br><br>To render a shadow, you must first render the geometry and then render the shadow volume without writing to the depth buffer or the color buffer. Use alpha blending to avoid having to write to the color buffer. Each place that the shadow volume appears will be marked in the stencil buffer. You can then reverse the cull and render the backfaces of the shadow volume, unmarking all the pixels that are covered in the stencil buffer. All these pixels will have passed the z-test, so they'll be visible behind the shadow volume. Therefore, they won't be in shadow. The pixels that are still marked are the ones lying inside the front and back boundaries of the shadow volume-these pixels will be in shadow. You can blend these pixels with a large black rectangle that covers the viewport to generate the shadow.<br></font><strong><br><font face=Verdana size=2>The ShadowVol and ShadowVol2 Demos</font></strong><br><br><font face=Verdana size=2>The ShadowVol sample on the companion CD in the \mssdk\Samples\Multimedia\D3dim\Src\ShadowVol directory contains a project that shows how to create and use stencil buffers to implement shadow volumes. The code illustrates how to use shadow volumes to cast the shadow of an arbitrarily shaped object onto another arbitrarily shaped object. The ShadowVol2 sample, which the Microsoft DirectX 7 SDK setup program on the companion CD installs in the \mssdk\Samples\Multimedia\D3dim\Src\ShadowVol2 directory on your hard disk, provides some additional capabilities for producing shadows with stencils.<br><br>The sample application provides these features in its Shadow Modes menu: </font></p>
<ul>
    <li><font size=2><font face=Verdana><strong>Draw Shadows:</strong> Allows you to turn on and off shadow rendering.<br><br></font></font><font face="Arial, Helvetica, sans-serif">
    <li><font face="Verdana, Arial, Helvetica, sans-serif" size=-1><strong>Show Shadow Volumes:</strong> Draws the shadow volumes used to compute the shadows rather than drawing the shadows themselves.<br><br></font>
    <li><font face="Verdana, Arial, Helvetica, sans-serif" size=-1><strong>Draw Shadow Volume Caps:</strong> When you turn this item off, some "extra" shadows might become visible where the far caps of the cylindrical shadow volumes happen to be visible.<br><br></font>
    <li><font face="Verdana, Arial, Helvetica, sans-serif" size=-1><strong>1-Bit Stencil Buffer Mode: </strong>Tells the code to use a different algorithm that uses only 1 bit of stencil buffer, which won't allow overlapping shadows. If the device supports only 1-bit stencils, you'll be forced to use this mode.<br><br></font>
    <li><font face="Verdana, Arial, Helvetica, sans-serif" size=-1><strong>Z-Order Shadow Vols in 1-Bit Stencil Buffer Mode:</strong> The shadow volumes must be rendered front to back, which means that if you don't check this option, rendering might be incorrect.</font> </li>
</ul>
<p><font face="Verdana, Arial, Helvetica, sans-serif" size=-1>Figure 12-1, Figure 12-2, and Figure 12-3 show three views of the scene generated by the ShadowVol2 sample application. You can see the shadows in Figures 12-1 and 12-3; Figure 12-2 illustrates the shadow volumes.</font></p>
</font>
<p>&nbsp;</p>
<p>
<table cellSpacing=3 cellPadding=3 width="42%" align=center border=0>
    <tbody>
        <tr bgColor=#cccc99>
            <td>
            <div align=left><font face="Arial, Helvetica, sans-serif">&lt;&lt;"F12xi01.eps"&gt;&gt; </font></div>
            </td>
        </tr>
        <tr bgColor=#000000>
            <td>
            <div align=center><font face="Arial, Helvetica, sans-serif"><strong><font face="Verdana, Arial, Helvetica, sans-serif" color=#ffffff size=-1>Figure 12-1. <em>Shadow cast</em></font></strong></font></div>
            </td>
        </tr>
    </tbody>
</table>
<font face="Verdana, Arial, Helvetica, sans-serif" size=-1><br></font>
<table cellSpacing=3 cellPadding=3 width="48%" align=center border=0>
    <tbody>
        <tr bgColor=#cccc99>
            <td><font face="Arial, Helvetica, sans-serif">&lt;&lt;"F12xi02.eps"&gt;&gt;</font></td>
        </tr>
        <tr bgColor=#000000>
            <td>
            <div align=center><font face="Arial, Helvetica, sans-serif" size=-1><strong><font face="Verdana, Arial, Helvetica, sans-serif" color=#ffffff>Figure 12-2. Shadow volumes</font></strong></font></div>
            </td>
        </tr>
    </tbody>
</table>
<font face="Verdana, Arial, Helvetica, sans-serif" size=-1><br></font>
<table cellSpacing=3 cellPadding=3 width="75%" align=center border=0>
    <tbody>
        <tr bgColor=#cccc99>
            <td>
            <div align=left><font face="Arial, Helvetica, sans-serif">&lt;&lt;"F12xi03.eps"&gt;&gt;</font></div>
            </td>
        </tr>
        <tr bgColor=#000000>
            <td>
            <div align=center><font face="Arial, Helvetica, sans-serif"><strong><font face="Verdana, Arial, Helvetica, sans-serif" color=#ffffff size=-1>Figure 12-3. Another view of the rendered shadows</font></strong></font></div>
            </td>
        </tr>
    </tbody>
</table>
</p>
<p><font face="Verdana, Arial, Helvetica, sans-serif" size=-1><strong>The Code So Far</strong><br><br>In this chapter, we didn't add any new code to the RoadRage project. To see these effects in action, refer to the ShadowVol and ShadowVol2 demo projects included in the DirectX samples.<br><strong><br>Conclusion</strong><br><br>In this chapter, you learned about stencil buffers and the exciting effects they can produce. In today's market, making your code stand out is a requisite if you want it to sell your applications and keep your users coming back for more. Incorporating strategic stencil-buffer effects into the introduction and into the body of a 3D real-time game might help you win over even the most discriminating game players.<br></font></p>
<p><font face="Verdana, Arial, Helvetica, sans-serif" size=-1>In Chapter 13, we'll discuss how to load and animate 3D models. Creating animated, lifelike characters that your users can interact with is one of the most powerful capabilities you can add to any game.<br><br><strong>Peter Kovach has been involved in computer software and hardware development since the mid-1970s. After 11 years in various levels of development and project management, he was eager to being pushing the envelope in 3D virtual world development. He currently words at Medtronic, where he is the project lead developming programmable, implantable medical devices that use a next-generation graphical user interface. </strong></font></p>
<img src ="http://www.cppblog.com/zmj/aggbug/68438.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/zmj/" target="_blank">zmj</a> 2008-12-03 09:46 <a href="http://www.cppblog.com/zmj/archive/2008/12/03/68438.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Collision detection</title><link>http://www.cppblog.com/zmj/archive/2008/11/22/67634.html</link><dc:creator>zmj</dc:creator><author>zmj</author><pubDate>Sat, 22 Nov 2008 15:25:00 GMT</pubDate><guid>http://www.cppblog.com/zmj/archive/2008/11/22/67634.html</guid><wfw:comment>http://www.cppblog.com/zmj/comments/67634.html</wfw:comment><comments>http://www.cppblog.com/zmj/archive/2008/11/22/67634.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/zmj/comments/commentRss/67634.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/zmj/services/trackbacks/67634.html</trackback:ping><description><![CDATA[<a href="http://en.wikipedia.org/wiki/Collision_detection">http://en.wikipedia.org/wiki/Collision_detection</a><br>
<h1 class=firstHeading>Collision detection</h1>
<div id=bodyContent>
<h3 id=siteSub>From Wikipedia, the free encyclopedia</h3>
<div id=contentSub></div>
<div id=jump-to-nav>Jump to: <a href="http://en.wikipedia.org/wiki/Collision_detection#column-one"><font color=#5a3696>navigation</font></a>, <a href="http://en.wikipedia.org/wiki/Collision_detection#searchInput"><font color=#5a3696>search</font></a></div>
<!-- start content -->
<div class=dablink>For collision detection on networks see <a class=mw-redirect title=CSMA/CD href="http://en.wikipedia.org/wiki/CSMA/CD"><font color=#002bb8>CSMA/CD</font></a></div>
<p>In <a class=mw-redirect title="Physical simulation" href="http://en.wikipedia.org/wiki/Physical_simulation"><font color=#002bb8>physical simulations</font></a>, <a title="Video game" href="http://en.wikipedia.org/wiki/Video_game"><font color=#002bb8>video games</font></a> and <a title="Computational geometry" href="http://en.wikipedia.org/wiki/Computational_geometry"><font color=#002bb8>computational geometry</font></a>, <strong>collision detection</strong> involves algorithms for checking for <a title=Collision href="http://en.wikipedia.org/wiki/Collision"><font color=#002bb8>collision</font></a>, i.e. intersection, of two given solids. Simulating what happens once a collision is detected is sometimes referred to as "collision response", for which see <a title="Physics engine" href="http://en.wikipedia.org/wiki/Physics_engine"><font color=#002bb8>physics engine</font></a> and <a title="Ragdoll physics" href="http://en.wikipedia.org/wiki/Ragdoll_physics"><font color=#002bb8>ragdoll physics</font></a>. Collision detection algorithms are a basic component of 3D video games. Without them, characters could go through walls and other obstacles.</p>
<table class=toc id=toc summary=Contents>
    <tbody>
        <tr>
            <td>
            <div id=toctitle>
            <h2>Contents</h2>
            <span class=toctoggle><font size=2>[</font><a class=internal id=togglelink href="javascript:toggleToc()"><font color=#002bb8 size=2>hide</font></a><font size=2>]</font></span></div>
            <ul>
                <li class=toclevel-1><a href="http://en.wikipedia.org/wiki/Collision_detection#Overview"><font color=#5a3696><span class=tocnumber>1</span> <span class=toctext>Overview</span></font></a>
                <li class=toclevel-1><a href="http://en.wikipedia.org/wiki/Collision_detection#Collision_detection_in_physical_simulation"><font color=#5a3696><span class=tocnumber>2</span> <span class=toctext>Collision detection in physical simulation</span></font></a>
                <ul>
                    <li class=toclevel-2><a href="http://en.wikipedia.org/wiki/Collision_detection#A_posteriori_versus_a_priori"><font color=#5a3696><span class=tocnumber>2.1</span> <span class=toctext>A posteriori versus a priori</span></font></a> </li>
                </ul>
                <li class=toclevel-1><a href="http://en.wikipedia.org/wiki/Collision_detection#Optimization"><font color=#5a3696><span class=tocnumber>3</span> <span class=toctext>Optimization</span></font></a>
                <ul>
                    <li class=toclevel-2><a href="http://en.wikipedia.org/wiki/Collision_detection#Exploiting_temporal_coherence"><font color=#5a3696><span class=tocnumber>3.1</span> <span class=toctext>Exploiting temporal coherence</span></font></a>
                    <li class=toclevel-2><a href="http://en.wikipedia.org/wiki/Collision_detection#Pairwise_pruning"><font color=#5a3696><span class=tocnumber>3.2</span> <span class=toctext>Pairwise pruning</span></font></a>
                    <li class=toclevel-2><a href="http://en.wikipedia.org/wiki/Collision_detection#Exact_pairwise_collision_detection"><font color=#5a3696><span class=tocnumber>3.3</span> <span class=toctext>Exact pairwise collision detection</span></font></a>
                    <li class=toclevel-2><a href="http://en.wikipedia.org/wiki/Collision_detection#A_priori_pruning"><font color=#5a3696><span class=tocnumber>3.4</span> <span class=toctext>A priori pruning</span></font></a>
                    <li class=toclevel-2><a href="http://en.wikipedia.org/wiki/Collision_detection#Spatial_partitioning"><font color=#5a3696><span class=tocnumber>3.5</span> <span class=toctext>Spatial partitioning</span></font></a> </li>
                </ul>
                <li class=toclevel-1><a href="http://en.wikipedia.org/wiki/Collision_detection#Video_games"><font color=#5a3696><span class=tocnumber>4</span> <span class=toctext>Video games</span></font></a>
                <li class=toclevel-1><a href="http://en.wikipedia.org/wiki/Collision_detection#Open_Source_Collision_Detection"><font color=#5a3696><span class=tocnumber>5</span> <span class=toctext>Open Source Collision Detection</span></font></a>
                <li class=toclevel-1><a href="http://en.wikipedia.org/wiki/Collision_detection#References"><font color=#5a3696><span class=tocnumber>6</span> <span class=toctext>References</span></font></a>
                <li class=toclevel-1><a href="http://en.wikipedia.org/wiki/Collision_detection#See_also"><font color=#5a3696><span class=tocnumber>7</span> <span class=toctext>See also</span></font></a>
                <li class=toclevel-1><a href="http://en.wikipedia.org/wiki/Collision_detection#External_links"><font color=#5a3696><span class=tocnumber>8</span> <span class=toctext>External links</span></font></a> </li>
            </ul>
            </td>
        </tr>
    </tbody>
</table>
<script type=text/javascript>
//<![cdata[
if (window.showTocToggle) { var tocShowText = "show"; var tocHideText = "hide"; showTocToggle(); }
//]]&gt;
</script>
<p><a id=Overview name=Overview></a></p>
<h2><span class=editsection>[<a title="Edit section: Overview" href="http://en.wikipedia.org/w/index.php?title=Collision_detection&amp;action=edit&amp;section=1"><font color=#002bb8>edit</font></a>]</span> <span class=mw-headline>Overview</span></h2>
<div class="thumb tright">
<div class=thumbinner style="WIDTH: 202px"><a class=image title="Billiards balls hitting each other are a classic example applicable within the science of collision detection." href="http://en.wikipedia.org/wiki/Image:Billiards_balls.jpg"><img class=thumbimage height=150 alt="" src="http://upload.wikimedia.org/wikipedia/commons/thumb/f/fe/Billiards_balls.jpg/200px-Billiards_balls.jpg" width=200 border=0></a>
<div class=thumbcaption>
<div class=magnify><a class=internal title=Enlarge href="http://en.wikipedia.org/wiki/Image:Billiards_balls.jpg"><span class="" style="BORDER-TOP-WIDTH: 2px; DISPLAY: inline-block; BORDER-LEFT-WIDTH: 2px; FONT-SIZE: 0px; BORDER-LEFT-COLOR: #0000ff; BACKGROUND-IMAGE: none; BORDER-BOTTOM-WIDTH: 2px; BORDER-BOTTOM-COLOR: #0000ff; VERTICAL-ALIGN: middle; CURSOR: hand; BORDER-TOP-COLOR: #0000ff; BORDER-RIGHT-WIDTH: 2px; BORDER-RIGHT-COLOR: #0000ff"><span style="DISPLAY: inline-block; FILTER: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='http://en.wikipedia.org/skins-1.5/common/images/magnify-clip.png'); WIDTH: 1px; HEIGHT: 1px"></span></span></a></div>
Billiards balls hitting each other are a classic example applicable within the science of collision detection.</div>
</div>
</div>
<p>In physical simulation, we wish to conduct experiments, such as playing <a class=mw-redirect title=Billiards href="http://en.wikipedia.org/wiki/Billiards"><font color=#002bb8>billiards</font></a>. The <a title=Physics href="http://en.wikipedia.org/wiki/Physics"><font color=#002bb8>physics</font></a> of bouncing billiard balls are well understood, under the umbrella of <a class=mw-redirect title="Rigid body motion" href="http://en.wikipedia.org/wiki/Rigid_body_motion"><font color=#002bb8>rigid body motion</font></a> and <a title="Elastic collision" href="http://en.wikipedia.org/wiki/Elastic_collision"><font color=#002bb8>elastic collisions</font></a>. An initial description of the situation would be given, with a very precise physical description of the billiard table and balls, as well as initial positions of all the balls. Given a certain impulsion on the cue ball (probably resulting from a player hitting the ball with his cue stick), we want to calculate the trajectories, precise motion, and eventual resting places of all the balls with a <a title="Computer program" href="http://en.wikipedia.org/wiki/Computer_program"><font color=#002bb8>computer program</font></a>. A program to simulate this game would consist of several portions, one of which would be responsible for calculating the precise impacts between the billiard balls. This particular example also turns out to be <a title="Numerical stability" href="http://en.wikipedia.org/wiki/Numerical_stability"><font color=#002bb8>numerically unstable</font></a>: a small error in any calculation will cause drastic changes in the final position of the billiard balls.</p>
<p>Video games have similar requirements, with some crucial differences. While physical simulation needs to simulate real-world physics as precisely as possible, video games need to simulate real-world physics in an <em>acceptable</em> way, in <a title="Real-time computing" href="http://en.wikipedia.org/wiki/Real-time_computing"><font color=#002bb8>real time</font></a> and robustly. Compromises are allowed, so long as the resulting simulation is satisfying to the game player.</p>
<p><a id=Collision_detection_in_physical_simulation name=Collision_detection_in_physical_simulation></a></p>
<h2><span class=editsection>[<a title="Edit section: Collision detection in physical simulation" href="http://en.wikipedia.org/w/index.php?title=Collision_detection&amp;action=edit&amp;section=2"><font color=#002bb8>edit</font></a>]</span> <span class=mw-headline>Collision detection in physical simulation</span></h2>
<p>Physical simulators differ in the way they react on a collision. Some use the softness of the material to calculate a force, which will resolve the collision in the following time steps like it is in reality. Due to the low softness of some materials this is very CPU intensive. Some simulators estimate the time of collision by linear interpolation, <a title="Rollback (data management)" href="http://en.wikipedia.org/wiki/Rollback_(data_management)"><font color=#002bb8>roll back</font></a> the simulation, and calculate the collision by the more abstract methods of <a class=mw-redirect title="Conservation laws" href="http://en.wikipedia.org/wiki/Conservation_laws"><font color=#002bb8>conservation laws</font></a>.</p>
<p>Some iterate the linear interpolation (<a title="Newton's method" href="http://en.wikipedia.org/wiki/Newton%27s_method"><font color=#002bb8>Newton's method</font></a>) to calculate the time of collision with a much higher precision than the rest of the simulation. Collision detection utilizes time coherence to allow ever finer time steps without much increasing CPU demand, such as in <a title="Air traffic control" href="http://en.wikipedia.org/wiki/Air_traffic_control"><font color=#002bb8>air traffic control</font></a>.</p>
<p>After an inelastic collision, special states of sliding and resting can occur and, for example, the <a title="Open Dynamics Engine" href="http://en.wikipedia.org/wiki/Open_Dynamics_Engine"><font color=#002bb8>Open Dynamics Engine</font></a> uses constrains to simulate them. Constrains avoid inertia and thus instability. Implementation of rest by means of a <a title="Scene graph" href="http://en.wikipedia.org/wiki/Scene_graph"><font color=#002bb8>scene graph</font></a> avoids drift.</p>
<p>In other words, physical simulators usually function one of two ways, where the collision is detected <a title="A priori and a posteriori (philosophy)" href="http://en.wikipedia.org/wiki/A_priori_and_a_posteriori_(philosophy)"><em><font color=#002bb8>a posteriori</font></em></a> (after the collision occurs) or <a title="A priori and a posteriori (philosophy)" href="http://en.wikipedia.org/wiki/A_priori_and_a_posteriori_(philosophy)"><em><font color=#002bb8>a priori</font></em></a> (before the collision occurs). In addition to the <em>a posteriori</em> and <em>a priori</em> distinction, almost all modern collision detection algorithms are broken into a hierarchy of algorithms.</p>
<p><a id=A_posteriori_versus_a_priori name=A_posteriori_versus_a_priori></a></p>
<h3><span class=editsection>[<a title="Edit section: A posteriori versus a priori" href="http://en.wikipedia.org/w/index.php?title=Collision_detection&amp;action=edit&amp;section=3"><font color=#002bb8>edit</font></a>]</span> <span class=mw-headline>A posteriori versus a priori</span></h3>
<p>In the <em>a posteriori</em> case, we advance the physical simulation by a small time step, then check if any objects are intersecting, or are somehow so close to each other that we deem them to be intersecting. At each simulation step, a list of all intersecting bodies is created, and the positions and trajectories of these objects are somehow "fixed" to account for the collision. We say that this method is <em>a posteriori</em> because we typically miss the actual instant of collision, and only catch the collision after it has actually happened.</p>
<p>In the <em>a priori</em> methods, we write a collision detection algorithm which will be able to predict very precisely the trajectories of the physical bodies. The instants of collision are calculated with high precision, and the physical bodies never actually interpenetrate. We call this <em>a priori</em> because we calculate the instants of collision before we update the configuration of the physical bodies.</p>
<p>The main benefits of the <em>a posteriori</em> methods are as follows. In this case, the collision detection algorithm need not be aware of the myriad physical variables; a simple list of physical bodies is fed to the algorithm, and the program returns a list of intersecting bodies. The collision detection algorithm doesn't need to understand friction, elastic collisions, or worse, nonelastic collisions and deformable bodies. In addition, the <em>a posteriori</em> algorithms are in effect one dimension simpler than the <em>a priori</em> algorithms. Indeed, an <em>a priori</em> algorithm must deal with the time variable, which is absent from the <em>a posteriori</em> problem.</p>
<p>On the other hand, <em>a posteriori</em> algorithms cause problems in the "fixing" step, where intersections (which aren't physically correct) need to be corrected. In fact, there are some<sup class="noprint Inline-Template"><span title="The material in the vicinity of this tag may use weasel words or too-vague attribution." style="WHITE-SPACE: nowrap">[<em><a title="Wikipedia:Avoid weasel words" href="http://en.wikipedia.org/wiki/Wikipedia:Avoid_weasel_words"><font color=#002bb8>who?</font></a></em>]</span></sup> who believe that such an algorithm is inherently flawed and unstable<sup class="noprint Template-Fact"><span title="This claim needs references to reliable sources&nbsp;since August 2008" style="WHITE-SPACE: nowrap">[<em><a title="Wikipedia:Citation needed" href="http://en.wikipedia.org/wiki/Wikipedia:Citation_needed"><font color=#002bb8>citation needed</font></a></em>]</span></sup>.</p>
<p>The benefits of the <em>a priori</em> algorithms are increased fidelity and stability. It is difficult (but not completely impossible) to separate the physical simulation from the collision detection algorithm. However, in all but the simplest cases, the problem of determining ahead of time when two bodies will collide (given some initial data) has no closed form solution -- a numerical <a title="Root-finding algorithm" href="http://en.wikipedia.org/wiki/Root-finding_algorithm"><font color=#002bb8>root finder</font></a> is usually involved.</p>
<p>Some objects are in <em>resting contact</em>, that is, in collision, but neither bouncing off, nor interpenetrating, such as a vase resting on a table. In all cases, resting contact requires special treatment: If two objects collide (<em>a posteriori</em>) or slide (<em>a priori</em>) and their relative motion is below a threshold, friction becomes <a title=Stiction href="http://en.wikipedia.org/wiki/Stiction"><font color=#002bb8>stiction</font></a> and both objects are arranged in the same branch of the <a title="Scene graph" href="http://en.wikipedia.org/wiki/Scene_graph"><font color=#002bb8>scene graph</font></a>; however, some believe that it poses special problems in <em>a posteriori</em> algorithm<sup class="noprint Template-Fact"><span title="This claim needs references to reliable sources&nbsp;since February 2007" style="WHITE-SPACE: nowrap">[<em><a title="Wikipedia:Citation needed" href="http://en.wikipedia.org/wiki/Wikipedia:Citation_needed"><font color=#002bb8>citation needed</font></a></em>]</span></sup>.</p>
<p><a id=Optimization name=Optimization></a></p>
<h2><span class=editsection>[<a title="Edit section: Optimization" href="http://en.wikipedia.org/w/index.php?title=Collision_detection&amp;action=edit&amp;section=4"><font color=#002bb8>edit</font></a>]</span> <span class=mw-headline>Optimization</span></h2>
<p>The obvious approaches to collision detection for multiple objects are very slow. Checking every object against every other object will, of course, work, but is too inefficient to be used when the number of objects is at all large. Checking objects with complex geometry against each other in the obvious way, by checking each face against each other face, is itself quite slow. Thus, considerable research has been applied to speeding up the problem.</p>
<p><a id=Exploiting_temporal_coherence name=Exploiting_temporal_coherence></a></p>
<h3><span class=editsection>[<a title="Edit section: Exploiting temporal coherence" href="http://en.wikipedia.org/w/index.php?title=Collision_detection&amp;action=edit&amp;section=5"><font color=#002bb8>edit</font></a>]</span> <span class=mw-headline>Exploiting temporal coherence</span></h3>
<p>In many applications, the configuration of physical bodies from one time step to the next changes very little. Many of the objects may not move at all. Algorithms have been designed so that the calculations done in a preceding time step can be reused in the current time step, resulting in faster algorithms.</p>
<p>At the coarse level of collision detection, the objective is to find pairs of objects which might potentially intersect. Those pairs will require further analysis. An early high performance algorithm for this was developed by M. C. Lin at U.C. Berkley <a class="external autonumber" title=http://www.cs.berkeley.edu/~jfc/mirtich/collDet.html href="http://www.cs.berkeley.edu/~jfc/mirtich/collDet.html" rel=nofollow><font color=#3366bb>[1]</font></a>, who suggested using <a class=mw-redirect title="Axis-aligned bounding box" href="http://en.wikipedia.org/wiki/Axis-aligned_bounding_box"><font color=#002bb8>axis-aligned bounding boxes</font></a> for all n bodies in the scene.</p>
<p>Each box is represented by the product of three intervals (i.e., a box would be <span class=tex style="DISPLAY: inline-block; FONT-SIZE: 0px; BORDER-LEFT-COLOR: black; BACKGROUND-IMAGE: none; BORDER-BOTTOM-COLOR: black; VERTICAL-ALIGN: middle; BORDER-TOP-COLOR: black; BORDER-RIGHT-COLOR: black"><span style="DISPLAY: inline-block; FILTER: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='http://upload.wikimedia.org/math/1/f/3/1f371e2f64c44695e65b9c0c22f1c682.png'); WIDTH: 1px; HEIGHT: 1px"></span></span>.) A common algorithm for collision detection of bounding boxes is <a title="Sweep and prune" href="http://en.wikipedia.org/wiki/Sweep_and_prune"><font color=#002bb8>sweep and prune</font></a>. We observe that two such boxes, <span class=tex style="DISPLAY: inline-block; FONT-SIZE: 0px; BORDER-LEFT-COLOR: black; BACKGROUND-IMAGE: none; BORDER-BOTTOM-COLOR: black; VERTICAL-ALIGN: middle; BORDER-TOP-COLOR: black; BORDER-RIGHT-COLOR: black"><span style="DISPLAY: inline-block; FILTER: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='http://upload.wikimedia.org/math/2/b/d/2bd2da79778a74d1869d3a6a3b58eaa0.png'); WIDTH: 1px; HEIGHT: 1px"></span></span>and <span class=tex style="DISPLAY: inline-block; FONT-SIZE: 0px; BORDER-LEFT-COLOR: black; BACKGROUND-IMAGE: none; BORDER-BOTTOM-COLOR: black; VERTICAL-ALIGN: middle; BORDER-TOP-COLOR: black; BORDER-RIGHT-COLOR: black"><span style="DISPLAY: inline-block; FILTER: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='http://upload.wikimedia.org/math/2/9/d/29d807c3dca041bdc0d0927d8e07ef32.png'); WIDTH: 1px; HEIGHT: 1px"></span></span>intersect if, and only if, <span class=texhtml><em>I</em><sub>1</sub></span> intersects <span class=texhtml><em>J</em><sub>1</sub></span>, <span class=texhtml><em>I</em><sub>2</sub></span> intersects <span class=texhtml><em>J</em><sub>2</sub></span> and <span class=texhtml><em>I</em><sub>3</sub></span> intersects <span class=texhtml><em>J</em><sub>3</sub></span>. We suppose that, from one time step to the next, <span class=texhtml><em>I</em><sub><em>k</em></sub></span> and <span class=texhtml><em>J</em><sub><em>k</em></sub></span> intersect, then it is very likely that at the next time step, they will still intersect. Likewise, if they did not intersect in the previous time step, then they are very likely to continue not to.</p>
<p>So we reduce the problem to that of tracking, from frame to frame, which intervals do intersect. We have three lists of intervals (one for each axis) and all lists are the same length (since each list has length <span class=texhtml><em>n</em></span>, the number of bounding boxes.) In each list, each interval is allowed to intersect all other intervals in the list. So for each list, we will have an <span class=tex style="DISPLAY: inline-block; FONT-SIZE: 0px; BORDER-LEFT-COLOR: black; BACKGROUND-IMAGE: none; BORDER-BOTTOM-COLOR: black; VERTICAL-ALIGN: middle; BORDER-TOP-COLOR: black; BORDER-RIGHT-COLOR: black"><span style="DISPLAY: inline-block; FILTER: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='http://upload.wikimedia.org/math/6/0/7/607acaa73c762411b20745149a11e90b.png'); WIDTH: 1px; HEIGHT: 1px"></span></span><a class=mw-redirect title="Matrix (math)" href="http://en.wikipedia.org/wiki/Matrix_(math)"><font color=#002bb8>matrix</font></a> <span class=texhtml><em>M</em> = (<em>m</em><sub><em>i</em><em>j</em></sub>)</span> of zeroes and ones: <span class=texhtml><em>m</em><sub><em>i</em><em>j</em></sub></span> is 1 if intervals <span class=texhtml><em>i</em></span> and <span class=texhtml><em>j</em></span> intersect, and 0 if they do not intersect.</p>
<p>By our assumption, the matrix <span class=texhtml><em>M</em></span> associated to a list of intervals will remain essentially unchanged from one time step to the next. To exploit this, the list of intervals is actually maintained as a list of labeled endpoints. Each element of the list has the coordinate of an endpoint of an interval, as well as a unique integer identifying that interval. Then, we <a title="Sorting algorithm" href="http://en.wikipedia.org/wiki/Sorting_algorithm"><font color=#002bb8>sort</font></a> the list by coordinates, and update the matrix <span class=texhtml><em>M</em></span> as we go. It's not so hard to believe that this algorithm will work relatively quickly if indeed the configuration of bounding boxes does not change significantly from one time step to the next.</p>
<p>In the case of deformable bodies such as cloth simulation, it may not be possible to use a more specific pairwise pruning algorithm as discussed below, and an <em>n</em>-body pruning algorithm is the best that can be done.</p>
<p>If an upper bound can be placed on the velocity of the physical bodies in a scene, then pairs of objects can be pruned based on their initial distance and the size of the time step.</p>
<p><a id=Pairwise_pruning name=Pairwise_pruning></a></p>
<h3><span class=editsection>[<a title="Edit section: Pairwise pruning" href="http://en.wikipedia.org/w/index.php?title=Collision_detection&amp;action=edit&amp;section=6"><font color=#002bb8>edit</font></a>]</span> <span class=mw-headline>Pairwise pruning</span></h3>
<p>Once we've selected a pair of physical bodies for further investigation, we need to check for collisions more carefully. However, in many applications, individual objects (if they are not too deformable) are described by a set of smaller primitives, mainly triangles. So now, we have two sets of triangles, <span class=tex style="DISPLAY: inline-block; FONT-SIZE: 0px; BORDER-LEFT-COLOR: black; BACKGROUND-IMAGE: none; BORDER-BOTTOM-COLOR: black; VERTICAL-ALIGN: middle; BORDER-TOP-COLOR: black; BORDER-RIGHT-COLOR: black"><span style="DISPLAY: inline-block; FILTER: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='http://upload.wikimedia.org/math/b/1/5/b150f86ec8067e3bff0c182258256c37.png'); WIDTH: 1px; HEIGHT: 1px"></span></span>and <span class=tex style="DISPLAY: inline-block; FONT-SIZE: 0px; BORDER-LEFT-COLOR: black; BACKGROUND-IMAGE: none; BORDER-BOTTOM-COLOR: black; VERTICAL-ALIGN: middle; BORDER-TOP-COLOR: black; BORDER-RIGHT-COLOR: black"><span style="DISPLAY: inline-block; FILTER: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='http://upload.wikimedia.org/math/f/8/2/f82aabbf434b2ba44f156e032b739562.png'); WIDTH: 1px; HEIGHT: 1px"></span></span>(for simplicity, we will assume that each set has the same number of triangles.)</p>
<p>The obvious thing to do is to check all triangles <span class=texhtml><em>S</em><sub><em>j</em></sub></span> against all triangles <span class=texhtml><em>T</em><sub><em>k</em></sub></span> for collisions, but this involves <span class=texhtml><em>n</em><sup>2</sup></span> comparisons, which is highly inefficient. If possible, it is desirable to use a pruning algorithm to reduce the number of pairs of triangles we need to check.</p>
<p>The most widely used family of algorithms is known as the <em>hierarchical bounding volumes</em> method. As a preprocessing step, for each object (in our example, <span class=texhtml><em>S</em></span> and <span class=texhtml><em>T</em></span>) we will calculate a hierarchy of bounding volumes. Then, at each time step, when we need to check for collisions between <span class=texhtml><em>S</em></span> and <span class=texhtml><em>T</em></span>, the hierarchical bounding volumes are used to reduce the number of pairs of triangles under consideration. For the sake of simplicity, we will give an example using bounding spheres, although it has been noted that spheres are undesirable in many cases.<sup class="noprint Template-Fact"><span title="This claim needs references to reliable sources&nbsp;since June 2008" style="WHITE-SPACE: nowrap">[<em><a title="Wikipedia:Citation needed" href="http://en.wikipedia.org/wiki/Wikipedia:Citation_needed"><font color=#002bb8>citation needed</font></a></em>]</span></sup></p>
<p>If <span class=texhtml><em>E</em></span> is a set of triangles, we can precalculate a bounding sphere <span class=texhtml><em>B</em>(<em>E</em>)</span>. There are many ways of choosing <span class=texhtml><em>B</em>(<em>E</em>)</span>, we only assume that <span class=texhtml><em>B</em>(<em>E</em>)</span> is a sphere that completely contains <span class=texhtml><em>E</em></span> and is as small as possible.</p>
<p>Ahead of time, we can compute <span class=texhtml><em>B</em>(<em>S</em>)</span> and <span class=texhtml><em>B</em>(<em>T</em>)</span>. Clearly, if these two spheres do not intersect (and that is very easy to test,) then neither do <span class=texhtml><em>S</em></span> and <span class=texhtml><em>T</em></span>. This is not much better than an <em>n</em>-body pruning algorithm, however.</p>
<p>If <span class=tex style="DISPLAY: inline-block; FONT-SIZE: 0px; BORDER-LEFT-COLOR: black; BACKGROUND-IMAGE: none; BORDER-BOTTOM-COLOR: black; VERTICAL-ALIGN: middle; BORDER-TOP-COLOR: black; BORDER-RIGHT-COLOR: black"><span style="DISPLAY: inline-block; FILTER: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='http://upload.wikimedia.org/math/4/a/5/4a5f9e8499dc0a3907fc05b75ec01609.png'); WIDTH: 1px; HEIGHT: 1px"></span></span>is a set of triangles, then we can split it into two halves <span class=tex style="DISPLAY: inline-block; FONT-SIZE: 0px; BORDER-LEFT-COLOR: black; BACKGROUND-IMAGE: none; BORDER-BOTTOM-COLOR: black; VERTICAL-ALIGN: middle; BORDER-TOP-COLOR: black; BORDER-RIGHT-COLOR: black"><span style="DISPLAY: inline-block; FILTER: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='http://upload.wikimedia.org/math/4/e/d/4ed433aa71ab0b41dee53ea50e57ed06.png'); WIDTH: 1px; HEIGHT: 1px"></span></span>and <span class=tex style="DISPLAY: inline-block; FONT-SIZE: 0px; BORDER-LEFT-COLOR: black; BACKGROUND-IMAGE: none; BORDER-BOTTOM-COLOR: black; VERTICAL-ALIGN: middle; BORDER-TOP-COLOR: black; BORDER-RIGHT-COLOR: black"><span style="DISPLAY: inline-block; FILTER: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='http://upload.wikimedia.org/math/3/0/7/3079eae29bfea791f1b60a4b690ecd75.png'); WIDTH: 1px; HEIGHT: 1px"></span></span>. We can do this to <span class=texhtml><em>S</em></span> and <span class=texhtml><em>T</em></span>, and we can calculate (ahead of time) the bounding spheres <span class=texhtml><em>B</em>(<em>L</em>(<em>S</em>)),<em>B</em>(<em>R</em>(<em>S</em>))</span> and <span class=texhtml><em>B</em>(<em>L</em>(<em>T</em>)),<em>B</em>(<em>R</em>(<em>T</em>))</span>. The hope here is that these bounding spheres are much smaller than <span class=texhtml><em>B</em>(<em>S</em>)</span> and <span class=texhtml><em>B</em>(<em>T</em>)</span>. And, if, for instance, <span class=texhtml><em>B</em>(<em>S</em>)</span> and <span class=texhtml><em>B</em>(<em>L</em>(<em>T</em>))</span> do not intersect, then there is no sense in checking any triangle in <span class=texhtml><em>S</em></span> against any triangle in <span class=texhtml><em>L</em>(<em>T</em>)</span>.</p>
<p>As a precomputation, we can take each physical body (represented by a set of triangles) and recursively decompose it into a <a title="Binary tree" href="http://en.wikipedia.org/wiki/Binary_tree"><font color=#002bb8>binary tree</font></a>, where each node <span class=texhtml><em>N</em></span> represents a set of triangles, and its two children represent <span class=texhtml><em>L</em>(<em>N</em>)</span> and <span class=texhtml><em>R</em>(<em>N</em>)</span>. At each node in the tree, as a we can precompute the bounding sphere <span class=texhtml><em>B</em>(<em>N</em>)</span>.</p>
<p>When the time comes for testing a pair of objects for collision, their bounding sphere tree can be used to eliminate many pairs of triangles.</p>
<p>Many variants of the algorithms are obtained by choosing something other than a sphere for <span class=texhtml><em>B</em>(<em>T</em>)</span>. If one chooses <a class=mw-redirect title="Axis-aligned bounding box" href="http://en.wikipedia.org/wiki/Axis-aligned_bounding_box"><font color=#002bb8>axis-aligned bounding boxes</font></a>, one gets AABBTrees. <a class=mw-redirect title="Oriented bounding box" href="http://en.wikipedia.org/wiki/Oriented_bounding_box"><font color=#5a3696>Oriented bounding box</font></a> trees are called OBBTrees. Some trees are easier to update if the underlying object changes. Some trees can accommodate higher order primitives such as <a title="Spline (mathematics)" href="http://en.wikipedia.org/wiki/Spline_(mathematics)"><font color=#002bb8>splines</font></a> instead of simple triangles.</p>
<p><a id=Exact_pairwise_collision_detection name=Exact_pairwise_collision_detection></a></p>
<h3><span class=editsection>[<a title="Edit section: Exact pairwise collision detection" href="http://en.wikipedia.org/w/index.php?title=Collision_detection&amp;action=edit&amp;section=7"><font color=#002bb8>edit</font></a>]</span> <span class=mw-headline>Exact pairwise collision detection</span></h3>
<p>Once we're done pruning, we are left with a number of candidate pairs to check for exact collision detection.</p>
<p>A basic observation is that for any two <a title="Convex set" href="http://en.wikipedia.org/wiki/Convex_set"><font color=#002bb8>convex</font></a> objects which are disjoint, one can find a plane in space so that one object lies completely on one side of that plane, and the other object lies on the opposite side of that plane. This allows the development of very fast collision detection algorithms for convex objects.</p>
<p>Early work in this area involved "<a title="Separating axis theorem" href="http://en.wikipedia.org/wiki/Separating_axis_theorem"><font color=#002bb8>separating plane</font></a>" methods. Two triangles collide essentially only when they can not be separated by a plane going through three vertices. That is, if the triangles are <span class=texhtml><em>v</em><sub>1</sub>,<em>v</em><sub>2</sub>,<em>v</em><sub>3</sub></span> and <span class=texhtml><em>v</em><sub>4</sub>,<em>v</em><sub>5</sub>,<em>v</em><sub>6</sub></span> where each <span class=texhtml><em>v</em><sub><em>j</em></sub></span> is a vector in <span class=tex style="DISPLAY: inline-block; FONT-SIZE: 0px; BORDER-LEFT-COLOR: black; BACKGROUND-IMAGE: none; BORDER-BOTTOM-COLOR: black; VERTICAL-ALIGN: middle; BORDER-TOP-COLOR: black; BORDER-RIGHT-COLOR: black"><span style="DISPLAY: inline-block; FILTER: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='http://upload.wikimedia.org/math/c/3/5/c35ed5f43a2953196b55e5207a2c959e.png'); WIDTH: 1px; HEIGHT: 1px"></span></span>, then we can take three vertices, <span class=texhtml><em>v</em><sub><em>i</em></sub>,<em>v</em><sub><em>j</em></sub>,<em>v</em><sub><em>k</em></sub></span>, find a plane going through all three vertices, and check to see if this is a separating plane. If any such plane is a separating plane, then the triangles are deemed to be disjoint. On the other hand, if none of these planes are separating planes, then the triangles are deemed to intersect. There are twenty such planes.</p>
<p>If the triangles are coplanar, this test is not entirely successful. One can either add some extra planes, for instance, planes that are normal to triangle edges, to fix the problem entirely. In other cases, objects that meet at a flat face must necessarily also meet at an angle elsewhere, hence the overall collision detection will be able to find the collision.</p>
<p>Better methods have since been developed. Very fast algorithms are available for finding the closest points on the surface of two convex polyhedral objects. Early work by M. C. Lin <sup class=reference id=cite_ref-0><a title="" href="http://en.wikipedia.org/wiki/Collision_detection#cite_note-0"><font color=#5a3696><span>[</span>1<span>]</span></font></a></sup> used a variation on the <a title="Simplex algorithm" href="http://en.wikipedia.org/wiki/Simplex_algorithm"><font color=#002bb8>simplex algorithm</font></a> from <a title="Linear programming" href="http://en.wikipedia.org/wiki/Linear_programming"><font color=#002bb8>linear programming</font></a>. The <a class=mw-redirect title="Gilbert-Johnson-Keerthi distance algorithm" href="http://en.wikipedia.org/wiki/Gilbert-Johnson-Keerthi_distance_algorithm"><font color=#002bb8>Gilbert-Johnson-Keerthi distance algorithm</font></a> has superseded that approach. These algorithms approach constant time when applied repeatedly to pairs of stationary or slow-moving objects, when used with starting points from the previous collision check.</p>
<p>The end result of all this algorithmic work is that collision detection can be done efficiently for thousands of moving objects in real time on typical personal computers and game consoles.</p>
<p><a id=A_priori_pruning name=A_priori_pruning></a></p>
<h3><span class=editsection>[<a title="Edit section: A priori pruning" href="http://en.wikipedia.org/w/index.php?title=Collision_detection&amp;action=edit&amp;section=8"><font color=#002bb8>edit</font></a>]</span> <span class=mw-headline>A priori pruning</span></h3>
<p>Where most of the objects involved are fixed, as is typical of video games, a priori methods using precomputation can be used to speed up execution.</p>
<p>Pruning is also desirable here, both <em>n</em>-body pruning and pairwise pruning, but the algorithms must take time and the types of motions used in the underlying physical system into consideration.</p>
<p>When it comes to the exact pairwise collision detection, this is highly trajectory dependent, and one almost has to use a numerical <a title="Root-finding algorithm" href="http://en.wikipedia.org/wiki/Root-finding_algorithm"><font color=#002bb8>root-finding algorithm</font></a> to compute the instant of impact.</p>
<p>As an example, consider two triangles moving in time <span class=texhtml><em>v</em><sub>1</sub>(<em>t</em>),<em>v</em><sub>2</sub>(<em>t</em>),<em>v</em><sub>3</sub>(<em>t</em>)</span> and <span class=texhtml><em>v</em><sub>4</sub>(<em>t</em>),<em>v</em><sub>5</sub>(<em>t</em>),<em>v</em><sub>6</sub>(<em>t</em>)</span>. At any point in time, the two triangles can be checked for intersection using the twenty planes previously mentioned. However, we can do better, since these twenty planes can all be tracked in time. If <span class=texhtml><em>P</em>(<em>u</em>,<em>v</em>,<em>w</em>)</span> is the plane going through points <span class=texhtml><em>u</em>,<em>v</em>,<em>w</em></span> in <span class=tex style="DISPLAY: inline-block; FONT-SIZE: 0px; BORDER-LEFT-COLOR: black; BACKGROUND-IMAGE: none; BORDER-BOTTOM-COLOR: black; VERTICAL-ALIGN: middle; BORDER-TOP-COLOR: black; BORDER-RIGHT-COLOR: black"><span style="DISPLAY: inline-block; FILTER: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='http://upload.wikimedia.org/math/c/3/5/c35ed5f43a2953196b55e5207a2c959e.png'); WIDTH: 1px; HEIGHT: 1px"></span></span>then there are twenty planes <span class=texhtml><em>P</em>(<em>v</em><sub><em>i</em></sub>(<em>t</em>),<em>v</em><sub><em>j</em></sub>(<em>t</em>),<em>v</em><sub><em>k</em></sub>(<em>t</em>))</span> to track. Each plane needs to be tracked against three vertices, this gives sixty values to track. Using a root finder on these sixty functions produces the exact collision times for the two given triangles and the two given trajectory. We note here that if the trajectories of the vertices are assumed to be linear polynomials in <span class=texhtml><em>t</em></span> then the final sixty functions are in fact cubic polynomials, and in this exceptional case, it is possible to locate the exact collision time using the formula for the roots of the cubic. Some numerical analysts suggest that using the formula for the roots of the cubic is not as numerically stable as using a root finder for polynomials.<sup class="noprint Template-Fact"><span title="This claim needs references to reliable sources&nbsp;since June 2008" style="WHITE-SPACE: nowrap">[<em><a title="Wikipedia:Citation needed" href="http://en.wikipedia.org/wiki/Wikipedia:Citation_needed"><font color=#002bb8>citation needed</font></a></em>]</span></sup></p>
<p><a id=Spatial_partitioning name=Spatial_partitioning></a></p>
<h3><span class=editsection>[<a title="Edit section: Spatial partitioning" href="http://en.wikipedia.org/w/index.php?title=Collision_detection&amp;action=edit&amp;section=9"><font color=#002bb8>edit</font></a>]</span> <span class=mw-headline>Spatial partitioning</span></h3>
<p>Alternative algorithms are grouped under the <a class=mw-redirect title="Spatial partitioning" href="http://en.wikipedia.org/wiki/Spatial_partitioning"><font color=#002bb8>spatial partitioning</font></a> umbrella, which includes <a title=Octree href="http://en.wikipedia.org/wiki/Octree"><font color=#002bb8>octrees</font></a>, <a title="Binary space partitioning" href="http://en.wikipedia.org/wiki/Binary_space_partitioning"><font color=#002bb8>binary space partitioning</font></a> (or BSP trees) and other, similar approaches. If one splits space into a number of simple cells, and if two objects can be shown not to be in the same cell, then they need not be checked for intersection. Since BSP trees can be precomputed, that approach is well suited to handling walls and fixed obstacles in games. These algorithms are generally older than the algorithms described above.</p>
<p><a id=Video_games name=Video_games></a></p>
<h2><span class=editsection>[<a title="Edit section: Video games" href="http://en.wikipedia.org/w/index.php?title=Collision_detection&amp;action=edit&amp;section=10"><font color=#002bb8>edit</font></a>]</span> <span class=mw-headline>Video games</span></h2>
<p>Video games have to split their very limited computing time between several tasks. Despite this resource limit, and the use of relatively primitive collision detection algorithms, programmers have been able to create believeable, if inexact, systems for use in games.</p>
<p>For a long time, video games had a very limited number of objects to treat, and so checking all pairs was not a problem. In two-dimensional games, in some cases, the hardware was able to efficiently detect and report overlapping pixels between <a title="Sprite (computer graphics)" href="http://en.wikipedia.org/wiki/Sprite_(computer_graphics)"><font color=#002bb8>sprites</font></a> on the screen. In other cases, simply tiling the screen and binding each <em>sprite</em> into the tiles it overlaps provides sufficient pruning, and for pairwise checks, bounding rectangles or circles are used and deemed sufficiently accurate.</p>
<p>Three dimensional games have used spatial partitioning methods for <span class=texhtml><em>n</em></span>-body pruning, and for a long time used one or a few spheres per actual 3D object for pairwise checks. Exact checks are very rare, except in games attempting to <a title="Simulation game" href="http://en.wikipedia.org/wiki/Simulation_game"><font color=#002bb8>simulate</font></a> reality closely. Even then, exact checks are not necessarily used in all cases.</p>
<p>Because games use simplified physics, stability is not as much of an issue.<sup class="noprint Template-Fact"><span title="This claim needs references to reliable sources&nbsp;since June 2008" style="WHITE-SPACE: nowrap">[<em><a title="Wikipedia:Citation needed" href="http://en.wikipedia.org/wiki/Wikipedia:Citation_needed"><font color=#002bb8>citation needed</font></a></em>]</span></sup> Almost all games use <em>a posteriori</em> collision detection, and collisions are often resolved using very simple rules. For instance, if a character becomes embedded in a wall, he might be simply moved back to his last known good location. Some games will calculate the distance the character can move before getting embedded into a wall, and only allow him to move that far.</p>
<p>A slightly more sophisticated and striking effect is <a title="Ragdoll physics" href="http://en.wikipedia.org/wiki/Ragdoll_physics"><font color=#002bb8>ragdoll physics</font></a>. If a video game character is disabled, instead of playing a preset animation, a simplified skeleton of the character is animated as if it were a rag doll. This rag doll falls limp, and might collide with itself and the environment, in which case it should behave appropriately.</p>
<p>In many cases for video games, approximating the characters by a point is sufficient for the purpose of collision detection with the environment. In this case, binary space partition trees provide a viable, efficient and simple algorithm for checking if a point is embedded in the scenery or not. Such a data structure can also be used to handle "resting position" situation gracefully when a character is running along the ground. Collisions between characters, and collisions with projectiles and hazards, are treated separately.</p>
<p>A robust simulator is one that will react to any input in a reasonable way. For instance, if we imagine a high speed <a title="Racing game" href="http://en.wikipedia.org/wiki/Racing_game"><font color=#002bb8>racecar video game</font></a>, from one simulation step to the next, it is conceivable that the cars would advance a substantial distance along the race track. If there is a shallow obstacle on the track (such as a brick wall), it is not entirely unlikely that the car will completely leap over it, and this is very undesirable. In other instances, the "fixing" that the a posteriori algorithms require isn't implemented correctly, and characters find themselves embedded in walls, or falling off into a deep black void. These are the hallmarks of a mediocre collision detection and physical simulation system.</p>
<p><a id=Open_Source_Collision_Detection name=Open_Source_Collision_Detection></a></p>
<h2><span class=editsection>[<a title="Edit section: Open Source Collision Detection" href="http://en.wikipedia.org/w/index.php?title=Collision_detection&amp;action=edit&amp;section=11"><font color=#002bb8>edit</font></a>]</span> <span class=mw-headline>Open Source Collision Detection</span></h2>
<ul>
    <li><a class="external text" title=http://code.google.com/p/gjkd/ href="http://code.google.com/p/gjkd/" rel=nofollow><font color=#3366bb>GJKD</font></a> A 2D implementation of the Gilbert-Johnson-Keerthi (GJK) algorithm, written in D.
    <li><a class="external text" title=http://code.google.com/p/mpr2d/ href="http://code.google.com/p/mpr2d/" rel=nofollow><font color=#3366bb>MPR2D</font></a> A 2D implementation of the Minkowski Portal Refinement (MPR) Algorithm, written in D. </li>
</ul>
<p><a id=References name=References></a></p>
<h2><span class=editsection>[<a title="Edit section: References" href="http://en.wikipedia.org/w/index.php?title=Collision_detection&amp;action=edit&amp;section=12"><font color=#002bb8>edit</font></a>]</span> <span class=mw-headline>References</span></h2>
<ol class=references>
    <li id=cite_note-0><strong><a title="" href="http://en.wikipedia.org/wiki/Collision_detection#cite_ref-0"><font color=#5a3696>^</font></a></strong> Lin, Ming C. "<em><a class="external text" title=ftp://ftp.cs.unc.edu/pub/users/manocha/PAPERS/COLLISION/thesis.pdf href="ftp://ftp.cs.unc.edu/pub/users/manocha/PAPERS/COLLISION/thesis.pdf" rel=nofollow><font color=#3366bb>Efficient Collision Detection for Animation and Robotics (thesis)</font></a></em>". University of California, Berkeley. </li>
</ol>
<p><a id=See_also name=See_also></a></p>
<h2><span class=editsection>[<a title="Edit section: See also" href="http://en.wikipedia.org/w/index.php?title=Collision_detection&amp;action=edit&amp;section=13"><font color=#002bb8>edit</font></a>]</span> <span class=mw-headline>See also</span></h2>
<ul>
    <li><a title="Bounding volume" href="http://en.wikipedia.org/wiki/Bounding_volume"><font color=#002bb8>Bounding volume</font></a>
    <li><a title="Game physics" href="http://en.wikipedia.org/wiki/Game_physics"><font color=#002bb8>Game physics</font></a>
    <li><a title="Gilbert&#8211;Johnson&#8211;Keerthi distance algorithm" href="http://en.wikipedia.org/wiki/Gilbert%E2%80%93Johnson%E2%80%93Keerthi_distance_algorithm"><font color=#002bb8>Gilbert&#8211;Johnson&#8211;Keerthi distance algorithm</font></a>
    <li><a title="Physics engine" href="http://en.wikipedia.org/wiki/Physics_engine"><font color=#002bb8>Physics engine</font></a>
    <li><a title="Ragdoll physics" href="http://en.wikipedia.org/wiki/Ragdoll_physics"><font color=#002bb8>Ragdoll physics</font></a> </li>
</ul>
<p><a id=External_links name=External_links></a></p>
<h2><span class=editsection>[<a title="Edit section: External links" href="http://en.wikipedia.org/w/index.php?title=Collision_detection&amp;action=edit&amp;section=14"><font color=#002bb8>edit</font></a>]</span> <span class=mw-headline>External links</span></h2>
<ul>
    <li><a class="external text" title=http://www.cs.unc.edu/~geom/collide/ href="http://www.cs.unc.edu/~geom/collide/" rel=nofollow><font color=#3366bb>University of California, Berkeley collision detection research web site</font></a>
    <li><a class="external text" title=http://web.comlab.ox.ac.uk/oucl/work/stephen.cameron/distances/ href="http://web.comlab.ox.ac.uk/oucl/work/stephen.cameron/distances/" rel=nofollow><font color=#3366bb>Prof. Steven Cameron (Oxford University) web site on collision detection</font></a>
    <li><a class="external text" title=http://demonstrations.wolfram.com/HowToAvoidACollision/ href="http://demonstrations.wolfram.com/HowToAvoidACollision/" rel=nofollow><font color=#3366bb>How to Avoid a Collision</font></a> by George Beck, <a class=mw-redirect title="The Wolfram Demonstrations Project" href="http://en.wikipedia.org/wiki/The_Wolfram_Demonstrations_Project"><font color=#002bb8>The Wolfram Demonstrations Project</font></a>.
    <li><a class="external text" title=http://3dcodingtutorial.com/Collision-Detection/Collision-Boxes.html href="http://3dcodingtutorial.com/Collision-Detection/Collision-Boxes.html" rel=nofollow><font color=#3366bb>Basic collision detection in OpenGL</font></a>. </li>
</ul>
<!--
NewPP limit report
Preprocessor node count: 695/1000000
Post-expand include size: 7270/2048000 bytes
Template argument size: 2466/2048000 bytes
Expensive parser function count: 5/500
--><!-- Saved in parser cache with key enwiki:pcache:idhash:171552-0!1!0!default!!en!2 and timestamp 20081114013836 -->
<div class=printfooter>Retrieved from "<a href="http://en.wikipedia.org/wiki/Collision_detection"><font color=#5a3696>http://en.wikipedia.org/wiki/Collision_detection</font></a>"</div>
</div>
<img src ="http://www.cppblog.com/zmj/aggbug/67634.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/zmj/" target="_blank">zmj</a> 2008-11-22 23:25 <a href="http://www.cppblog.com/zmj/archive/2008/11/22/67634.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Bounding volume</title><link>http://www.cppblog.com/zmj/archive/2008/11/22/67615.html</link><dc:creator>zmj</dc:creator><author>zmj</author><pubDate>Sat, 22 Nov 2008 11:35:00 GMT</pubDate><guid>http://www.cppblog.com/zmj/archive/2008/11/22/67615.html</guid><wfw:comment>http://www.cppblog.com/zmj/comments/67615.html</wfw:comment><comments>http://www.cppblog.com/zmj/archive/2008/11/22/67615.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/zmj/comments/commentRss/67615.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/zmj/services/trackbacks/67615.html</trackback:ping><description><![CDATA[<a href="http://en.wikipedia.org/wiki/K-DOP">http://en.wikipedia.org/wiki/K-DOP</a><br>
<h1 class=firstHeading>Bounding volume</h1>
<div id=bodyContent>
<h3 id=siteSub>From Wikipedia, the free encyclopedia</h3>
<div id=contentSub>&nbsp;&nbsp;(Redirected from <a title=K-DOP href="http://en.wikipedia.org/w/index.php?title=K-DOP&amp;redirect=no"><font color=#5a3696>K-DOP</font></a>)</div>
<div id=jump-to-nav>Jump to: <a href="http://en.wikipedia.org/wiki/K-DOP#column-one"><font color=#5a3696>navigation</font></a>, <a href="http://en.wikipedia.org/wiki/K-DOP#searchInput"><font color=#5a3696>search</font></a></div>
<!-- start content -->
<div class="thumb tright">
<div class=thumbinner style="WIDTH: 182px"><a class=image title="A bounding box for a three dimensional model" href="http://en.wikipedia.org/wiki/Image:BoundingBox.jpg"><font color=#5a3696><img class=thumbimage height=183 alt="" src="http://upload.wikimedia.org/wikipedia/commons/thumb/7/7e/BoundingBox.jpg/180px-BoundingBox.jpg" width=180 border=0></font></a>
<div class=thumbcaption>
<div class=magnify><a class=internal title=Enlarge href="http://en.wikipedia.org/wiki/Image:BoundingBox.jpg"><span class="" style="BORDER-TOP-WIDTH: 2px; DISPLAY: inline-block; BORDER-LEFT-WIDTH: 2px; FONT-SIZE: 0px; BORDER-LEFT-COLOR: #0000ff; BACKGROUND-IMAGE: none; BORDER-BOTTOM-WIDTH: 2px; BORDER-BOTTOM-COLOR: #0000ff; VERTICAL-ALIGN: middle; CURSOR: hand; BORDER-TOP-COLOR: #0000ff; BORDER-RIGHT-WIDTH: 2px; BORDER-RIGHT-COLOR: #0000ff"><span style="DISPLAY: inline-block; FILTER: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='http://en.wikipedia.org/skins-1.5/common/images/magnify-clip.png'); WIDTH: 1px; HEIGHT: 1px"></span></span></a></div>
A bounding box for a three dimensional model</div>
</div>
</div>
<dl>
<dd><em>For <a title="Building code" href="http://en.wikipedia.org/wiki/Building_code"><font color=#002bb8>building code</font></a> compliance, see <a class=mw-redirect title=Bounding href="http://en.wikipedia.org/wiki/Bounding"><font color=#002bb8>Bounding</font></a>.</em> </dd></dl>
<p>In <a title="Computer graphics" href="http://en.wikipedia.org/wiki/Computer_graphics"><font color=#002bb8>computer graphics</font></a> and <a title="Computational geometry" href="http://en.wikipedia.org/wiki/Computational_geometry"><font color=#002bb8>computational geometry</font></a>, a <strong>bounding volume</strong> for a set of objects is a closed volume that completely contains the union of the objects in the set. Bounding volumes are used to improve the efficiency of geometrical operations by using simple volumes to contain more complex objects. Normally, simpler volumes have simpler ways to test for overlap.</p>
<p>A bounding volume for a set of objects is also a bounding volume for the single object consisting of their union, and the other way around. Therefore it is possible to confine the description to the case of a single object, which is assumed to be non-empty and bounded (finite).</p>
<table class=toc id=toc summary=Contents>
    <tbody>
        <tr>
            <td>
            <div id=toctitle>
            <h2>Contents</h2>
            <span class=toctoggle><font size=2>[</font><a class=internal id=togglelink href="javascript:toggleToc()"><font color=#002bb8 size=2>hide</font></a><font size=2>]</font></span></div>
            <ul>
                <li class=toclevel-1><a href="http://en.wikipedia.org/wiki/K-DOP#Uses_of_bounding_volumes"><font color=#5a3696><span class=tocnumber>1</span> <span class=toctext>Uses of bounding volumes</span></font></a>
                <li class=toclevel-1><a href="http://en.wikipedia.org/wiki/K-DOP#Common_types_of_bounding_volume"><font color=#5a3696><span class=tocnumber>2</span> <span class=toctext>Common types of bounding volume</span></font></a>
                <li class=toclevel-1><a href="http://en.wikipedia.org/wiki/K-DOP#Basic_intersection_checks"><font color=#5a3696><span class=tocnumber>3</span> <span class=toctext>Basic intersection checks</span></font></a>
                <li class=toclevel-1><a href="http://en.wikipedia.org/wiki/K-DOP#See_also"><font color=#5a3696><span class=tocnumber>4</span> <span class=toctext>See also</span></font></a>
                <li class=toclevel-1><a href="http://en.wikipedia.org/wiki/K-DOP#External_links"><font color=#5a3696><span class=tocnumber>5</span> <span class=toctext>External links</span></font></a> </li>
            </ul>
            </td>
        </tr>
    </tbody>
</table>
<script type=text/javascript>
//<![cdata[
if (window.showTocToggle) { var tocShowText = "show"; var tocHideText = "hide"; showTocToggle(); }
//]]&gt;
</script>
<p><a id=Uses_of_bounding_volumes name=Uses_of_bounding_volumes></a></p>
<h2><span class=editsection>[<a title="Edit section: Uses of bounding volumes" href="http://en.wikipedia.org/w/index.php?title=Bounding_volume&amp;action=edit&amp;section=1"><font color=#002bb8>edit</font></a>]</span> <span class=mw-headline>Uses of bounding volumes</span></h2>
<p>Bounding volumes are most often used to accelerate certain kinds of tests.</p>
<p>In <a title="Ray tracing" href="http://en.wikipedia.org/wiki/Ray_tracing"><font color=#002bb8>ray tracing</font></a>, bounding volumes are used in ray-intersection tests, and in many <a title="Rendering (computer graphics)" href="http://en.wikipedia.org/wiki/Rendering_(computer_graphics)"><font color=#002bb8>rendering</font></a> <a class=mw-redirect title=Algorithms href="http://en.wikipedia.org/wiki/Algorithms"><font color=#002bb8>algorithms</font></a>, they are used for <a title="Viewing frustum" href="http://en.wikipedia.org/wiki/Viewing_frustum"><font color=#002bb8>viewing frustum</font></a> tests. If the ray or viewing frustum does not intersect the bounding volume, it cannot intersect the object contained in the volume. These intersection tests produce a list of objects that must be displayed. Here, displayed means rendered or rasterized.</p>
<p>In <a title="Collision detection" href="http://en.wikipedia.org/wiki/Collision_detection"><font color=#002bb8>collision detection</font></a>, when two bounding volumes do not intersect, then the contained objects cannot collide, either.</p>
<p>Testing against a bounding volume is typically much faster than testing against the object itself, because of the bounding volume's simpler geometry. This is because an 'object' is typically composed of polygons or data structures that are reduced to polygonal approximations. In either case, it is computationally wasteful to test each polygon against the view volume if the object is not visible. (Onscreen objects must be 'clipped' to the screen, regardless of whether their surfaces are actually visible.)</p>
<p>To obtain bounding volumes of complex objects, a common way is to break the objects/scene down using a <a title="Scene graph" href="http://en.wikipedia.org/wiki/Scene_graph"><font color=#002bb8>scene graph</font></a> or more specifically <a class=mw-redirect title="Bounding volume hierarchies" href="http://en.wikipedia.org/wiki/Bounding_volume_hierarchies"><font color=#002bb8>bounding volume hierarchies</font></a> like e.g. <a class=new title="OBB tree (page does not exist)" href="http://en.wikipedia.org/w/index.php?title=OBB_tree&amp;action=edit&amp;redlink=1"><font color=#ba0000>OBB trees</font></a>. The basic idea behind this is to organize a scene in a tree-like structure where the root comprises the whole scene and each leaf contains a smaller subpart.</p>
<p><a id=Common_types_of_bounding_volume name=Common_types_of_bounding_volume></a></p>
<h2><span class=editsection>[<a title="Edit section: Common types of bounding volume" href="http://en.wikipedia.org/w/index.php?title=Bounding_volume&amp;action=edit&amp;section=2"><font color=#002bb8>edit</font></a>]</span> <span class=mw-headline>Common types of bounding volume</span></h2>
<p>The choice of the type of bounding volume for a given application is determined by a variety of factors: the computational cost of computing a bounding volume for an object, the cost of updating it in applications in which the objects can move or change shape or size, the cost of determining intersections, and the desired precision of the intesection test. It is common to use several types in conjunction, such as a cheap one for a quick but rough test in conjunction with a more precise but also more expensive type.</p>
<p>The types treated here all give <a title="Convex set" href="http://en.wikipedia.org/wiki/Convex_set"><font color=#002bb8>convex</font></a> bounding volumes. If the object being bounded is known to be convex, this is not a restriction. If non-convex bounding volumes are required, an approach is to represent them as a union of a number of convex bounding volumes. Unfortunately, intersection tests become quickly more expensive as the bounding boxes become more sophisticated.</p>
<p>A <strong><a title="Bounding sphere" href="http://en.wikipedia.org/wiki/Bounding_sphere"><font color=#002bb8>bounding sphere</font></a></strong> is a <a title=Sphere href="http://en.wikipedia.org/wiki/Sphere"><font color=#002bb8>sphere</font></a> containing the object. In 2-D graphics, this is a <a title=Circle href="http://en.wikipedia.org/wiki/Circle"><font color=#002bb8>circle</font></a>. Bounding spheres are represented by centre and radius. They are very quick to test for collision with each other: two spheres intersect when the distance between their centres does not exceed the sum of their radii. This makes bounding spheres appropriate for objects that can move in any number of dimensions.</p>
<p>A <strong>bounding ellipsoid</strong> is an <a title=Ellipsoid href="http://en.wikipedia.org/wiki/Ellipsoid"><font color=#002bb8>ellipsoid</font></a> containing the object. Ellipsoids usually provide tighter fitting than a sphere. Intersections with ellipsoids are done by scaling the other object along the <a class=mw-redirect title="Principal axes" href="http://en.wikipedia.org/wiki/Principal_axes"><font color=#002bb8>principal axes</font></a> of the ellipsoid by an amount equal to the <a title="Multiplicative inverse" href="http://en.wikipedia.org/wiki/Multiplicative_inverse"><font color=#002bb8>multiplicative inverse</font></a> of the radii of the ellipsoid, thus reducing the problem to intersecting the scaled object with a <a title="Unit sphere" href="http://en.wikipedia.org/wiki/Unit_sphere"><font color=#002bb8>unit sphere</font></a>. Care should be taken to avoid problems if the applied scaling introduces <a title=Skew href="http://en.wikipedia.org/wiki/Skew"><font color=#002bb8>skew</font></a>. Skew can make the usage of ellipsoids impractical in certain cases, for example collision between two arbitrary ellipsoids.</p>
<p>A <strong>bounding cylinder</strong> is a <a title="Cylinder (geometry)" href="http://en.wikipedia.org/wiki/Cylinder_(geometry)"><font color=#002bb8>cylinder</font></a> containing the object. In most applications the axis of the cylinder is aligned with the vertical direction of the scene. Cylinders are appropriate for 3-D objects that can only rotate about a vertical axis but not about other axes, and are otherwise constrained to move by translation only. Two vertical-axis-aligned cylinders intersect when, simultaneously, their projections on the vertical axis intersect &#8211; which are two line segments &#8211; as well their projections on the horizontal plane &#8211; two circular disks. Both are easy to test. In <a title="Video game" href="http://en.wikipedia.org/wiki/Video_game"><font color=#002bb8>video games</font></a>, bounding cylinders are often used as bounding volumes for people standing upright.</p>
<p>A <strong>bounding capsule</strong> is a <a class=new title="Swept sphere (page does not exist)" href="http://en.wikipedia.org/w/index.php?title=Swept_sphere&amp;action=edit&amp;redlink=1"><font color=#ba0000>swept sphere</font></a> (i.e. the volume that a sphere takes as it moves along a straight line segment) containing the object. Capsules can be represented by the radius of the swept sphere and the segment that the sphere is swept across). It has traits similar to a cylinder, but is easier to use, because the intersection test is simpler. A capsule and another object intersect if the distance between the capsule's defining segment and some feature of the other object is smaller than the capsule's radius. For example, two capsules intersect if the distance between the capsules' segments is smaller than the sum of their radii. This holds for arbitrarily rotated capsules, which is why they're more appealing than cylinders in practice.</p>
<p>A <strong>bounding box</strong> is a <a title=Cuboid href="http://en.wikipedia.org/wiki/Cuboid"><font color=#002bb8>cuboid</font></a>, or in 2-D a <a title=Rectangle href="http://en.wikipedia.org/wiki/Rectangle"><font color=#002bb8>rectangle</font></a>, containing the object. In <a title="Dynamical simulation" href="http://en.wikipedia.org/wiki/Dynamical_simulation"><font color=#002bb8>dynamical simulation</font></a>, bounding boxes are preferred to other shapes of bounding volume such as <a title="Bounding sphere" href="http://en.wikipedia.org/wiki/Bounding_sphere"><font color=#002bb8>bounding spheres</font></a> or <a class=mw-redirect title="Bounding cylinder" href="http://en.wikipedia.org/wiki/Bounding_cylinder"><font color=#002bb8>cylinders</font></a> for objects that are roughly cuboid in shape when the intersection test needs to be fairly accurate. The benefit is obvious, for example, for objects that rest upon other, such as a car resting on the ground: a bounding sphere would show the car as possibly intersecting with the ground, which then would need to be rejected by a more expensive test of the actual model of the car; a bounding box immediately shows the car as not intersecting with the ground, saving the more expensive test.</p>
<p>In many applications the bounding box is aligned with the axes of the co-ordinate system, and it is then known as an <strong>axis-aligned bounding box</strong> (<strong>AABB</strong>). To distinguish the general case from an AABB, an arbitrary bounding box is sometimes called an <strong>oriented bounding box</strong> (<strong>OBB</strong>). AABBs are much simpler to test for intersection than OBBs, but have the disadvantage that when the model is rotated they cannot be simply rotated with it, but need to be recomputed.</p>
<p>A <strong><a title="Minimum bounding rectangle" href="http://en.wikipedia.org/wiki/Minimum_bounding_rectangle"><font color=#002bb8>minimum bounding rectangle</font></a></strong> or <strong>MBR</strong> &#8211; the least AABB in 2-D &#8211; is frequently used in the description of geographic (or "geospatial") data items, serving as a simplified proxy for a dataset's spatial extent (see <a title="Geospatial metadata" href="http://en.wikipedia.org/wiki/Geospatial_metadata"><font color=#002bb8>geospatial metadata</font></a>) for the purpose of data search (including spatial queries as applicable) and display. It is also a basic component of the <a title=R-tree href="http://en.wikipedia.org/wiki/R-tree"><font color=#002bb8>R-tree</font></a> method of <a title="Spatial index" href="http://en.wikipedia.org/wiki/Spatial_index"><font color=#002bb8>spatial indexing</font></a>.</p>
<p>A <strong>discrete oriented polytope</strong> (<strong>DOP</strong>) generalizes the AABB. A DOP is a convex <a title=Polytope href="http://en.wikipedia.org/wiki/Polytope"><font color=#002bb8>polytope</font></a> containing the object (in 2-D a <a title=Polygon href="http://en.wikipedia.org/wiki/Polygon"><font color=#002bb8>polygon</font></a>; in 3-D a <a title=Polyhedron href="http://en.wikipedia.org/wiki/Polyhedron"><font color=#002bb8>polyhedron</font></a>), constructed by taking a number of suitably oriented planes at infinity and moving them until they collide with the object. The DOP is then the convex polytope resulting from intersection of the half-spaces bounded by the planes. Popular choices for constructing DOPs in 3-D graphics include the <strong>axis-aligned bounding box</strong>, made from 6 axis-aligned planes, and the <strong>beveled bounding box</strong>, made from 10 (if beveled only on vertical edges, say) 18 (if beveled on all edges), or 26 planes (if beveled on all edges and corners). A DOP constructed from <em>k</em> planes is called a <em>k</em>-DOP; the actual number of faces can be less than <em>k</em>, since some can become degenerate, shrunk to an edge or a vertex.</p>
<p>A <strong><a title="Convex hull" href="http://en.wikipedia.org/wiki/Convex_hull"><font color=#002bb8>convex hull</font></a></strong> is the smallest convex volume containing the object. If the object is the union of a finite set of points, its convex hull is a polytope, and in fact the smallest possible containing polytope.</p>
<p><a id=Basic_intersection_checks name=Basic_intersection_checks></a></p>
<h2><span class=editsection>[<a title="Edit section: Basic intersection checks" href="http://en.wikipedia.org/w/index.php?title=Bounding_volume&amp;action=edit&amp;section=3"><font color=#002bb8>edit</font></a>]</span> <span class=mw-headline>Basic intersection checks</span></h2>
<p>For some types of bounding volume (OBB and convex polyhedra), an effective check is that of the <a title="Separating axis theorem" href="http://en.wikipedia.org/wiki/Separating_axis_theorem"><font color=#002bb8>separating axis theorem</font></a>. The idea here is that, if there exists an axis by which the objects do not overlap, then the objects do not intersect. Usually the axes checked are those of the basic axes for the volumes (the unit axes in the case of an AABB, or the 3 base axes from each OBB in the case of OBBs). Often, this is followed by also checking the cross-products of the previous axes (one axis from each object).</p>
<p>In the case of an AABB, this tests becomes a simple set of overlap tests in terms of the unit axes. For an AABB defined by M,N against one defined by O,P they do not intersect if (M<sub>x</sub>&gt;P<sub>x</sub>) or (O<sub>x</sub>&gt;N<sub>x</sub>) or (M<sub>y</sub>&gt;P<sub>y</sub>) or (O<sub>y</sub>&gt;N<sub>y</sub>) or (M<sub>z</sub>&gt;P<sub>z</sub>) or (O<sub>z</sub>&gt;N<sub>z</sub>).</p>
<p>An AABB can also be projected along an axis, for example, if it has edges of length L and is centered at C, and is being projected along the axis N:<br><span class=tex style="DISPLAY: inline-block; FONT-SIZE: 0px; BORDER-LEFT-COLOR: black; BACKGROUND-IMAGE: none; BORDER-BOTTOM-COLOR: black; VERTICAL-ALIGN: middle; BORDER-TOP-COLOR: black; BORDER-RIGHT-COLOR: black"><span style="DISPLAY: inline-block; FILTER: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='http://upload.wikimedia.org/math/0/1/1/011ba89e226c4bc19d257f27bbbd30c5.png'); WIDTH: 1px; HEIGHT: 1px"></span></span>, and <span class=tex style="DISPLAY: inline-block; FONT-SIZE: 0px; BORDER-LEFT-COLOR: black; BACKGROUND-IMAGE: none; BORDER-BOTTOM-COLOR: black; VERTICAL-ALIGN: middle; BORDER-TOP-COLOR: black; BORDER-RIGHT-COLOR: black"><span style="DISPLAY: inline-block; FILTER: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='http://upload.wikimedia.org/math/f/6/a/f6a7494af4f6939a4925d52659815535.png'); WIDTH: 1px; HEIGHT: 1px"></span></span>or <span class=tex style="DISPLAY: inline-block; FONT-SIZE: 0px; BORDER-LEFT-COLOR: black; BACKGROUND-IMAGE: none; BORDER-BOTTOM-COLOR: black; VERTICAL-ALIGN: middle; BORDER-TOP-COLOR: black; BORDER-RIGHT-COLOR: black"><span style="DISPLAY: inline-block; FILTER: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='http://upload.wikimedia.org/math/f/5/9/f597c57fe530d659b2e70c68c6ec361c.png'); WIDTH: 1px; HEIGHT: 1px"></span></span>, and <span class=tex style="DISPLAY: inline-block; FONT-SIZE: 0px; BORDER-LEFT-COLOR: black; BACKGROUND-IMAGE: none; BORDER-BOTTOM-COLOR: black; VERTICAL-ALIGN: middle; BORDER-TOP-COLOR: black; BORDER-RIGHT-COLOR: black"><span style="DISPLAY: inline-block; FILTER: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='http://upload.wikimedia.org/math/3/4/a/34ae9d4eca3d9f1b692c28e798b76f5d.png'); WIDTH: 1px; HEIGHT: 1px"></span></span>where m and n are the minimum and maximum extents.</p>
<p>An OBB is similar in this respect, but is slightly more complicated. For an OBB with L and C as above, and with I, J, and K as the OBB's base axes, then:<br><span class=tex style="DISPLAY: inline-block; FONT-SIZE: 0px; BORDER-LEFT-COLOR: black; BACKGROUND-IMAGE: none; BORDER-BOTTOM-COLOR: black; VERTICAL-ALIGN: middle; BORDER-TOP-COLOR: black; BORDER-RIGHT-COLOR: black"><span style="DISPLAY: inline-block; FILTER: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='http://upload.wikimedia.org/math/a/c/6/ac6b5d1f1feb338fdb1c0811db88aa69.png'); WIDTH: 1px; HEIGHT: 1px"></span></span></p>
<p><span class=tex style="DISPLAY: inline-block; FONT