| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895 |
- <html xmlns:MSHelp="http://msdn.microsoft.com/mshelp" xmlns:msxsl="urn:schemas-microsoft-com:xslt" xmlns:xanx="http://schemas.microsoft.com/developer/xanx/2005"><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /><meta name="save" content="history" /><title>Picking with Triangle Accuracy Sample</title>
- <style><!--
- /***********************************************************
- * SCRIPT-SUPPORTING STYLES
- ***********************************************************/
- /* Defines the userData cache persistence mechanism. */
- .userDataStyle
- {
- behavior: url(#default#userData);
- }
- /* Used to save the scroll bar position when navigating away from a page. */
- div.saveHistory
- {
- behavior: url(#default#saveHistory);
- }
- /* Formats the expand/collapse images for all collapsible regions. */
- img.toggle
- {
- border: 0;
- margin-right: 5;
- }
- /* Formats the Language filter drop-down image. */
- img#languageFilterImage
- {
- border: 0;
- margin-left: 0;
- vertical-align: middle;
- }
- /* Formats the Members Options filter drop-down image. */
- img#membersOptionsFilterImage
- {
- border: 0;
- margin-left: 0;
- vertical-align: middle;
- }
- /* Formats the Collapse All/Expand All images. */
- img#toggleAllImage
- {
- margin-left: 0;
- vertical-align: middle;
- }
- /* Supports XLinks */
- MSHelp\:link
- {
- text-decoration: underline;
- color: #0000ff;
- hoverColor: #3366ff;
- filterString: ;
- }
- body
- {
- background: #FFFFFF;
- color: #000000;
- font-family: Verdana;
- font-size: medium;
- font-style: normal;
- font-weight: normal;
- margin-top: 0;
- margin-bottom: 0;
- margin-left: 0;
- margin-right: 0;
- width: 100%;
- /*font-size: 110%;*/
- }
- div.section
- {
- margin-left: 15px;
- }
- div.hxnx5
- {
- margin-left: 1.5em;
- }
- /* Font for all headings */
- h1, h2, h3, h4, h5, h6
- {
- font-family: Verdana, Arial, Helvetica, sans-serif;
- margin-top: 18;
- margin-bottom: 8;
- font-weight: bold;
- }
- h1
- {
- font-size: 130%;
- color: #003399;
- }
- div#scrollyes h1 /* Changes font size for full-scrolling topic */
- {
- font-size: 150%;
- }
- h2
- {
- font-size: 122%;
- }
- h3
- {
- font-size: 115%;
- margin-top: 9;
- margin-bottom: 4;
- }
- h4
- {
- font-size: 115%;
- margin-top: 9;
- margin-bottom: 4;
- }
- h5
- {
- font-size: 100%;
- margin-top: 9;
- margin-bottom: 4;
- }
- h6
- {
- font-size: 100%;
- margin-top: 9;
- margin-bottom: 4;
- }
- ul p, ol p, dl p
- {
- margin-left: 0em;
- }
- p
- {
- margin-top: .6em;
- margin-bottom: .6em;
- }
-
- td p
- {
- margin-top: 0.0em;
- margin-bottom: 0.6em;
- }
- dd p
- {
- margin-top: 0.0em;
- margin-bottom: 0.6em;
- }
- .image
- {
- text-align: center;
- }
- dl
- {
- margin-top: 0em;
- margin-bottom: 1.3em;
- }
- dd
- {
- margin-bottom: 0em;
- margin-left: 1.5em;
- }
- dl.glossary dd
- {
- margin-bottom: 0em;
- margin-left: 1.5em;
- }
- dt
- {
- margin-top: .6em;
- margin-bottom: 1;
- }
- ul, ol
- {
- margin-top: 0.6em;
- margin-bottom: 0.6em;
- }
-
- ol
- {
- margin-left: 2.5em;
- }
-
- ul
- {
- list-style-type: disc;
- margin-left: 1.9em;
- }
- li
- {
- margin-bottom: 0.4em;
- }
- ul ol, ol ol
- {
- list-style-type: lower-alpha;
- }
- pre
- {
- margin-top: .6em;
- margin-bottom: .6em;
- font: 105% Lucida, mono;
- color: #000066;
- }
- code
- {
- font-family: Monospace, Courier New, Courier;
- font-size: 105%;
- color: #000066;
- }
- table.userdata td
- {
- background: #ffffff;
- background-color: #F5F5F5;
- border-color: #ffffff;
- border: none;
- }
- table.clsWarning
- {
- background: #ffffff;
- padding: 0px;
- margin: 0px;
- border: none;
- }
- table.clsWarning td
- {
- padding: 0px;
- margin: 0px;
- background: #ffffff;
- vertical-align: middle;
- font-size: 70%;
- }
- div#mainSection table
- {
- width: 95%;
- background: #ffffff;
- margin-top: 5px;
- margin-bottom: 5px;
- }
- div#mainSection table th
- {
- padding: 5px 6px;
- background: #EFEFF7;
- text-align: left;
- font-size: 70%;
- vertical-align: bottom;
- border-bottom: 1px solid #C8CDDE;
- }
- div#mainSection table td
- {
- padding: 5px 5px;
- background: #F7F7FF;
- vertical-align: top;
- font-size: 70%;
- border-bottom: 1px solid #D5D5D3;
- }
- div#syntaxCodeBlocks table th
- {
- padding: 1px 6px;
- color: #000066;
- }
- div#syntaxCodeBlocks table td
- {
- padding: 1px 5px;
- }
- /* Applies to the running header text in the first row of the upper table in the
- non-scrolling header region. */
- span#runningHeaderText
- {
- color: #003399;
- font-size: 90%;
- padding-left: 13;
- }
- /* Applies to the topic title in the second row of the upper table in the
- non-scrolling header region. */
- span#nsrTitle
- {
- color: #003399;
- font-size: 120%;
- font-weight: 600;
- padding-left: 13;
- }
- /* Applies to everything below the non-scrolling header region. */
- div#mainSection
- {
- font-size: 70%;
- width: 100%;
- }
- /* Applies to everything below the non-scrolling header region, minus the footer. */
- div#mainBody
- {
- font-size: 90%;
- margin-left: 15;
- margin-top: 10;
- padding-bottom: 20;
- }
- /* Adds right padding for all blocks in mainBody */
- div#mainBody p, div#mainBody ol, div#mainBody ul, div#mainBody dl
- {
- padding-right: 5;
- }
- div#mainBody div.alert, div#mainBody div.code, div#mainBody div.tableSection
- {
- width:98.9%;
- }
- div.alert p, div.code p
- {
- margin-top:5;
- margin-bottom:8;
- }
- /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Begin Note Styles - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
- div#mainSection div.alert table
- {
- border: 0;
- }
- div#mainSection div.alert table th
- {
- padding-top: 0;
- padding-bottom: 0;
- padding-left: 5;
- padding-right: 5;
- }
- div#mainSection div.alert table td
- {
- padding-left: 5;
- padding-right: 5;
- }
- img.note
- {
- border: 0;
- margin-left: 0;
- margin-right: 3;
- }
- /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - End Note Styles - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
- /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Begin Non-scrolling Header Region Styles - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
- /* Applies to the entire non-scrolling header region. */
- div#header
- {
- background-color: #D4DFFF;
- padding-top: 0;
- padding-bottom: 0;
- padding-left: 0;
- padding-right: 0;
- width: 100%;
- }
- /* Applies to both tables in the non-scrolling header region. */
- div#header table
- {
- margin-top: 0;
- margin-bottom: 0;
- border-bottom-color: #C8CDDE;
- border-bottom-style: solid;
- border-bottom-width: 1;
- background: #D4DFFF;
- width: 100%;
- }
- /* Applies to cells in both tables in the non-scrolling header region. */
- div#header table td
- {
- color: #0000FF;
- font-size: 70%;
- padding-right: 20;
- padding-top: 1;
- padding-bottom: 1;
- border: none;
- background: #D4DFFF;
- }
- /* Applies to the last row in the upper table of the non-scrolling header region. Text
- in this row includes See Also, Constructors, Methods, and Properties. */
- div#header table tr#headerTableRow3 td
- {
- padding-bottom: 2;
- padding-top: 5;
- padding-left: 15;
- }
- /* Applies to the lower table in the non-scrolling header region. Text in this table
- includes Collapse All/Expand All, Language Filter, and Members Options. */
- div#header table#bottomTable
- {
- border-top-color: #FFFFFF;
- border-top-style: solid;
- border-top-width: 1;
- text-align: left;
- padding-left: 15;
- }
- blockquote
- {
- margin-left: 3.8em;
- margin-right: 3.8em;
- margin-top: .6em;
- margin-bottom: .6em;
- }
- sup
- {
- text-decoration: none;
- font-size: smaller;
- }
- a:link
- {
- color: #0000FF;
- /* font-weight: bold */
- }
-
- a:visited
- {
- color: #0000AA;
- /* font-weight: bold */
- }
-
- a:hover
- {
- color: #3366FF;
- /* font-weight: bold */
- }
-
- .label
- {
- font-weight: bold;
- margin-top: 1em;
- margin-left: -26px;
- }
-
- .tl
- {
- margin-bottom: .75em;
- }
-
- .atl
- {
- padding-left: 1.5em;
- padding-bottom: .75em;
- }
-
- .cfe
- {
- font-weight: bold;
- }
-
- .mini
- {
- font-size: smaller;
- }
-
- .dt
- {
- margin-bottom: -.6em;
- }
-
- .indent
- {
- margin-left: 1.9em;
- margin-right: 1.9em;
- }
- .product
- {
- text-align: right;
- color: #333333;
- font-size: smaller;
- font-style: italic;
- }
- .buttonbarshade
- {
- position: relative;
- margin: 0;
- left: 0px;
- top: 2;
- width: 50%;
- height: 40px;
- }
- .buttonbartable
- {
- position: absolute;
- margin: 0;
- padding:0;
- border:0;
- left:0px;
- top: 2;
- width: 100%;
- height: 40px;
- }
- /* background color, font for header */
- table.buttonbartable td, table.buttonbarshade td
- {
- background: #ffffff; /*#5177B8; #80C615;*/
- border-left: 0px solid #80C615;
- margin: 0;
- padding: 0px 0px 0px 0px;
- font-family: Impact, sans-serif;
- font-size: 14pt;
- }
- table.buttonbartable td.button1
- {
- background: #5177B8; /*#80C615;*/;
- padding: 0;
- font-weight: bold;
- text-align: center;
- cursor: hand;
- }
- table.buttonbartable td.button2
- {
- background: #5177B8; /*#80C615;*/;
- font-weight: bold;
- text-align: center;
- }
- table.buttonbartable td.button3
- {
- background: #5177B8; /*#80C615;*/;
- font-weight: bold;
- text-align: center;
- }
- table.buttonbartable td.runninghead
- {
- padding-left: 0px;
- font-style: italic;
- text-align: left;
- }
- .version
- {
- text-align: left;
- color: #000000;
- margin-top: 3em;
- margin-left: -26px;
- font-size: smaller;
- font-style: italic;
- }
- .lang, .ilang
- {
- color: #0000ff;
- font: normal 7pt Arial, Helvetica, sans-serif;
- }
- div.langMenu
- {
- position: absolute;
- z-index: 1;
- width: 96pt;
- padding: 8pt;
- visibility: hidden;
- border: 1px solid #000000;
- background: #ffffd0;
- }
- div.langMenu ul
- {
- padding-left: 2em;
- margin-left: 0;
- }
- div.filtered
- {
- margin: 4pt 0 8pt -26px;
- padding: 4px 4px 8px 26px;
- width: 100%;
- border: 2px solid #aaaacc;
- background: #ffffff;
- }
- div.filtered2
- {
- margin: 4pt 0 8pt -26px;
- padding: 4px 4px 8px 26px;
- width: 100%;
- border: none;
- background: #ffffff;
- }
- div.filtered h1, div.filtered h2, div.filtered h3, div.filtered h4
- {
- margin-left: -22px;
- }
- div.filtered span.lang
- {
- position: relative;
- left: -22px;
- }
- div.reftip
- {
- position: absolute;
- z-index: 1;
- padding: 8pt;
- visibility: hidden;
- border: 1px solid #000000;
- background: #ffffd0;
- }
- a.synParam
- {
- color: #0000FF;
- /*color: #3F7800;*/
- /*color: #8DC54F;*/
- text-decoration: none;
- font-weight: normal;
- }
- a.synParam:hover
- {
- text-decoration: underline;
- font-weight: normal;
- }
- div.sapop
- {
- position: absolute;
- z-index: 1;
- left: 26px;
- width: 100%;
- padding: 10px 10px 10px 36px;
- visibility: hidden;
- border: 1px solid #000000;
- background: #ffffd0;
- }
- div.footer
- {
- width: 100%;
- border: none;
- background: #ffffff;
- margin-top: 18pt;
- padding-bottom: 12pt;
- color: #0000FF;
- /*color: #228B22; */
- text-align: center;
- font-size: 76%;
- }
- div.preliminary
- {
- margin-top: 8pt;
- padding-bottom: 12pt;
- color: #A0A0A0;
- }
- /* A procedure section. eg. 'To create a file', 'To add a value' */
- div.proc
- {
- margin-left: 0.5em;
- }
-
- /* The title of a 'procedure' section. */
- div.proc h3
- {
- font-family: Verdana, Arial, Helvetica, sans-serif;
- font-weight: bold;
- font-size: 115%;
- margin-top: 1em;
- margin-bottom: 0.4em;
- margin-left: -0.5em;
- color: #003399;
- }
- div.proc ul
- {
- margin-left: 1.5em;
- }
- div.proc ol
- {
- margin-left: 2.0em;
- }
-
- .note
- {
- margin-left: 14pt;
- margin-right: 12pt;
- }
- .indent1
- {
- margin-left: 12pt;
- }
- .indent2
- {
- margin-left: 24pt;
- }
- .indent3
- {
- margin-left: 36pt;
- }
- p.proch
- {
- padding-left: 16px;
- }
- p.proch img
- {
- position: relative;
- vertical-align: top;
- left: -18px;
- margin-right: -14px;
- margin-bottom: -18px;
- }
-
- div.clsPlatSpec
- {
- background-color:#FFF8DC;
- border-style:solid;
- border-width:1pt 0pt 0pt 1pt;
- border-color:#ffE4C4;
- margin-top:0.6em;
- width:100%;
- }
- /* Applies to the language labels in the Language Filter drop-down list. */
- .languageFilter
- {
- color: #0000FF;
- cursor:hand;
- text-decoration:underline;
- padding-bottom:4;
- }
- /* Dropdown areas */
- #languageSpan {
- position: absolute;
- visibility: hidden;
- border-style: solid;
- border-width: 1px;
- border-color: #C8CDDE;
- background: #d4dfff;
- padding: 4px;
- font-size: 70%;
- }
- #membersOptionsSpan {
- position: absolute;
- visibility: hidden;
- border-style: solid;
- border-width: 1px;
- border-color: #C8CDDE;
- background: #d4dfff;
- padding: 4px;
- font-size: 70%;
- }
- --></style>
- <xml>
- <MSHelp:TOCTitle Title="Picking with Triangle Accuracy Sample" />
- <MSHelp:RLTitle Title="Picking with Triangle Accuracy Sample" />
- <MSHelp:Keyword Index="A" Term="O:Microsoft.Xna.TrianglePicking" />
- <MSHelp:Keyword Index="A" Term="0a66c38e-f49c-90cc-f149-eefa1d5dbd59" />
- <MSHelp:Keyword Index="K" Term="Picking with Triangle Accuracy Sample" />
- <MSHelp:Attr Name="AssetID" Value="0a66c38e-f49c-90cc-f149-eefa1d5dbd59" />
- <MSHelp:Attr Name="Locale" Value="en-us" />
- <MSHelp:Attr Name="CommunityContent" Value="1" />
- <MSHelp:Attr Name="TopicType" Value="kbOrient" />
- </xml>
- </head><body><div id="mainSection"><div id="mainBody">
- <h1>Picking with Triangle Accuracy Sample</h1>
-
- This sample shows you how to access vertex position data from a model.
- It then uses that information to implement a per-triangle picking test.
-
- <a id="ID2EJ" name="ID2EJ"> </a><h1 class="heading">Sample Overview</h1><div id="ID2EJ" class="hxnx1">
-
- <p>This sample builds on the ideas presented in the Picking sample. If you are unfamiliar with the process of converting between world space and screen space and checking for intersection between rays and bounding primitives, you should start with the Picking sample, which explains these basic concepts.</p>
- <p>This sample extends the approximate bounding box tests from the Picking sample to perform an accurate per-triangle picking test. It loops over all the triangles in the model and performs a ray-to-triangle intersection test for each one. It uses a custom content processor to extract the model vertex position data into a format that can be easily accessed at run time.</p>
- <a id="ID2ER" name="ID2ER"> </a><h2 class="subHeading">Sample Controls</h2><div id="ID2ER" class="hxnx2">
-
- <p>This sample uses the following keyboard and gamepad controls.</p>
- <table>
- <tr>
- <th>Action</th>
- <th>Keyboard control</th>
- <th>Gamepad control</th>
- </tr>
- <tr>
- <td>Move the cursor</td>
- <td>N/A</td>
- <td>Left thumbstick</td>
- </tr>
- <tr>
- <td>Move the camera</td>
- <td>
- <p>UP ARROW, DOWN ARROW, LEFT ARROW, RIGHT ARROW or W, A, S, D</p>
- </td>
- <td>Right thumbstick</td>
- </tr>
- <tr>
- <td>Zoom in and out</td>
- <td>Z, X</td>
- <td>Left and right triggers</td>
- </tr>
- <tr>
- <td>Reset the camera</td>
- <td>R</td>
- <td>Click the right thumbstick</td>
- </tr>
- <tr>
- <td>Exit</td>
- <td>ESC or ALT+F4</td>
- <td>BACK</td>
- </tr>
- </table>
- <p>On Windows, you can also use the mouse to move the cursor.</p>
- </div>
- </div>
- <a id="ID2ECD" name="ID2ECD"> </a><h1 class="heading">How the Sample Works</h1><div id="ID2ECD" class="hxnx1">
-
- <p>
- The TrianglePickingPipeline project implements a custom content processor called <code>TrianglePickingProcessor</code>. This derives from the built-in <b>ModelProcessor</b> class, and overrides the <b>Process</b> method. It uses the recursive <b>FindVertices</b> method to scan over the tree of input geometry, storing all the vertex positions into a list (three entries per triangle). It then chains to the base class <b>ModelProcessor.Process</b> method to convert the input <b>NodeContent</b> object into a <b>ModelContent</b> instance, and attaches the list of vertex positions to the Tag property of the output <b>ModelContent</b>.
- </p>
- <p>
- To make use of this custom processor, the TrianglePickingPipeline assembly is added as a reference to the content project, as described in <a href="http://msdn2.microsoft.com/library/bb447743.aspx">Using a Custom Importer or Content Processor</a>. In the properties for each model asset, you can now set the <b>Content Processor</b> field to TrianglePickingProcessor. If you forget to do this when adding a new model, you will get an exception when trying to pick against that model because the Tag property will not contain the neccessary vertex position data.
- </p>
- <p>
- The <code>RayIntersectsModel</code> method in Game.cs implements the picking. The implementation transforms the input ray by the inverse of the model transform matrix. This action is neccessary because the input ray is in world space, but our model data is stored in object space. Normally, you would have to transform all the model data by the model transform matrix. This moves it into world space before testing it against the ray. However, that transform can be slow if there are a lot of triangles in the model. Therefore, you should do the opposite. Transforming the ray by the inverse model transform moves it into object space. In object space, you can test it directly against your model data. Since there is only one ray, but typically many triangles, this approach can be much faster.
- </p>
- <p>
- To keep things efficient, the <code>RayIntersectsModel</code> method starts by applying a bounding sphere test. This means it tests each triangle only if the ray intersects the bounding sphere. This enables you to trivially reject many models without even looking at their triangle data. The sample displays a list—in the upper left corner of the screen—of all the models that passed this bounding sphere test. If you move the cursor near a model, you will notice that sometimes the approximate bounding sphere test passes even when the more accurate triangle test does not find any intersection. But when the cursor is far away, this bounding test can quickly reject any need to examine the model more carefully.
- </p>
- <p>
- If the bounding sphere test passes, <code>RayIntersectsModel</code> then goes into a loop, calling the <code>RayIntersectsTriangle</code> method once for every triangle in the model. It keeps track of the closest triangle yet discovered so it can always return the closest match if the ray intersects more than one triangle.
- </p>
- </div>
- <a id="ID2EXE" name="ID2EXE"> </a><h1 class="heading">Extending the Sample</h1><div id="ID2EXE" class="hxnx1">
-
- <p>
- This sample loops over all the triangles in a model, calling <code>RayIntersectsTriangle</code> once for each. If there are too many triangles, this can be slow. To perform fast collision detection against more detailed models, you could organize the collision triangles into some kind of hierarchical structure such as an octree. This enables the use of more efficient intersection algorithms.
- </p>
- <p>
- Sometimes you might use different versions of your geometry for collision and rendering. For example, you might want to display a high-detail mesh, but use an approximated version with fewer triangles for your collision tests. You could do this entirely in the content processor, without requiring any run-time code changes at all. You could change the <code>FindVertices</code> method to store only vertex positions from meshes labeled with "collision" in their names. Then you could remove these meshes from the input tree so they won't be picked up as part of the visible model. You could then create files containing two different versions of each mesh. One version would be for drawing, while the other would be a specially-labeled version for the collision system.
- </p>
- </div>
- </div><div class="footer" id="footer"><p>© 2010 Microsoft Corporation. All rights reserved.<br />Send feedback to <a href="mailto:[email protected]?subject=Documentation Feedback: Picking with Triangle Accuracy Sample">[email protected]</a>.</p></div></div></body></html>
|