The camera setup must be done first, before anything else.
<set_camera>
<frustum view_angle, near_field, far_field />
<position x, y, z />
<pointat x, y z />
</set_camera>
Example:
<set_camera>
<frustum 45.0, 2.5, 12000.0/>
<position 0.0, 1200.0, -4900.0/>
<pointat 0.0, 0.0, -2350.0/>
</set_camera>
Where: View_angle is in degrees. (Frustum is the viewable volume in front of the
virtual camera, or viewing location.)
Near-field is the closest range from the camera that objects will be visible.
Far-field is the farthest range.
Convention is to assume coordinates are in meters.
X-axis is initially left-right (for camera position x=0 with z=negative).
Y-axis is up-down (positive y is up).
Z-axis is into screen.
The pointat operator specifies where the camera is pointing at.
Camera settings can be changed throughout simulation.
If unsure about these settings, experiment. Frustum can be varied
interactively under the Meta-menu.
2. Defining Object Types:
<def_obj> type_name
<col r g b t/>
<tri> <vrt t1x t1y t1z /> <vrt t2x t2y t2z /> <vrt t3x t3y t3z /> </tri>
...
</def_obj>
In def_obj, color can be anywhere or (almost) nowhere.
Color r,g,b and t, where t is transparency (1=solid, 0=clear, 0.5=translucent, etc.).
Example:
<def_obj> BuildingT36
<tri> <col 0.19 0.27 0.28 1/>
<vrt 118.03 0 -259.674/>
<vrt 157.36 0 -259.674/>
<vrt 157.36 206.467 -259.674/>
</tri>
<tri> <vrt 118.03 206.467 -259.674/>
<vrt 118.03 0 -259.674/>
<vrt 157.36 206.467 -259.674/>
</tri>
<tri> <vrt 118.03 206.467 -312.025/>
<vrt 118.03 206.467 -259.674/>
<vrt 157.36 206.467 -259.674/>
</tri>
</def_obj>
The above shows how to define objects with triangular polygons.
Quadralateral polygons are also supported through the <quad> construct:
<quad> <vrt x y z /> <vrt x y z /> <vrt x y z /> <vrt x y z /> </quad>
Note there are four vertices per a quad. Special care must be taken, when using quads, to not cross the vertices, like an hour-class shape.
Open GL does not support that.
A key point to note is that, by default, triangles and quadralaterals are visible only from their front side. (This is advantageous because it is more efficient as most objects are viewed from one side. For example the walls of any solid object, such as a boat or a building, as viewed from outside.) The front side is determined by the pointing direction of the vector norm of the vertices, - also called the winding. If you get the winding (order of the vertices) wrong, you may notice your triangle is viewable from the wrong side. Simply reverse the winding by flipping a pair of vertices in the case of a triangle, or by re-ordering three vertices of a quad.
A simple way to avoid the wrong-side problem is to use two-sided polygons. These are also useful when you are describing a thin surface which actually can be viewed from both sides. Use the variants <tri2> and <quad2> accordingly.
Images/Textures:
Instead of just colored surfaces, you can define objects by mapping arbitrary images to the quadralaterials.
This produces rich textures and realistic views, while often reducing the total polygons for drawing scenes with
better qualities.
Instead of <tri>, <col>,and <quad>; use:
<image> image_filename <vrt t1x t1y t1z/> <vrt t1x t1y t1z/> <vrt t1x t1y t1z/> <vrt t1x t1y t1z/> </image>Mixtures of <tri>, & <quad>,and <image> can be used in any combination.
Example:
<def_obj> BuildingT79
<image> skyscraper.ppm <vrt 118.03 0 -259.674/> <vrt 57.36 106.4 -59.4/>
<vrt 157.36 0 -259.674/> <vrt 157.36 206.467 -259.674/>
</image>
<col 0.19 0.27 0.28 1/>
<tri> <vrt 118.03 206.467 -259.674/>
<vrt 118.03 0 -259.674/> <vrt 157.36 206.467 -259.674/>
</tri>
</def_obj>
Note that images require four vertices. See above notes on quads for
discussion about winding order. Not all image formats are currently
supported on all platforms. The .ppm format is supported on all platforms.
Image dimensions (width/height in columns/rows) which are not a power of
two (ex. 32, 64, 128, 256, etc..) will cause OpenGL to tile or repeat the
image until it fits within the next power of two. This is good for
textures which you wish to have applied as tiles. If you need a one-to-one
match with your quad, resize your image so that the sides are powers of 2.
The number of rows must equal the number of columns or else you will get
bizarre results. Images can be converted to PPM and resized through any of a
variety of programs, such as ImageMagik Convert, XV, The Gimp,
cjpeg, and netpbm.
You do not need to match an image file directly to each polygon rendered.
You can use different slices of a common image to cover many different polygons.
Placing "slice" coordinates before each vertex tells where out of
a large image to map the slice to. The slice coordinates map
an x-y region within an image to an x,y,z position in 3-space.
The slice coords range from 0.0 -to- 1.0 (floating point). For example,
(0.0,0.0) is the upper left corner of the image, and (1.0,1.0) is
the bottom right corner, regardless of pixel dimensions of the image.
Example:
<image> pic.ppm
<slc 0.4 0.2> <vrt 118.03 0 -259.674/>
<slc 0.6 0.2> <vrt 57.36 106.4 -59.4/>
<slc 0.6 0.3> <vrt 157.36 0 -259.674/>
<slc 0.4 0.3> <vrt 157.36 206.467 -259.674/>
</image>
This gives you the power to warp images in various ways.
The default method is equivalent to:
<image> pic.ppm
<slc 0.0 0.0> <vrt 118.03 0 -259.674/>
<slc 1.0 0.0> <vrt 57.36 106.4 -59.4/>
<slc 1.0 1.0> <vrt 157.36 0 -259.674/>
<slc 0.0 1.0> <vrt 157.36 206.467 -259.674/>
</image>
Example Winding Order:
(1)------------>(2)
|
|
|
|
v
(4)<------------(3)
The above winding order makes the quad or image viewable from one side, and
invisible from the other side. For example, the winding order 1, 4, 3, 2, is also
valid, and will make the quad/image viewable form the opposite side. However, an
order such as 1, 3, 4, 2, is not valid, because the vertices will cross
and do not circle the perimeter.
Scaling and Offsets:
Scale:
<scale> SC </scale>
Offset:
<offset x=XX y=YY z=ZZ/>
Where SC is the scale amount, and XX, YY, ZZ are the offset amounts for x
y, and z axes, respectively. These commands scale or offset all subsequent
objects by the designated amounts. This can be used to fit objects
which were defined with greatly differing sizes into common scenes.
Also allows changing the centers for better rotations.
Examples:
<scale> 2.0 </scale>
<offset x=10.0/>
<offset x=10.0 y=-30.0/>
3. Instantiating Objects:
<inst_obj> instance_name type_name
x y z xAxisAngle yAxisAngle zAxisAngle
</inst_obj>
...
Where x,y,z is initial position, and the remaining are the initial angles in degrees.
The above is useful for instantiating the initial objects. To add new objects at
later times, use inst_obj_at.
<inst_obj_at> instance_name type_name T
x y z xAxisAngle yAxisAngle zAxisAngle
</inst_obj>
Where T is instantiation time.
Example
<inst_obj> Building_37 BuildingT36 0 0 0 0 0 0 </inst_obj>
Instance Scaling - <scale> SC </scale>
- Affects the instantiation positions.
- Is obeyed when encountered anywhere between objects.
(Except within an object's definition where it is local.)
- Remains set to whatever, until re-set back to 1.0.
- Does not affect an instance of an object's defined size,
but does scale the position values of the instantiated object.
4. Moving Objects:
moveobject
<mo obj_instance_name t1 t2 x, y, z />
<mo_rel obj_instance_name duration x, y, z />
rotateobject
<ro obj_instance_name t1 t2 xang, yang, zang />
<ro_rel obj_instance_name duration xang, yang, zang />
orbitobject
<orbity obj_instance_name t1 t2 centerx, centery, centerz, yang />
<orbity_rel obj_instance_name duration centerx, centery, centerz, yang />
The _rel, or relative versions of the movement commands instruct the
viewer to move the object for the duration specified, beginning whenever the command
is received by the viewer. These permit non-synchronized/real-time simulations to
drive the viewer. They are time-relative, or relative to the current time.
All angles are specified in degrees.
5. Drawing Lines or Radio Beams:
Lines between Points in Space -
DrawLine
<drawline x1 y1 z1 x2 y2 z2 t1 t2 r g b thickness/>
<drawline_rel x1 y1 z1 x2 y2 z2 duration r g b thickness/>
Beams between Points in Space -
BeamXYZ - (Same as DrawLine but with thickness = 3.0)
<beamxyz x1 y1 z1 x2 y2 z2 t1 t2 r g b />
Beams between objects -
Beam
<beam obj_instance_name1 obj_instance_name2 t1 t2 r g b />
Beam offsets -
BeamOffset
<beamoffset y=?? />
Raises or lowers the point that beams are drawn to/from objects (as drawn via the <beam obj1 obj2 ... command).
The value offsets the attachment point in the Y-dimension (usually up/down). The beam command normally
draws to an object's defined origin point. However, many vehicle object definitions start at y=0.0
(where the tires meet the road), and work upward from there. If left alone, beams will be drawn to
the bottom of the object, and will often be obscurred by terrain. Instead, you may wish the beam to be
drawn toward the top of the vehicle, where the antenna is. Accomplish this by providing a positive Y offset.
This is a global offset.
6. Comments:
You may place comments within geometry files, or use the comments to comment-out
sections of a geometry file. The comment construct is:
<comment> whatever
...
</comment>
7. Including Files:
You may reference other files from within a geometry file.
The include construct is:
<include> filename </include>
8. Requesting Time:
This command is intended for use from live programs connected by sockets to WinFrame3D.
Often it is useful to synchronize, or have some notion as to the progress of the
viewer from a simulation which may not run in real-time. For example, the simulation
may either not want to get too far ahead, or fall behind the real-time clock which
governs the viewer. In such cases, the interactive program can ask the WinFrame3D
viewer for the time by sending the following command on the socket.
<time/>
WinFrame3D will respond with the current time in seconds since the start of the viewer
as a floating-point number character string. This is the same time reference which
governs the display (ex. T1 and T2). The string is sent back over the same socket
on which the command was received.
Example:
{
char tmpst[100];
send_soc( soc, "<time />\n"); /* Ask what time it is. */
send_soc( soc, "<nop />\n"); /* Send nop to flush socket. */
if (recv_soc( soc, tmpstr, 100 ) < 0) printf("socket error\n");
if (sscanf( &(tmpstr[3]), "%f", &Tnow )!=1) printf("error reading time (%s)\n", tmpstr);;
}
9. Fog Control -
- Normally fog is "on", it's density is set to 0.0002, and it's color is
r=0.3 g=0.3 b=0.5.
- Fog is controlled by command-line options.
- Disable fog by: -fogoff
or: -nofog
- Control fog density by increasing or decreasing the fog-density value:
-fogdensity 0.0002
- Change fog color by:
-fogcolor r g b
For example:
-fogcolor 0.3 0.3 0.5
See Other WF3d Command Line Options.
10. Background Color - <bgcolor r=0.3 g=0.3 b=0.6/>
- Normally background color is r=0.3 g=0.3 b=0.6.
- This command changes the background color to whatever you want.
- Example: <bgcolor r=0 g=0 b=0/>
(Makes black background.)
11. Adding Text -
<def_text name=? r=?, g=?, b=?, scale=? thickness=?> YOUR TEXT HERE </def_text>
... Defines a text object which can be instantiated anywhere, as many times as needed.
As a proper object, it can be moved, rotated, shifted, etc.. Do not forget to instantiate.
Example:
<def_text name=mytext1 scale=10 thickness=2 r=1 g=0 b=0> This is the test. </def_text>
<inst_obj> textitem1 mytext1 120 200 45 0 0 0 </inst_obj>
The name is required, but the other parameters are optional. Scale controls the size of
the text, and defaults to 1.0. Thickness controls the thickness or boldness, and defaults
to 1.0. The r,g,b values control the text color, range bettween 0.0 and 1.0, and default
to a lime color. The original of the front of the text defintion is set at the 0,0,0 origin,
and spaces along the positive X-axis, and z=0, with height in y, starting at y=0.
An alternate method of adding text is shown below. It places text in a single command,
but does not create a named object, so it cannot be moved or manipulated.
<put_text r=?, g=?, b=?, scale=? thickness=? x=? y=? z=? xang=? yang=? zang=?> This is the test. </put_text>
12. Camera Positioning -
You can move and point the camera via the following file or socket commands.
These can be used to pan the camera at predetermined rates and times.
<camera_move t1 t2 x, y, z />
<camera_move_rel duration x, y, z />
and
<camera_point t1 t2 x, y, z />
<camera_point_rel duration x, y, z />
13. Removing Objects -
Removing Object Instances:
<rmobj name=?? T=?? />
Name is the instance-name of the object to be removed.
T designates the time the object will be removed.
Relative times may be specified with rmobj_rel.
(The time will then be interpretted relative to when the command arrived to the viewer).
Example:
<rmobj name=tank1 T=10.5 />
<rmobj_rel name=tank1 T=3.5 />
Removing Object Definitions: (This also removes all instances automatically.)
<rmdef name=?? T=?? />
Name is the type-name of the object-definition to be removed.
T designates the time the object will be removed.
Relative times may be specified with rmdef_rel.
(The time will then be interpretted relative to when the command arrived to the viewer).
Example:
<rmdef name=Tank_T72 T=10.5 />
<rmdef_rel name=Tank_T72 T=3.5 />
14. Spheres, Cylinders, Disks, Boxes -
Several basic geometric shapes can be quickly defined through the following convenience functions.
See also: WF3d