X3D Model Documentation: CloudsProcedural1.x3d

  1  <?xml version="1.0" encoding="UTF-8"?>
  2  <!DOCTYPE X3D PUBLIC "ISO//Web3D//DTD X3D 3.2//EN" "https://www.web3d.org/specifications/x3d-3.2.dtd">
  3  <X3D profile='Immersive' version='3.2 xmlns:xsd='http://www.w3.org/2001/XMLSchema-instance' xsd:noNamespaceSchemaLocation='https://www.web3d.org/specifications/x3d-3.2.xsd'>
  4       <head>
  5            <meta name='titlecontent='CloudsProcedural1.x3d'/>
  6            <meta name='descriptioncontent='X3D utilizing ecmascript to develop quasi volumetric 3D clouds from png image textured billboard nodes.'/>
  7            <meta name='creatorcontent='Capt Darren W. Murphy'/>
  8            <meta name='createdcontent='1 November 2007'/>
  9            <meta name='modifiedcontent='20 October 2019'/>
 10            <meta name='identifiercontent='https://savage.nps.edu/Savage/Environment/Atmosphere/CloudsProcedural1.x3d'/>
 11            <meta name='generatorcontent='X3D-Edit, https://www.web3d.org/x3d/content/README.X3D-Edit.html'/>
 12            <meta name='licensecontent='../../license.html'/>
 13            <meta name=' TODO content=' fix links '/>
 14       </head>
<!--

<!--
Event Graph ROUTE Table shows event connections.
-->
<!-- to top Index for DEF nodes: Cirrus, Clouds, Cumulus, PixelScript, Placemarks, Terrain

Index for Viewpoint nodes: Viewpoint_1, Viewpoint_2, Viewpoint_3
-->
 15       <Scene>
 16            <!-- A png image file for the cloud texture must be designated in the ecmascript node. -->
 17            <WorldInfo title='CloudsProcedural1.x3d'/>
 18            <Viewpoint description='Mainjump='falseorientation='0 1 0 1.57position='50000 1000 42000'/>
 19            <Viewpoint description='Light House Towerjump='falseorientation='0 1 0 1.3position='45000 1290 44000'/>
 20            <Viewpoint description='centerWestjump='falseorientation='0 1 0 2.5position='48000 1000 20000'/>
 21            <Background groundColor='0 0 1skyColor='0 0 1'/>
 22            <DirectionalLight ambientIntensity='1direction='-1 0 0global='true'/>
 23            <Group DEF='Terrain'>
 24                 <Transform scale='50 50 50translation='25000 0 25000'>
 25                      <Inline   url=' "../../Locations/MontereyBayCalifornia/MontereyBayLargeMesh.x3d" "https://savage.nps.edu/Savage/Locations/MontereyBayCalifornia/MontereyBayLargeMesh.x3d" "../../Locations/MontereyBayCalifornia/MontereyBayLargeMesh.wrl" "https://savage.nps.edu/Savage/Locations/MontereyBayCalifornia/MontereyBayLargeMesh.wrl" '/>
 26                 </Transform>
 27                 <Transform rotation='1 0 0 1.57translation='25000 0 25000'>
 28                      <Shape>
 29                           <Rectangle2D size='77000 55000'/>
 30                           <Appearance>
 31                                <ImageTexture   url=' "ocean.png " "https://savage.nps.edu/Savage/Environment/Atmosphere/ocean.png " '/>
 32                           </Appearance>
 33                      </Shape>
 34                 </Transform>
 35            </Group>
 36            <Group DEF='Placemarks'>
 37                 <Transform scale='50 50 50translation='45000 30 44000'>
 38                      <Inline   url=' "Lighthouse.x3d" "https://savage.nps.edu/Savage/Environment/Atmosphere/Lighthouse.x3d" "Lighthouse.wrl" "https://savage.nps.edu/Savage/Environment/Atmosphere/Lighthouse.wrl" '/>
 39                 </Transform>
 40            </Group>
 41            <Group DEF='Clouds'>
 42 
               <!-- Transform Cumulus is a DEF node that has 1 USE node: USE_1 -->
               <Transform DEF='Cumulus'/>
 43 
               <!-- Transform Cirrus is a DEF node that has 1 USE node: USE_1 -->
               <Transform DEF='Cirrus'/>
 44                 <Script DEF='PixelScriptdirectOutput='true'>
 45                      <field name='Cumulustype='SFNodeaccessType='initializeOnly'>
 46                           <Transform USE='Cumulus'/>
 47                      </field>
 48                      <field name='Cirrustype='SFNodeaccessType='initializeOnly'>
 49                           <Transform USE='Cirrus'/>
 50                      </field>
  <![CDATA[
        
ecmascript:
function cumulustranslation() // These values designate the boundary location of the cloud
{
	X = 50000*Math.random();          //  X horizontal range
	Y = 1000 + 300*Math.random();	 //  Y vertical base + range
	Z = 50000*Math.random();         // z horizontal range

	randomt = new String(X+' '+Y+' '+Z);

	return randomt;

}



function cumulusscale() // these values scale a cloud within a designated size
{

	maxscale = 1;

	scale = Math.round(9+maxscale*Math.random());
	X = 1.5*scale;
	Y = scale;
	Z = scale;

	randomscale = new String(X+' '+Y+' '+Z);

	return randomscale;

}


function cirrustranslation() // These values designate the boundary location of the cloud
{
	X = 50000*Math.random();          //  X horizontal range
	Y = 8000 + 1000*Math.random();	 //  Y vertical base + range
	Z = 50000*Math.random();         // z horizontal range

	randomt = new String(X+' '+Y+' '+Z);

	return randomt;

}



function cirrusscale() // these values scale a cloud within a designated size
{

	maxscale = 1;

	scale = Math.round(9+maxscale*Math.random());
	X = 1.5*scale;
	Y = 2*Math.random();
	Z = 1.5*scale;

	randomscale = new String(X+' '+Y+' '+Z);

	return randomscale;

}


function cumulussectiontranslation() // These random values place another portion of cumulus type cloud
{

	randomtheta = 6.28319*Math.random();
	randomphi = .7854*Math.random();
	randomradius = 90 + 5*Math.random();//the first whole number should be close to the sectionradius

	X = randomradius*Math.cos(randomtheta)*Math.sin(randomphi);
	Z = randomradius*Math.sin(randomtheta)*Math.sin(randomphi);
	Y = randomradius*Math.cos(randomphi);


	randomt = new String(X+' '+Y+' '+Z);

	return randomt;

}

function cirrussectiontranslation() // These random values place another portion of cirrus type cloud
{

	randomtheta = 6.28319*Math.random();
	randomphi = .7854*Math.random();
	randomradius = 90 + 5*Math.random();//the first whole number should be close to the sectionradius

	X = randomradius*Math.cos(randomtheta)*Math.sin(randomphi);
	Z = randomradius*Math.sin(randomtheta)*Math.sin(randomphi);
	Y = randomradius*Math.cos(randomphi);


	randomt = new String(X+' '+Y+' '+Z);

	return randomt;

}


function rotation() // This random value is for the billboard rotation not used in this script
{


	radians = 6.28*Math.random();

	randomr = new String('0 0 1 ' + radians );


	return randomr;

}

function cumulus()
{

maxi = 10;  // number of clouds

maxj = 5; // denotes how many portions affecting the size of the cloud

maxk = 8;  // number of billboards indicating cloud density

sectionradius = 100;  //radius of individual cloud sections





for (var i=0; i < maxi; i++)
{



CloudStringA = '	Transform {		\n' +
'    scale '+ cumulusscale() + '               	\n' +
'    translation '+ cumulustranslation() + '    \n' +    // cloud placement
'    children [	                                \n';


CloudStringB = new Array();
CloudStringF = new Array();

   	for (var j=0; j < maxj; j++)
   	{

	radius = 0;

	CloudStringB[j]= '  Transform {		    	       \n' +
	'    translation '+ cumulussectiontranslation() + '    \n' +     // section placement
	'    children [	                                       \n';


	CloudStringC = new Array();
	image = new String();

      		for (var k=1; k < maxk; k++)  // maxk value denotes how many textured billboards make up the cloud
      		{


		randomtheta = 6.28319*Math.random();
		randomphi = 1.57079*Math.random();
		radius = radius+(sectionradius/maxk); // radius incremental steps based on billow radius and max billboards

		X = radius*Math.cos(randomtheta)*Math.sin(randomphi);
		Z = radius*Math.sin(randomtheta)*Math.sin(randomphi);
		Y = radius*Math.cos(randomphi);


		if (Y <= 30) //cloud shading and lighting control
  	{
	image = ' \"Spheretexture.png\" \"https://savage.nps.edu/Savage/Environment/Spheretexture.png\" \n';
  	}

  		else
  	{
	image = ' \"Spheretexture.png\" \"https://savage.nps.edu/Savage/Environment/Spheretexture.png\" \n';
  	}



		Billboardtranslation = new String(X+' '+Y+' '+Z);

		CloudStringC[k] = '	Transform {		                \n' +
		'            translation '+ Billboardtranslation   + '          \n' +     // random billboard placement within radius designated above
		'	  children [	                                        \n' +
		'	      Billboard {	                                \n' +
		'	        axisOfRotation 0 0 0	                        \n' +     // 0 0 0 designates rotation on all axis
		'	        children [	                                \n' +
		'	            Transform {	                		\n' +
		'	              rotation  0 0 0 0 		        \n' +     // a rotation of the individual billboards can be defined
		'	              children [	                        \n' +
		'	                  Shape {	                        \n' +
		'	                    appearance Appearance {	        \n' +
		'				material Material {		\n' +
		'				                }  		\n' +
		'	                      texture ImageTexture {	        \n' +
		'	                        url [ ' + image + ' ]           \n' +
		'	                      }	                                \n' +
		'	                    }	                                \n' +
		'	geometry Sphere {					\n' +
		'	          radius 50					\n' +
		'	        }						\n' +
		'	                  }	                                \n' +
		'	              ]	                                        \n' +
		'	            }	                                        \n' +
		'	       ]	                                        \n' +
		'	   }	                                                \n' +
		'      ]	                                                \n' +
		'     }	                                                        \n';


		}

	CloudStringD = CloudStringC.join(' ');


	CloudStringE = '   ]	                 \n' +
	'	}	                         \n';

	CloudStringF[j] = CloudStringB[j] + CloudStringD +CloudStringE;


	}

CloudStringG = CloudStringF.join(' ');

CloudStringH = '      ]	                                        \n' +
'     }	                                                        \n' +
'#########################################################      \n';

CloudString = CloudStringA + CloudStringG + CloudStringH;



newNode = Browser.createVrmlFromString(CloudString);
Cumulus.children[i] = newNode[0];


   }

}

function cirrus()

{

maxi = 2;  // number of clouds

maxj = 5; // denotes how many portions affecting the size of the cloud

maxk = 8;  // number of billboards indicating cloud density

sectionradius = 1000;  //radius of individual cloud sections





for (var i=0; i < maxi; i++)
{



CloudStringA = '	Transform {		 \n' +
'    scale '+ cirrusscale() + '               	 \n' +
'    translation '+ cirrustranslation() + '      \n' +    // cloud placement
'    children [	                                 \n';


CloudStringB = new Array();
CloudStringF = new Array();

   	for (var j=0; j < maxj; j++)
   	{

	radius = 0;

	CloudStringB[j]= '  Transform {		    	      \n' +
	'    translation '+ cirrussectiontranslation() + '    \n' +     // section placement
	'    children [	                                      \n';


	CloudStringC = new Array();

      		for (var k=1; k < maxk; k++)  // maxk value denotes how many textured billboards make up the cloud
      		{


		randomtheta = 6.28319*Math.random();
		randomphi = 1.57079*Math.random();
		radius = radius+(sectionradius/maxk); // radius incremental steps based on section radius and max billboards

		X = radius*Math.cos(randomtheta)*Math.sin(randomphi);
		Z = radius*Math.sin(randomtheta)*Math.sin(randomphi);
		Y = radius*Math.cos(randomphi);

		Billboardtranslation = new String(X+' '+Y+' '+Z);

		CloudStringC[k] = '	Transform {		                \n' +
		'            translation '+ Billboardtranslation   + '          \n' +     // random billboard placement within radius designated above
		'	  children [	                                        \n' +
		'	      Billboard {	                                \n' +
		'	        axisOfRotation 0 0 0	                        \n' +     // 0 0 0 designates rotation on all axis
		'	        children [	                                \n' +
		'	            Transform {	                		\n' +
		'	              rotation '  + rotation() + '	        \n' +
		'	              children [	                        \n' +
		'	                  Shape {	                        \n' +
		'	                    appearance Appearance {	        \n' +
		'			    material Material {			\n' +
		'			    }					\n' +
 		'	                      texture ImageTexture {	        \n' +
		'	                        url [\"cloudtexture3.png\" \"https://savage.nps.edu/Savage/Environment/cloudtexture1_4.png\" ] \n' +
		'	                      }	                                \n' +
		'	                    }	                                \n' +
		'	                    geometry IndexedFaceSet {	        \n' +     // define type of geometry to texture
		'	                      coordIndex [ 0, 1, 2, 3 ]	        \n' +
		'			      solid FALSE		        \n' +
		'	                      coord Coordinate {	        \n' +
		'	                        point [ 500 500 0,	        \n' +     // define size of the geometry. Here 100 meter 2D square.
		'	                                500 -500 0,	        \n' +
		'	                               -500 -500 0,	        \n' +
		'	                               -500 500 0 ]	        \n' +
		'	                      }	                                \n' +
		'	                    }	                                \n' +
		'	                  }	                                \n' +
		'	              ]	                                        \n' +
		'	            }	                                        \n' +
		'	       ]	                                        \n' +
		'	   }	                                                \n' +
		'      ]	                                                \n' +
		'     }	                                                        \n';


		}

	CloudStringD = CloudStringC.join(' ');

	CloudStringE = '   ]	                 \n' +
	'	}	                         \n';

	CloudStringF[j] = CloudStringB[j] + CloudStringD +CloudStringE;


	}

CloudStringG = CloudStringF.join(' ');

CloudStringH = '      ]	                                        \n' +
'     }	                                                        \n' +
'#########################################################      \n';

CloudString = CloudStringA + CloudStringG + CloudStringH;



newNode = Browser.createVrmlFromString(CloudString);
Cirrus.children[i] = newNode[0];

  }

}


function initialize()

{

cumulus();

cirrus();
}

      
]]>
 52                 </Script>
 53            </Group>
 54       </Scene>
 55  </X3D>
<!--

<!--
Event Graph ROUTE Table shows event connections.
-->
<!-- to top Index for DEF nodes: Cirrus, Clouds, Cumulus, PixelScript, Placemarks, Terrain

Index for Viewpoint nodes: Viewpoint_1, Viewpoint_2, Viewpoint_3
-->
X3D Tooltips element index: Appearance, Background, DirectionalLight, field, Group, head, ImageTexture, Inline, meta, Rectangle2D, Scene, Script, Shape, Transform, Viewpoint, WorldInfo, X3D, plus documentation for accessType definitions, type definitions, XML data types, and field types

-->
<!-- Online at
https://savage.nps.edu/Savage/Environment/Atmosphere/CloudsProcedural1Index.html -->
<!-- Version control at
https://gitlab.nps.edu/Savage/Savage/Environment/Atmosphere/CloudsProcedural1.x3d -->

<!-- Color-coding legend: X3D terminology <X3dNode  DEF='idNamefield='value'/> matches XML terminology <XmlElement  DEF='idNameattribute='value'/>
(Light-blue background: event-based behavior node or statement) (Grey background inside box: inserted documentation) (Magenta background: X3D Extensibility)
-->

to top <!-- For additional help information about X3D scenes, please see X3D Tooltips, X3D Resources, and X3D Scene Authoring Hints. -->