ShapeWaterTutorial, version = 0

Elbow Water Tutorial

This tutorial will step through generating a spot using the ElbowWater function.
You can cut and paste the 3DML code into a text editor. Also, all the tutorial spots are located in the directory labeled /TutorialSpots/.


The ElbowWater function creates a tube of water bent through 90 degrees around the X axis. The center axis is parallel to the YZ plane. The center of the initial radius is the block's (0,0,0) coordinate, and may be offset by the parameters Xoffset, Ystart and Zstart. The center of the final radius is specified by the parameters Yend and Zend. The parameters Rinit and Rfinal specify the initial and final radii. The parameter Nvertices tells the function the number of vertices on one side of a water.bset or ShapeWater.bset block. The parameters Xoffset, Yoffset, Zstart, Zend, Rinit, Rfinal are specified in pixels.
Refer to Figure 1 and 2.

Note: Use the ElbowNxN.block from the ShapeWater blockset in the CREATE tag for any block being modified by the ElbowWater( ) function. The ElbowNxN.block's have extra polygons to fill the interior of the elbow tube to help prevent Rover from rendering missing surfaces when the block is viewed from certain directions.

The RIPPLE tag propagates Waves from the Initial radius end to the Final radius end.

Function Prototype:
ElbowWater( blockReference, Nvertices, Xoffset, Ystart, Yend, Zstart, Zend, Rinit, Rfinal )

Function Prototype:
ElbowWaterGeneral( blockReference, Nvertices, Xoffset, Ystart, Yend, Zstart, Zend, Rinit, Rfinal, theta )
The ElbowWaterGeneral function allows the bend angle to be specified. The bend angle, theta, q, is specified in radians, and is the angle starting from the Y axis and increasing in the direction of the Z axis. (Think of "rotate around X axis".)
Note: This routine is only valid for angles less than +/- 90 degrees.

Scale Factor: Figure 1. Elbow Water 3D
Scale Factor: Figure 2. Elbow Water 2D

ElbowWaterSpot1.3dml

Create a spot that places an elbow of water with the center of the initial radius at the (0,200,0) coordinates of a block. The center of the final radius will be at the (0,30,200) coordinates of a block. The initial radius will be 40 pixels and the final radius will be 40 pixels. The tube will be made with the Elbow15x15 block from from the ShapeWater blockset.
<spot>
<head>
   <title name="Elbow Water Spot 1"/>
   <blockset href="http://blocksets.flatland.com/flatsets/basic.bset"/>

   <!-- get the ShapeWater Blockset -->
   <blockset href="http://www.mikejost.com/3dml/Blocksets/ShapeWater/ShapeWater.bset"/>

   <debug/>
   <map style="double" dimensions="(5,5,1)" /> 
   <sky brightness="90%"/>
   <ambient_light brightness="100%"/>
   <ground texture="@basic:cement.gif"/>

</head>
<body>

<!--   Import ShapeWater Functions   -->
<import href="http://www.mikejost.com/3dml/Blocksets/ShapeWater/ShapeWater.3dml"/>

<entrance name="default" location="(4,2,1)" angle="270,0" />

<!--  Create the Elbow water block -->
<create symbol="ew" block="Elbow15x15">
   <param movable="yes" origin="(0.0, 0.0, 0.0)"/> <!-- make block Movable and set origin to lower south-west corner -->
   <part name="water" texture="@ShapeWater:bluewater.jpg" style="scaled" translucency="60%" faces="2"/>
   <part name="interior" texture="@ShapeWater:bluewater.jpg" style="tiled" translucency="80%" faces="1"/>
   <action trigger="start">
      <ripple style="raindrops" force="8.0" droprate="50%" damp="99%"/>
   </action>
</create>

<define>

   <!-- Start Function -->
   <function name="start">
      // Initialize the vertices of the water block for an initial radius of 40
      // centered at (0,200,0) and a final radius of 40 centered at (0,30,200). 
      waterBlock = map.get_block("ew");
      // Elbow( block, Nvertices, Xoffset, Ystart, Yend, Zstart, Zend, Rinit, Rfinal )
      ElbowWater( waterBlock, 15, 0, 200, 30, 0, 200, 40.0, 40.0);
   </function>

</define>

<!--
 1  2  3  4  5  -->
<level number="1">
.. .. .. .. ..  <!--  1 -->
.. .. ew .. ..  <!--  2 -->
.. .. .. .. ..  <!--  3 -->
.. .. .. .. ..  <!--  4 -->
.. .. .. .. ..  <!--  5 -->
</level>

</body>
</spot>


The spot should look like Figure 1 with both the initial and final radii the same. The wave should propagate from the left (Rinit) to the right (Rfinal).

How Elbow parameters effect Elbow shape.

The next spot will give a quick view of how the relationship between ystart and zend effects the elbow shape when xoffset=0, yend=0, and zstart=0. The intial and final radii will be 20 pixels. The code in the spot moves ystart and zend from 0 to 250 pixels in 25 pixel steps.

ElbowWaterSpot2.3dml


<spot>
<head>
   <title name="Elbow Water Spot 2"/>
   <blockset href="http://blocksets.flatland.com/flatsets/basic.bset"/>

   <!-- get the ShapeWater Blockset -->
   <blockset href="http://www.mikejost.com/3dml/Blocksets/ShapeWater/ShapeWater.bset"/>

   <debug/>
   <map style="double" dimensions="(5,5,1)" /> 
   <sky brightness="90%"/>
   <ambient_light brightness="100%"/>
   <ground texture="@basic:cement.gif"/>

</head>
<body>

<!--   Import ShapeWater Functions   -->
<import href="http://www.mikejost.com/3dml/Blocksets/ShapeWater/ShapeWater.3dml"/>

<entrance name="default" location="(4,2,1)" angle="270,0" />

<!--  Create the Elbow water block -->
<create symbol="ew" block="Elbow15x15">
   <param movable="yes" origin="(0.0, 0.0, 0.0)"/> <!-- make block Movable and set origin to lower south-west corner -->
   <part name="water" texture="@ShapeWater:bluewater.jpg" style="scaled" translucency="60%" faces="2"/>
   <part name="interior" texture="@ShapeWater:bluewater.jpg" style="tiled" translucency="80%" faces="1"/>
   <action trigger="start">
      <ripple style="raindrops" force="8.0" droprate="50%" damp="99%"/>
   </action>
   <define>
      <type>z</type>
      <dir>1</dir>
      <ystart>0</ystart>
      <zend>0</zend>
   </define>
   <script trigger="timer" delay="0.25" >
      waterBlock = map.get_block("ew");

      if (type = "z") {
         if (dir gt 0) {
            zend = zend + 15;
            if (zend gt 250) { zend = 250; type ="y"; }  
         }
         else {   
            zend = zend - 15;
            if (zend lt 0) { zend = 0; type = "y"; }   
         }   
      }   
      else{   
         if (dir gt 0) {   
            ystart = ystart + 15;
            if (ystart gt 250) { ystart = 250; dir = -1; type = "z"; }   
         }   
         else{   
            ystart = ystart - 15;
            if (ystart lt 0) { ystart = 0; dir = 1; type = "z"; }   
         }   
      }
      // Elbow( block, Nvertices, Xoffset, Ystart, Yend, Zstart, Zend, Rinit, Rfinal )
      spot.ElbowWater( waterBlock, 15, 0, ystart, 0, 0, zend, 20, 20);
   
   </script>
</create>

<!--
 1  2  3  4  5  -->
<level number="1">
.. .. .. .. ..  <!--  1 -->
.. .. ew .. ..  <!--  2 -->
.. .. .. .. ..  <!--  3 -->
.. .. .. .. ..  <!--  4 -->
.. .. .. .. ..  <!--  5 -->
</level>

</body>
</spot>


Experimentation:

  • Try using the ElbowWaterGeneral function. ElbowWaterSpot3.3dml uses this function and changes the angle from 0 to 135 degrees.
  • Try making Rinit positive and Rfinal negative.


    Notes:

  • The origin of the block is the center of rotations.
  • The ElbowWater() center coordinates are absolute block coordinates and are not based on the origin of the block.

    End of ElbowWater Tutorial

    The rest is up to you. Have fun.