Changes between Version 2 and Version 3 of Support/Tutorials/NPSTutorials/osgGeometery

Show
Ignore:
Timestamp:
08/23/07 22:39:39 (7 years ago)
Author:
osg (IP: 81.70.103.176)
Comment:

Redirect to wiki formatted tutorial

Legend:

Unmodified
Added
Removed
Modified
  • Support/Tutorials/NPSTutorials/osgGeometery

    v2 v3  
    1 {{{ 
    2 #!html 
    3 <table width="825" border="0" align="center" cellpadding="0" cellspacing="0" bgcolor="#333333"  ><!-- background="../Images/BorderBG.gif"--> 
    4   <!--DWLayoutTable--> 
    5   <tr> 
    6     <td width="3" rowspan="5" valign="top"><!--DWLayoutEmptyCell-->&nbsp;</td> 
    7     <td width="641" height="30" valign="top"><!--DWLayoutEmptyCell-->&nbsp;</td> 
    8     <td colspan="3" rowspan="2" valign="top"><!--DWLayoutEmptyCell-->&nbsp;</td> 
    9   <td width="3" rowspan="5" valign="top"><!--DWLayoutEmptyCell-->&nbsp;</td> 
    10   </tr> 
    11   <tr> 
    12     <td height="31"><div align="center"><span class="style4"><a href="http://www.openscenegraph.org/">OpenSceneGraph</a> Tutorials (<a href="index.htm">Index</a>) </span></div></td> 
    13   </tr> 
    14   <tr> 
    15     <td height="12" colspan="4" valign="middle"><div align="center" class="style2"></div></td> 
    16   </tr> 
    17   <tr> 
    18     <td height="44" colspan="4" valign="top"><!-- InstanceBeginEditable name="MainBody" --> 
    19     <table width="100%" border="0" cellpadding="0" cellspacing="0"> 
    20       <!--DWLayoutTable--> 
    21       <tr> 
    22         <td width="761" height="16"><div align="center"> 
    23           <p class="big" align="left"><span class="bodystyle"><strong>Working with Open Scene Graph Geometry</strong></span></p> 
    24         </div> 
    25           <div align="left"> 
    26             <p class="bodystyle">Overview:</p> 
    27           </div> 
    28           <blockquote> 
    29             <div class="bodystyle" align="left"> 
    30               <p>This section covers some of the methods that can be used to create geometric primitives. There are several ways to deal with geometry objects: at the lowest level loosly wraps OpenGL primitives; an intermediate level using open scene graph basic shapes and at a higher level, loaded from files. This tutorial covers the lowest level. This method provides the greatest flexibility and requies the most effort. Normally at the scene graph level geometry is loaded from files. Most of the effort of tracking vertices is handled by file loaders.</p> 
    31             </div> 
    32           </blockquote> 
    33           <div align="left"> 
    34             <p><span class="bodystyle">Background:</span></p> 
    35           </div> 
    36           <blockquote> 
    37             <p><span class="bodystyle">A brief explanation of the following classes is helpful:</span></p> 
    38             <p><span class="bodystyle"> The 'Geode' class:</span></p> 
    39             <blockquote> 
    40               <p><span class="bodystyle"> The geode class is derived from the 'node' class. Nodes (and thus geodes) can be added to a scene graph as leaf nodes. Geode instances can have any number of 'drawables' associated with them.</span></p> 
    41             </blockquote> 
    42             <p><span class="bodystyle">The 'Drawable' class hierarchy:</span></p> 
    43             <blockquote> 
    44               <p><span class="bodystyle">The base class 'drawable' is a pure virtual class with six concrete derived classes. (<a href="http://www.openscenegraph.org/documentation/OpenSceneGraphReferenceDocs/classosg_1_1Drawable.html">reference</a>)<br> 
    45                 The 'geometry' class can have vertex (and vertex data) associated with it directly, or can have any number of 'primitiveSet' instances associated with it.<br> 
    46       Vertex and vertex attribute data (color, normals, texture coordinates) is stored in arrays. Since more than one vertex may share the same color, normal or texture coordinate, and array of indices can be used to map vertex arrays to color, normal or texture coordinate arrays.</span></p> 
    47             </blockquote> 
    48             <p><span class="bodystyle">The 'PrimitiveSet' class:</span></p> 
    49             <blockquote> 
    50               <p><span class="bodystyle">This class loosely wraps the OpenGL drawing primitives - POINTS, LINES, LINE_STRIP, LINE_LOOP,... QUADS,... POLYGON.</span></p> 
    51             </blockquote> 
    52           </blockquote> 
    53           <div align="center"> 
    54             <p align="left"><span class="bodystyle">The code:</span></p> 
    55           </div> 
    56           <blockquote> 
    57             <div align="left"> 
    58               <p class="bodystyle">The following section of code sets up a viewer to see the scene we create, a 'group' instance to serve as the root of the scene graph, a geometry node (geode) to collect drawables, and a geometry instance to associate vertices and vertex data. (In this case the shape to render is a four-sided pyramid.)</p> 
    59               <pre class="codebox"><span class="operator">...</span><span class="type"> 
    60 int</span><span class="keyword"> main</span><span class="operator">() 
    61 { 
    62    ...</span> 
    63    osgProducer<span class="operator">::</span>Viewer viewer<span class="operator">;</span> 
    64    osg<span class="operator">::</span>Group<span class="operator">*</span> root<span class="operator"> =</span><span class="keyword"> new</span> osg<span class="operator">::</span>Group<span class="operator">();</span> 
    65    osg<span class="operator">::</span>Geode<span class="operator">*</span> pyramidGeode<span class="operator"> =</span><span class="keyword"> new</span> osg<span class="operator">::</span>Geode<span class="operator">();</span> 
    66    osg<span class="operator">::</span>Geometry<span class="operator">*</span> pyramidGeometry<span class="operator"> =</span><span class="keyword"> new</span> osg<span class="operator">::</span>Geometry<span class="operator">();</span></pre> 
    67  
    68               <p class="bodystyle">Next we need to associate the pyramid geometry with the pyramid geode and add the pyramid geode to the root node of the scene graph.</p> 
    69               <pre class="codebox">   pyramidGeode<span class="operator">-&gt;</span>addDrawable<span class="operator">(</span>pyramidGeometry<span class="operator">);</span>  
    70    root<span class="operator">-&gt;</span>addChild<span class="operator">(</span>pyramidGeode<span class="operator">);</span></pre> 
    71               <p class="bodystyle">Declare an array of vertices. Each vertex will be represented by a triple -- an instances of the vec3 class. An instance of osg::Vec3Array can be used to store these triples. Since osg::Vec3Array is derived from the STL vector class, we can use the push_back method to add array elements. Push back adds elements to the end of the vector, thus the index of first element entered is zero, the second entries index is 1, etc.<br> 
    72       Using a right-handed coordinate system with 'z' up, array elements zero..four below represent the 5 points required to create a simple pyramid. </p> 
    73               <pre class="codebox">   osg<span class="operator">::</span>Vec3Array<span class="operator">*</span> pyramidVertices<span class="operator"> =</span><span class="keyword"> new</span> osg<span class="operator">::</span>Vec3Array<span class="operator">;</span> 
    74    pyramidVertices<span class="operator">-&gt;</span>push_back<span class="operator">(</span> osg<span class="operator">::</span>Vec3<span class="operator">(</span><span class="int"> 0</span><span class="operator">,</span><span class="int"> 0</span><span class="operator">,</span><span class="int"> 0</span><span class="operator">) );</span><span class="comment"> // front left</span> 
    75    pyramidVertices<span class="operator">-&gt;</span>push_back<span class="operator">(</span> osg<span class="operator">::</span>Vec3<span class="operator">(</span><span class="int">10</span><span class="operator">,</span><span class="int"> 0</span><span class="operator">,</span><span class="int"> 0</span><span class="operator">) );</span><span class="comment"> // front right</span> 
    76    pyramidVertices<span class="operator">-&gt;</span>push_back<span class="operator">(</span> osg<span class="operator">::</span>Vec3<span class="operator">(</span><span class="int">10</span><span class="operator">,</span><span class="int">10</span><span class="operator">,</span><span class="int"> 0</span><span class="operator">) );</span><span class="comment"> // back right </span> 
    77    pyramidVertices<span class="operator">-&gt;</span>push_back<span class="operator">(</span> osg<span class="operator">::</span>Vec3<span class="operator">(</span><span class="int"> 0</span><span class="operator">,</span><span class="int">10</span><span class="operator">,</span><span class="int"> 0</span><span class="operator">) );</span><span class="comment"> // back left </span> 
    78    pyramidVertices<span class="operator">-&gt;</span>push_back<span class="operator">(</span> osg<span class="operator">::</span>Vec3<span class="operator">(</span><span class="int"> 5</span><span class="operator">,</span><span class="int"> 5</span><span class="operator">,</span><span class="int">10</span><span class="operator">) );</span><span class="comment"> // peak</span></pre> 
    79  
    80               <p class="bodystyle">Associate this set of vertices with the geometry associated with the geode we added to the scene.</p> 
    81               <pre class="codebox">   pyramidGeometry<span class="operator">-&gt;</span>setVertexArray<span class="operator">(</span> pyramidVertices<span class="operator"> );</span> </pre> 
    82  
    83               <p class="bodystyle">Next, create a primitive set and add it to the pyramid geometry. Use the first four points of the pyramid to define the base using an instance of the DrawElementsUint class. Again this class is derived from the STL vector, so the push_back method will add elements in sequential order. To ensure proper backface cullling, vertices should be specified in counterclockwise order. The arguments for the constructor are the enumerated type for the primitive (same as the OpenGL primitive enumerated types), and the index in the vertex array to start from.</p> 
    84               <pre class="codebox">   osg<span class="operator">::</span>DrawElementsUInt<span class="operator">*</span> pyramidBase<span class="operator"> =</span><span class="keyword">  
    85       new</span> osg<span class="operator">::</span>DrawElementsUInt<span class="operator">(</span>osg<span class="operator">::</span>PrimitiveSet<span class="operator">::</span>QUADS<span class="operator">,</span><span class="int"> 0</span><span class="operator">);</span> 
    86    pyramidBase<span class="operator">-&gt;</span>push_back<span class="operator">(</span><span class="int">3</span><span class="operator">);</span> 
    87    pyramidBase<span class="operator">-&gt;</span>push_back<span class="operator">(</span><span class="int">2</span><span class="operator">);</span> 
    88    pyramidBase<span class="operator">-&gt;</span>push_back<span class="operator">(</span><span class="int">1</span><span class="operator">);</span> 
    89    pyramidBase<span class="operator">-&gt;</span>push_back<span class="operator">(</span><span class="int">0</span><span class="operator">);</span> 
    90    pyramidGeometry<span class="operator">-&gt;</span>addPrimitiveSet<span class="operator">(</span>pyramidBase<span class="operator">);</span> </pre> 
    91  
    92               <p class="bodystyle">Repeat the same for each of the four sides. Again, vertices are specified in counter-clockwise order. </p> 
    93               <pre class="codebox">   osg<span class="operator">::</span>DrawElementsUInt<span class="operator">*</span> pyramidFaceOne<span class="operator"> =</span><span class="keyword">  
    94       new</span> osg<span class="operator">::</span>DrawElementsUInt<span class="operator">(</span>osg<span class="operator">::</span>PrimitiveSet<span class="operator">::</span>TRIANGLES<span class="operator">,</span><span class="int"> 0</span><span class="operator">);</span> 
    95    pyramidFaceOne<span class="operator">-&gt;</span>push_back<span class="operator">(</span><span class="int">0</span><span class="operator">);</span> 
    96    pyramidFaceOne<span class="operator">-&gt;</span>push_back<span class="operator">(</span><span class="int">1</span><span class="operator">);</span> 
    97    pyramidFaceOne<span class="operator">-&gt;</span>push_back<span class="operator">(</span><span class="int">4</span><span class="operator">);</span> 
    98    pyramidGeometry<span class="operator">-&gt;</span>addPrimitiveSet<span class="operator">(</span>pyramidFaceOne<span class="operator">);</span> 
    99  
    100    osg<span class="operator">::</span>DrawElementsUInt<span class="operator">*</span> pyramidFaceTwo<span class="operator"> =</span><span class="keyword">  
    101       new</span> osg<span class="operator">::</span>DrawElementsUInt<span class="operator">(</span>osg<span class="operator">::</span>PrimitiveSet<span class="operator">::</span>TRIANGLES<span class="operator">,</span><span class="int"> 0</span><span class="operator">);</span> 
    102    pyramidFaceTwo<span class="operator">-&gt;</span>push_back<span class="operator">(</span><span class="int">1</span><span class="operator">);</span> 
    103    pyramidFaceTwo<span class="operator">-&gt;</span>push_back<span class="operator">(</span><span class="int">2</span><span class="operator">);</span> 
    104    pyramidFaceTwo<span class="operator">-&gt;</span>push_back<span class="operator">(</span><span class="int">4</span><span class="operator">);</span> 
    105    pyramidGeometry<span class="operator">-&gt;</span>addPrimitiveSet<span class="operator">(</span>pyramidFaceTwo<span class="operator">);</span> 
    106  
    107    osg<span class="operator">::</span>DrawElementsUInt<span class="operator">*</span> pyramidFaceThree<span class="operator"> =</span><span class="keyword">  
    108       new</span> osg<span class="operator">::</span>DrawElementsUInt<span class="operator">(</span>osg<span class="operator">::</span>PrimitiveSet<span class="operator">::</span>TRIANGLES<span class="operator">,</span><span class="int"> 0</span><span class="operator">);</span> 
    109    pyramidFaceThree<span class="operator">-&gt;</span>push_back<span class="operator">(</span><span class="int">2</span><span class="operator">);</span> 
    110    pyramidFaceThree<span class="operator">-&gt;</span>push_back<span class="operator">(</span><span class="int">3</span><span class="operator">);</span> 
    111    pyramidFaceThree<span class="operator">-&gt;</span>push_back<span class="operator">(</span><span class="int">4</span><span class="operator">);</span> 
    112    pyramidGeometry<span class="operator">-&gt;</span>addPrimitiveSet<span class="operator">(</span>pyramidFaceThree<span class="operator">);</span> 
    113  
    114    osg<span class="operator">::</span>DrawElementsUInt<span class="operator">*</span> pyramidFaceFour<span class="operator"> =</span><span class="keyword">  
    115       new</span> osg<span class="operator">::</span>DrawElementsUInt<span class="operator">(</span>osg<span class="operator">::</span>PrimitiveSet<span class="operator">::</span>TRIANGLES<span class="operator">,</span><span class="int"> 0</span><span class="operator">);</span> 
    116    pyramidFaceFour<span class="operator">-&gt;</span>push_back<span class="operator">(</span><span class="int">3</span><span class="operator">);</span> 
    117    pyramidFaceFour<span class="operator">-&gt;</span>push_back<span class="operator">(</span><span class="int">0</span><span class="operator">);</span> 
    118    pyramidFaceFour<span class="operator">-&gt;</span>push_back<span class="operator">(</span><span class="int">4</span><span class="operator">);</span> 
    119    pyramidGeometry<span class="operator">-&gt;</span>addPrimitiveSet<span class="operator">(</span>pyramidFaceFour<span class="operator">)</span></pre> 
    120             </div> 
    121             <div class="bodystyle" align="left"> 
    122               <p>Declare and load an array of Vec4 elements to store colors. </p> 
    123               <pre class="codebox">   osg<span class="operator">::</span>Vec4Array<span class="operator">*</span> colors<span class="operator"> =</span><span class="keyword"> new</span> osg<span class="operator">::</span>Vec4Array<span class="operator">;</span> 
    124    colors<span class="operator">-&gt;</span>push_back<span class="operator">(</span>osg<span class="operator">::</span>Vec4<span class="operator">(</span><span class="float">1.0f</span><span class="operator">,</span><span class="float"> 0.0f</span><span class="operator">,</span><span class="float"> 0.0f</span><span class="operator">,</span><span class="float"> 1.0f</span><span class="operator">) );</span><span class="comment"> //index 0 red 
    125 </span>   colors<span class="operator">-&gt;</span>push_back<span class="operator">(</span>osg<span class="operator">::</span>Vec4<span class="operator">(</span><span class="float">0.0f</span><span class="operator">,</span><span class="float"> 1.0f</span><span class="operator">,</span><span class="float"> 0.0f</span><span class="operator">,</span><span class="float"> 1.0f</span><span class="operator">) );</span><span class="comment"> //index 1 green 
    126 </span>   colors<span class="operator">-&gt;</span>push_back<span class="operator">(</span>osg<span class="operator">::</span>Vec4<span class="operator">(</span><span class="float">0.0f</span><span class="operator">,</span><span class="float"> 0.0f</span><span class="operator">,</span><span class="float"> 1.0f</span><span class="operator">,</span><span class="float"> 1.0f</span><span class="operator">) );</span><span class="comment"> //index 2 blue 
    127 </span>   colors<span class="operator">-&gt;</span>push_back<span class="operator">(</span>osg<span class="operator">::</span>Vec4<span class="operator">(</span><span class="float">1.0f</span><span class="operator">,</span><span class="float"> 1.0f</span><span class="operator">,</span><span class="float"> 1.0f</span><span class="operator">,</span><span class="float"> 1.0f</span><span class="operator">) );</span><span class="comment"> //index 3 white </span></pre> 
    128  
    129               <p>Declare the variable that will match vertex array elements to color array elements. This vector should have the same number of elements as the number of vertices. This vector serves as a link between vertex arrays and color arrays. Entries in this index array correspond to elements in the vertex array. Their values correspond to the index in the color array. This same scheme would be followed if vertex array elements were matched with normal or texture coordinate arrays.<br> 
    130       Note that in this case, we are assigning 5 vertices to four colors. Vertex array element zero (bottom left) and four (peak) are both assigned to color array element zero (red).</p> 
    131               <pre class="codebox">   osg<span class="operator">::</span>TemplateIndexArray<span class="operator"> 
    132       &lt;</span><span class="type">unsigned int</span><span class="operator">,</span> osg<span class="operator">::</span>Array<span class="operator">::</span>UIntArrayType<span class="operator">,</span><span class="int">4</span><span class="operator">,</span><span class="int">4</span><span class="operator">&gt; *</span>colorIndexArray<span class="operator">;</span> 
    133    colorIndexArray<span class="operator"> =</span><span class="keyword">  
    134       new</span> osg<span class="operator">::</span>TemplateIndexArray<span class="operator">&lt;</span><span class="type">unsigned int</span><span class="operator">,</span> osg<span class="operator">::</span>Array<span class="operator">::</span>UIntArrayType<span class="operator">,</span><span class="int">4</span><span class="operator">,</span><span class="int">4</span><span class="operator">&gt;;</span> 
    135    colorIndexArray<span class="operator">-&gt;</span>push_back<span class="operator">(</span><span class="int">0</span><span class="operator">);</span><span class="comment"> // vertex 0 assigned color array element 0 
    136 </span>   colorIndexArray<span class="operator">-&gt;</span>push_back<span class="operator">(</span><span class="int">1</span><span class="operator">);</span><span class="comment"> // vertex 1 assigned color array element 1 
    137 </span>   colorIndexArray<span class="operator">-&gt;</span>push_back<span class="operator">(</span><span class="int">2</span><span class="operator">);</span><span class="comment"> // vertex 2 assigned color array element 2 
    138 </span>   colorIndexArray<span class="operator">-&gt;</span>push_back<span class="operator">(</span><span class="int">3</span><span class="operator">);</span><span class="comment"> // vertex 3 assigned color array element 3 
    139 </span>   colorIndexArray<span class="operator">-&gt;</span>push_back<span class="operator">(</span><span class="int">0</span><span class="operator">);</span><span class="comment"> // vertex 4 assigned color array element 0 </span></pre> 
    140             </div> 
    141             <div class="bodystyle" align="left"> 
    142               <p>The next step is to associate the array of colors with the geometry, assign the color indices created above to the geometry and set the binding mode to _PER_VERTEX.</p> 
    143               <pre class="codebox">   pyramidGeometry<span class="operator">-&gt;</span>setColorArray<span class="operator">(</span>colors<span class="operator">);</span> 
    144    pyramidGeometry<span class="operator">-&gt;</span>setColorIndices<span class="operator">(</span>colorIndexArray<span class="operator">);</span> 
    145    pyramidGeometry<span class="operator">-&gt;</span>setColorBinding<span class="operator">(</span>osg<span class="operator">::</span>Geometry<span class="operator">::</span>BIND_PER_VERTEX<span class="operator">);</span> 
    146  
    147    osg<span class="operator">::</span>Vec2Array<span class="operator">*</span> texcoords<span class="operator"> =</span><span class="keyword"> new</span> osg<span class="operator">::</span>Vec2Array<span class="operator">(</span><span class="int">5</span><span class="operator">); 
    148    (*</span>texcoords<span class="operator">)[</span><span class="int">0</span><span class="operator">].</span>set<span class="operator">(</span><span class="float">0.00f</span><span class="operator">,</span><span class="float">0.0f</span><span class="operator">); 
    149    (*</span>texcoords<span class="operator">)[</span><span class="int">1</span><span class="operator">].</span>set<span class="operator">(</span><span class="float">0.25f</span><span class="operator">,</span><span class="float">0.0f</span><span class="operator">); 
    150    (*</span>texcoords<span class="operator">)[</span><span class="int">2</span><span class="operator">].</span>set<span class="operator">(</span><span class="float">0.50f</span><span class="operator">,</span><span class="float">0.0f</span><span class="operator">); 
    151    (*</span>texcoords<span class="operator">)[</span><span class="int">3</span><span class="operator">].</span>set<span class="operator">(</span><span class="float">0.75f</span><span class="operator">,</span><span class="float">0.0f</span><span class="operator">); 
    152    (*</span>texcoords<span class="operator">)[</span><span class="int">4</span><span class="operator">].</span>set<span class="operator">(</span><span class="float">0.50f</span><span class="operator">,</span><span class="float">1.0f</span><span class="operator">);</span> 
    153     pyramidGeometry<span class="operator">-&gt;</span>setTexCoordArray<span class="operator">(</span><span class="int">0</span><span class="operator">,</span>texcoords<span class="operator">);</span></pre> 
    154               <p class="bodystyle">Now that we have created a geometry node and added it to the scene we can reuse this geometry. For example, if we wanted to put a second pyramid 15 units to the right of the first one, we could add this geode as the child of a transform node in our scene graph. </p> 
    155               <pre class="codebox"><span class="comment">// Declare and initialize a transform node. 
    156 </span>   osg<span class="operator">::</span>PositionAttitudeTransform<span class="operator">*</span> pyramidTwoXForm<span class="operator"> =</span><span class="keyword"> 
    157       new</span> osg<span class="operator">::</span>PositionAttitudeTransform<span class="operator">();</span><span class="comment"> 
    158  
    159 // Use the 'addChild' method of the osg::Group class to 
    160 // add the transform as a child of the root node and the 
    161 // pyramid node as a child of the transform. 
    162 </span>   root<span class="operator">-&gt;</span>addChild<span class="operator">(</span>pyramidTwoXForm<span class="operator">);</span> 
    163    pyramidTwoXForm<span class="operator">-&gt;</span>addChild<span class="operator">(</span>pyramidGeode<span class="operator">);</span><span class="comment"> 
    164  
    165 // Declare and initialize a Vec3 instance to change the 
    166 // position of the tank model in the scene 
    167 </span>   osg<span class="operator">::</span>Vec3 pyramidTwoPosition<span class="operator">(</span><span class="int">15</span><span class="operator">,</span><span class="int">0</span><span class="operator">,</span><span class="int">0</span><span class="operator">);</span> 
    168    pyramidTwoXForm<span class="operator">-&gt;</span>setPosition<span class="operator">(</span> pyramidTwoPosition<span class="operator"> );</span> </pre> 
    169  
    170               <p class="bodystyle">The final step is to set up and enter a simulation loop.</p> 
    171                           <pre class="codebox">   viewer<span class="operator">.</span>setUpViewer<span class="operator">(</span>osgProducer<span class="operator">::</span>Viewer<span class="operator">::</span>STANDARD_SETTINGS<span class="operator">);</span> 
    172    viewer<span class="operator">.</span>setSceneData<span class="operator">(</span> root<span class="operator"> );</span> 
    173  
    174    viewer<span class="operator">.</span>realize<span class="operator">();</span><span class="flow"> 
    175  
    176    while</span><span class="operator">( !</span>viewer<span class="operator">.</span>done<span class="operator">() ) 
    177    {</span> 
    178       viewer<span class="operator">.</span>sync<span class="operator">();</span> 
    179       viewer<span class="operator">.</span>update<span class="operator">();</span> 
    180       viewer<span class="operator">.</span>frame<span class="operator">(); 
    181    }</span> </pre> 
    182  
    183               </div> 
    184           </blockquote> 
    185           <div class="bodystyle" align="left"> 
    186             <blockquote> 
    187               <p>Good luck! </p> 
    188             </blockquote> 
    189           </div></td> 
    190       </tr> 
    191     </table> 
    192     <!-- InstanceEndEditable --></td> 
    193   </tr> 
    194   <tr> 
    195     <td colspan="4" valign="top"><table width="100%" border="0" cellpadding="0" cellspacing="0"> 
    196         <!--DWLayoutTable--> 
    197         <tr> 
    198           <td><div align="center"> 
    199               <hr> 
    200               NPS osgTutorial <a href="index.htm">index</a>. 
    201               <br> 
    202               Author: jasullivan &lt;at&gt; nps &lt;dot&gt; edu | <a href="http://www.nps.navy.mil/cs/sullivan/">Home</a>  
    203               </div></td> 
    204         </tr> 
    205     </table>      <!-- background="../Images/borderLow.gif"DWLayoutEmptyCell-->      &nbsp;</td> 
    206   </tr> 
    207 </table> 
    208 }}} 
     1See [wiki:/Support/Tutorials/BasicGeometry Basic geometry]