Book Image

WebGL HOTSHOT

By : Mitch Williams
Book Image

WebGL HOTSHOT

By: Mitch Williams

Overview of this book

Table of Contents (17 chapters)
WebGL HOTSHOT
Credits
About the Author
About the Reviewers
www.PacktPub.com
Preface
Index

Creating an animated Solar System with multiple cameras for navigation


We conclude this 3D graphics overview with our first application, a Solar System with several cameras and planets undergoing multiple animations. First, we will look at the organization of these objects in a condensed version of the X3D code (the <IndexedFaceSet> node in the Earth was removed from here since it consists of thousands of values).

Engage thrusters

Earth comprises of three <Transform> nodes for its rotation around the Sun, the seasons, and the 24-hour day. Note that in the Earth's outermost transformation, center (0, 0, 10) is at the same distance from the Sun as the Earth's translation (0, 0, -10). This is because the center of the Earth's yearly rotation is the Sun. The rotation for the Earth's seasons is around the z axis, set to 0.4 radians or 23 degrees, the actual tilt of the Earth. The final inner <Transform> node controls the Earth's daily rotation.

The Moon <Transform> is a child of the Earth's annual rotation. The Moon's rotation is centered on the Earth. Thus, the Moon's translation is 3 units (3, 0, 0) from the Earth, but its center is 3 units behind (-3, 0, 0). Of course, the Moon is unaffected by the Earth's seasonal and daily rotation, and thus the Moon's <Transform> node is a child object of the Earth's outermost year <Transform> but not a child of the Earth's seasonal or daily transformation.

<NavigationInfo headlight="FALSE"/>
<Viewpoint id="mainCamera" orientation="1 0 0 -.3"
position="0 8 30"/>
<Viewpoint id="aboveCamera" orientation="1 0 0 -1.57"
position="0 180 0"/>
<PointLight/>
    <Transform DEF="Sun">
        <Shape>
            <Sphere radius="6" onclick =
                "document.getElementById('aboveCamera')
                .setAttribute('set_bind','true');"/>
            <Appearance>
                <Material diffuseColor="1 1 0" emissiveColor="1 .7 0"/>
            </Appearance>
        </Shape>
    </Transform>

    <Viewpoint id="EarthCamera" position=" 0 2 0" orientation="0 1 0 0"/>
    <Transform DEF="Earth" center="0 0 10"
translation="0 0 -10" scale="2 2 2">
        <Transform DEF="Earth-Season" rotation="0 0 1 .4">
            <Transform DEF="Earth-Day">
                <Shape>
….IndexedFaceSet and coordinates 
                </Shape>
            </Transform>
</Transform>
        <Transform DEF="Moon" center="-3 0 0"
translation="3 0 0">
<Shape>
                <Sphere radius=".6"/>
                <Appearance>
            <Material diffuseColor=".4 .4 .4"/>
                </Appearance>
</Shape>
        </Transform>
    </Transform>

Saturn also has a <Transform> node centered around the Sun and two child <Transform> nodes to control Saturn's day and rings that are constructed from a flat plane and a texture map with a transparency.

    <Viewpoint id="SaturnCamera" position=" 0 0 0"
orientation="0 1 0 0" fieldOfView=".5"/>
    <Transform DEF="Saturn" center="0 0 20"
translation="0 0 -20" scale="4 4 4">
        <Transform DEF="SaturnDay">
            <Shape>
                <Appearance>
                    <Material diffuseColor='1 1 1'
                              specularColor='.1 .1 .1'
                              shininess='0.9' />
                    <ImageTexture
url="./textureMaps/saturn.jpg"/>
                </Appearance>
                <IndexedFaceSet USE='Sphere_GEOMETRY' />
            </Shape>
        </Transform>

Saturn's rings are just a flat plane consisting of two polygons and a texture map. A .gif image is used to allow transparent areas in the corners and the center where Saturn sits. Saturn's rings are slightly tilted towards the Sun during the phases of its rotation around the Sun, as shown in the figure that follows this code:

        <Transform DEF="rings" rotation="1 0 0 .2">
            <Shape>
                <Appearance>
                    <Material diffuseColor='1 1 1'
                              specularColor='.2 .2 .2'
                              shininess='0.8'
                              emissiveColor=".1 .1 .1"/>
                    <ImageTexture
url="./textureMaps/SaturnRings.gif"/>
                </Appearance>
                <IndexedFaceSet coordIndex="0 1 2 -1 2 3 0 -1   2 1 0 -1   0 3 2 -1"
texCoordIndex="0 1 2 -1   2 3 0 -1 2 1 0 -1   0 3 2 -1">
                    <Coordinate point="-4 0 4   4 0 44 0 -4   -4 0 -4"/>
                    <TextureCoordinate point="0 0   1 01 1   0 1"/>
                </IndexedFaceSet>
            </Shape>
        </Transform>
    </Transform>
</Transform>

Animation is a series of <TimeSensor>, <OrientationInterpolator>, and <ROUTE> functions. The fraction of time is sent via the <ROUTE> node from <TimeSensor> to the interpolator, which uses another <ROUTE> node to update the rotation or position in the object's <Transform> node in order to allow rotation of the Earth around the Sun as the first four statements show in the following code. The next set of three statements control the seasonal tilt of the Earth using the same <TimeSensor> node with a rotation around the z axis of +/- 0.4 radians. The day rotation for the Earth has its own four statements to control the 24-hour day, animated as one second. The Moon has its own independent animation and finally, the camera focused on the Earth uses the same <TimeSensor> node as the Earth's year and seasons. However, the cameras focused on the Earth, the Earth's annual rotation, and the Earth's seasons have their own <OrientationInterpolator> nodes. Saturn has its own interpolators to rotate around the Sun and for its own day, but this is not shown in the following code:

<TimeSensor DEF="yearTimer" cycleInterval="36.5" loop="true"/>
<OrientationInterpolator DEF="yearlyRotation" key="0 .5 1"
keyValue="0 1 0 0   0 1 0 3.14   0 1 0 6.28"/>
<ROUTE fromField="fraction_changed" fromNode="yearTimer"
toField="set_fraction" toNode="yearlyRotation"/>
<ROUTE fromField="value_changed" fromNode="yearlyRotation"
toField="rotation" toNode="Earth"/>

Earth's seasonal rotation, which has a tilt of 0.4 radians, is demonstrated in the following code:

<OrientationInterpolator DEF="seasonalRotation" key="0 .5 1"
keyValue="0 0 1 .4   0 0 1 -.4   0 0 1 .4"/>
<ROUTE fromField="fraction_changed" fromNode="yearTimer"
toField="set_fraction" toNode="seasonalRotation"/>
<ROUTE fromField="value_changed" fromNode="seasonalRotation"
toField="rotation" toNode="Earth-Season"/>

Earth's day rotation, set to 1 second, is demonstrated in the following code:

<TimeSensor DEF="EarthDayTimer" cycleInterval="1" loop="true"/>
<OrientationInterpolator DEF="EarthDayRotation" key="0 .5 1"
keyValue="0 1 0 0   0 1 0 3.14   0 1 0 6.28"/>
<ROUTE fromField="fraction_changed" fromNode="EarthDayTimer"
toField="set_fraction" toNode="EarthDayRotation"/>
<ROUTE fromField="value_changed" fromNode="EarthDayRotation"
toField="rotation" toNode="Earth-Day"/>

The Moon's rotation around the Earth is set to 5.8 seconds and is demonstrated in the following code:

<TimeSensor DEF="moonTimer" cycleInterval="5.8" loop="true"/>
<OrientationInterpolator DEF="YRotMoon" key="0 .5 1"
keyValue="0 1 0 0   0 1 0 3.14   0 1 0 6.28"/>
<ROUTE fromField="fraction_changed" fromNode="moonTimer"
toField="set_fraction" toNode="YRotMoon"/>
<ROUTE fromField="value_changed" fromNode="YRotMoon"
toField="rotation" toNode="Moon"/>

To ensure that our camera stays focused on the Earth, the <Viewpoint> node is also animated using the same year timer as the Earth, as shown in the following code:

<OrientationInterpolator DEF="EarthCameraRotation" key="0 .5 1"
keyValue="0 1 0 0   0 1 0 3.14   0 1 0 6.28"/>
<ROUTE fromField="fraction_changed" fromNode="yearTimer"
toField="set_fraction" toNode="EarthCameraRotation"/>
<ROUTE fromField="value_changed" fromNode="EarthCameraRotation"
toField="orientation" toNode="EarthCamera"/>

The images in the preceding figure show the views from Saturn's and Earth's cameras, two of the four cameras in the scene. To track planets, the user requires HTML buttons to navigate from one planet to the next. Clicking on the Sun or Earth will also take the user to the respective cameras. Buttons for X3D on a web page use the same buttons as any HTML page. What is unique for X3D is that element ID's such as aboveCamera and mainCamera are the ID values for the <Viewpoint> nodes in X3D. The setAttribute('set_bind', 'true') method, also a part of X3D, sets this as the new camera position, as shown in the following code:

<input type="button" value="Solar System View"
onclick="document.getElementById('aboveCamera').setAttribute('set_bind','true');" />
<input type="button" value="Sun"
onclick="document.getElementById('mainCamera').setAttribute('set_bind','true');" />
<input type="button" value="Earth"
onclick="document.getElementById('EarthCamera').setAttribute('set_bind','true');" />
<input type="button" value="Saturn"
onclick="document.getElementById('SaturnCamera').setAttribute('set_bind','true');" />

Note

Some of the images in the preceding figure look pixelated or tiled. This is partly due to the default shader language and will be addressed as we go further in WebGL.

Objective complete – mini debriefing

If you are new to the creation of 3D, one of the most fun aspects is the instant gratification from creating 3D scenes. In the subsequent projects, we will apply 3D graphics to familiar applications and see the places where 3D can be a more effective communication tool for users.