opale.soya 0.1

Hand Book

Last update : 11/5/2000
Author : Artiste on the Web (A11W)
Problems, bugs, corrections, mail me ! Excuse the bad english...


1. Intro

No long speech, just 3D :-)

Opale.Soya is a Java 3D engine, build over OpenGL and GL4Java.
Fully object oriented, the speed is incredible and the special effects are mortal :-]

These doc isn't exhaustive because it's not a long book, but may be usefull.

2. Main packages

opale.soya All about initialisation.
opale.soya.util All that is not graphic, or that have no place elsewhere. Include math functions (Matrix, Quaternion), collections and javaBeans stuff.
opale.soya.awt AWT components, for 3D drawing, and overlay stuff.
opale.soya.font Character fonts.
opale.soya.soya2d 2D stuff, like textures, materials,...
opale.soya.soya3d 3D stuff. Big package ! In particular basic 3D elements, basic interfaces like Position, Orientation, Dimension, utilitary ojects like Point or Vector...
opale.soya.soya3d.event 3D events stuff. MoveEvent,...
opale.soya.soya3d.model Modeling stuff. In particular Shape class, Fragment,...
opale.soya.soya3d.geometry 3D geometric stuff : Sphere3D,...
opale.soya.soya3d.fx Special effects ! Sprite3D,...
opale.soya.soya3d.fx.particles Particles system. ParticlesBunch3D,...
opale.soya.soya3d.animation Animations stuff. Animation,...
opale.soya.editor Generic edition stuff, and a Bean editor. Object-specific edition class are in the same package than this object.
opale.soya.tutorial Tutorials !

3. Definitions

Animation (opale.soya.soya3d.animation.Animation) : Sequence of state for a given world (including all elements the world contains). Animation is created from several states, and then it is posible to interpolate between them.

Animations (opale.soya.soya3d.animation.Animations) : Collection of animation. Usefull to regroup and save several animation (of a same character,...), because one animation describe only one movement.

Camera (opale.soya.soya3d.Camera3D) : A 3D graphical element used as renderer : interface between a world (in 3D) and a rendering surface (AWT component so a 2D surface).

Collection (opale.soya.util.Collection) : A group of object. Opale.Soya use its own collection class, that extends the one of Java (java.util.Collection).

Element (opale.soya.soya3d.Element3D) : A 3D element, that can be added in a world (opale.soya.soya3d.World3D). Basic elements are volumes, worlds, lights and cameras. All 3D element class name end by "3D".

Environment (opale.soya.soya3d.Environment3D) : A world, with environmental properties, like fog, ambiant lighting...

Fragmented shape (opale.soya.soya3d.model.FragmentedShape) : A Shape created by addiing fragmented shape elements : triangles, quads... A fragmented shape is a collection of fragmented shape elements.

Fragmented shape element (opale.soya.soya3d.model.FragmentedShapeElement) : Objects to add in a fragmented shape, for example triangles, quadrangles (quad). For example a cube is made from 6 quads.

Graphical element (opale.soya.soya3d.GraphicalElement3D) : A graphical 3D element. Most of 3D elements are graphical.

Material (opale.soya.soya2d.Material) : A material is an object that regroup all the surface properties of an object : colors (2 colors : diffuse color and specular color), shininess,... including texture. Materials can be shared between many objects (many shapes, ...).

Rendering surface (opale.soya.awt.RenderingSurface) : A 2D surface where Opale.Soya can render a 3D view, often an AWT component (opale.soya.awt.RenderingCanvas).

Shape (opale.soya.soya3d.model.Shape) : A shape (often geometric) that can be set to a volume, like a cube,... Most of the shapes are fragmented shapes (see this). Shapes can be shared between many volumes.

Texture (opale.soya.soya2d.Texture) : 2D bitmap image placed on a 3D surface.

Volume (opale.soya.soya3d.Volume3D) : A 3D graphical element that draws a shape : something to see.

World (opale.soya.soya3d.World3D) : A 3D element (actually a volume and so a 3D graphical element) that can contains other 3D elements (so it's also a collection).

4. AWT component

Opale.Soya draws in a rendering surface (opale.soya.awt.RenderingSurface), often an AWT component (opale.soya.awt.RenderingCanvas, and opale.soya.awt.RenderingFrame : an AWT frame with a rendering canvas : this is the one used in the tutorials).
opale.soya.awt.RenderingSurface extends the normal canvas; The only important property is renderer. This property must refer to the renderer, generally the camera (myRenderingCanvas.setRenderer(myCamera)).

Overlay (opale.soya.awt.Overlay) : An overlay is a surface placed over the 3D. It can be text, image, 3D, ...

See tutorial 1.

5. Hierarchy

Opale.Soya represents 3D worlds in a hierarchical way, like a tree.
The base (the root) is a world, with no parent (this root world has not been added in another world); it is called the "root world".
The root world contains different elements (as many as you want, because a world is a collection of elements), including other worlds, and those ones can also contain worlds...
If you want to render something, you need, somewhere in the root world or in a world it contains, at least : a camera and something to see (a volume,...).
Each element has a parent world, that correspond to its parent property (getParent() method), except the "root world", and its parent is null. The isInside(World3D) method of an element is a convenient way to know if this element is in the world (= if this world is its parent or if the element's parent is in the world).

See tutorials 1 and 5.

Name : Each element (opale.soya.soya3d.Element3D) has a name (name property). This name can be use to identify or retrieve the element. Many elements can share the same name.
Several methods allow to recover elements in world from their name : element(name) return the first element of the desired name, elements(name) return an iterator of all the elements of the given name and search(name) is similar but accept willcards ("*", "?",...). All these methods have a recursive version (elementRecursive, elementsRecursive, searchRecursive) that search in the given world and all the worlds it contains.

6. Manipulation of graphical elements

All the basic elements of Opale.Soya, and most of the other, are graphical elements, like worlds, volumes, lights, cameras,... A graphical element corresponds to a local coordinates system, and implements at least the following 4 interfaces (from package opale.soya.soya3d):

CoordSyst (coordinates system) : All graphical element have a local frame. The x vector x of this frame is the right direction, the y vector the up direction and the z vector the back direction, so -z is the front direction.

Position : This interface has the following properties : x, y and z, that correspond to its coordinates. Those coordinates are defined in the parent coordinates sytem (that is to say in parent world coordinates, the one that contains the element).
The move(*) methods move the element, the addVector(vector) method translate it.

Orientation : The element has 3 vectors : x, y and z.
The rotate(*) methods rotate the element around the given axis. rotateLateral(angle) rotate around the y axis, rotateVertical(angle) around the x axis and rotateIncline(angle) around the z axis. The axis used by these 3 methods depend of the rotationType property; if it is set to ROTATION_TYPE_INTERNAL (default value), the element's axis are used; if the property is ROTATION_TYPE_EXTERNAL, the parent world's axis are used.
The lookAt(*) methods target the element's front direction (= -z) toward the given position or in the given direction (if the argument is a vector).

Dimension : The element has the following properties : width, height and depth, that 0correspond to its dimensions according to the element's x, y and z axis.
The scale(*) methods magnify or minify the element.


Point and Vector objects (opale.soya.soya3d.Point, opale.soya.soya3d.Vector) : These objects are not elements and so they cannot be added into a world; they are only used for computation but they implement the Position interface. For example the addVector(Vector) method translates a point or performs a vectorial addition (if it is called on a point or a vector).
Opale.Soya define a point or a vector by its 3 coordinates (x, y, z properties) AND a reference to the coordinates system in whitch those coordinates are defined (coordSyst property). Notice that this property is readable and writable; the setCoordSyst(CoordSyst) method make a frame conversion and the x, y and z coordinates are converted in the new system.
If the move(Position) method of a Position is called with a Position object as argument, and if the position argument is not defined in the same coordinates system, a coordinates conversion is automatically performed, except if the coordSyst property is null (in this case, no conversion are performed).
Example :
myVolume.move(new Point(0f, 0f, -1f, myVolume)); moves myVolume relatively, and advances it of 1 step.
myVolume.move(new Point(0f, 0f, -1f, myVolume.getParent())); move myVolume absolutely, and positions it to (0, 0, 1) in its parent local frame.

7. Modeling - 2D

In Opale.Soya, quite all the 2D surface properties of a 3D shape depends of materials (opale.soya.soya2d.Material). Materials are created and then set to 3D shape.

Textures (opale.soya.soya2d.Texture and its sub-classes) : Textures are considered as material property (unlike in OpenGL or many other 3D engine). There are many classes of textures : TextureRGB for non-transparent ones, TextureRGBM for simple transparent ones (true/false transparency; no semi-transparent or translucid pixels) and TextureRGBA for the transparent one (semi-transparent : with an alpha channel).
Textures objects are created from image files (one for the texture, and another for the mask/the apha channel for TextureRGBM and TextureRGBA); supported formats are the ones supported by java (gif, jpeg,...).

Colors : Each material has 2 colors : the normal one (diffuseColor) and the specular one (specularColor, often white).

Shininess : It represents how the surface is shiny, between 0 and 1. Metallic surfaces are near 0, and plastic surfaces are near 1.

There is many other properties, but they are rather specific, and you have to experiment them by yourself...

8. Modeling - 3D

In Opale.Soya, most of the rendered 3D is volumes (except special effects). What a volume does is just drawing a shape. So you must now learn to create and use shapes.
Shape is an abstract class; the concrete class that corresponds is fragmented shape (opale.soya.soya3d.model.FragmentedShape). A fragmented shape is a shape created from several piece : fragmented shape elements.
These fragmented shape elements are mainly triangles, quads, even if many other can be used (sphere,...). 6 quads can make a cube. Each quad can have different properties : for example, the material property defines the surface look (texture,...).
Complex shapes can need an important number of faces (= triangles or quads). That's why Opale.Soya automaticaly converts and assembles the fragmented shape elements in fragments, less numerous and drawn quickier. The conversion is automatic, nothing must be done !

Turn a world to a shape : An other way, usefull for big or repetitive shapes (like a game level...), is to create a world that corresponds to what's you want (with volumes and other shapes), and to turn it to a shape with the toShape() method. The returned shape is a fragmented shape as any other.

Static lights : The number of lights is limited by OpenGL (often 8 maxi) and also by the computation time they need. The "turn a world to shape" technic can create static lighting in a shape (There is no limit to the number of static lights, and they need quite no calculation) : when a world is converted to a shape, all the lights it contains and whose static property is true are applied staticaly to the shape.
See the chapter about lighting for the other effects of the static property.

Faces visibility : Faces (opale.soya.soya3d.model.Face), like triangles or quads, can have both sides visible or only one. The second possibility can make a performance boost (less face to draw). Opale.Soya is able to determines automaticaly the interior or the exterior of a closed shape, and to show only the interior or exterior part.
See the visibility property of a face.

Optimisation : The optimize() method of a shape optimize the shape (this method can take a while).

See tutorials 2 for modeling.

As soon as you have a shape, you can create a volume, set its shape property to your shape (setShape(shape) method) and add it to a world (add(element) method). The shape only describes the geometry; the volume describe position, orientation and dimensions. It is possible to use the same shape in many volumes.

9. Lighting

Opale.Soya has 3 kinds of lighting :
Ambiant lighting : The easier. It affects all objects, independently of their position/orientation. Ambiant lighting is defined in the environment object; this object is very similar to a world with a few additionnal property. The ambiantColor property (setAmbiantColor(red, green, blue) method) is used to define the ambiant lighting.
See tutorial 2.

Lighting with lights : The more common. The light graphical element is a light source. There are 3 kinds of light sources (type property) : the point (a luminous point : a torch,...), the directionnal (like the sun,...) and the spot (a luminous cone : a projector,...). As lights are graphical elements, it is possible to move or rotate them.
The lights properties are : The light color.
The light attenuation : constantAttenuation, linearAttenuation and quadraticAttenuation. The first is a distance-independant atténuation, the seconds depend of the distance and the third depends of the distance squarred. Attenuation has no effect on directionnal lights.
For a spot-light, spotAngle and spotExponent represents the angle of the cone, and the difference of intensity between the center and the border of the spot.

Static lighting : The more complex, the more limited but the quickier... See th 3D modeling chapter to learn how to create static lit shapes.
Static lights cannot change or move in any manner.
If the static property of a light is true, the light is considered as static and used when creating a shape from a world that contains the light; however the light no longer lit static-lit shapes (It is supposed that it has already been applied at the shape creation). Non-static-lit shapes are normaly, dynamicaly lit by the light.
The pureStatic property, if set to true, define a pure static light : these lights are taken into account for creating static-lit shapes, but they don't lit any non-static shapes.

10. Rendering

This chapter explains how Opale.Soya renders 3D. Reading this is not needed to use Opale.Soya ! But it can be interesting if you want to extends Opale.Soya's classes.

The rendering begins by the collect of all the Drawable (an interface for all objects that can draw 3D). This collect is performed by a DrawableCollector; matrixes are also computed at this time. Collected drawables are sorted by material, in order to minimise OpenGL calls while rendering.
Then the rendering is done, and the drawables are drawn (draw(...) method), in a material-order.

The full processus is obviously more complex...

11. Environment

An environment (opale.soya.soya3d.Environment3D) is a world with the following additionnal properties :

Background color (backgroundColor property).

Background image (backgroundImage property) : Use here a texture object as an image.

Fog : The fog has the same color of the backgroundColor. Fog is used only if the fogEnabled property is vrai. fogType, fogDensity (if fogType is exponentiel) or fogStart, fogEnd (if fogType is linear) modify the fog intensity.

Notice than, at this time, the environment properties of the environment that contains the camera is applied to all the 3D scene.

12. Animations

Opale.soya includes an animation system that is able to interpolate between 2 states of a world (including all the graphical elements it contains : like a character, ...).
Animation (opale.soya.soya3d.animation.Animation) : An animation represents a sequence of states, each one corresponding to a time.

How to create an animation : Very easy : create an animation object, set to your world the key state of your animation, then enter in the animation (addCurrentState(time, world) method). For example if you want an animation of a volume that move from (0, 0, 0) to (1, 0, 0) between time 0 and 1, set this volume to (0, 0, 0) (move(x, y, z)), call addCurrentState(0, myScene), then set it to (1, 0, 0) and call addCurrentState(1, myScene).

How to play an animation : Define the animation property of the world, then its animationTime property controls the current state. In the previous example, myScene.setAnimationTime(0) move the volume to (0, 0, 0), myScene.setAnimationTime(1) move it to (1, 0, 0) and myScene.setAnimationTime(0.5) move it to (0.5, 0, 0).

Cyclic animation : An animation is cyclic if it ends by returning to the first state (so you can play another cycle). In this case, the cyclicLap property represents the time between the last and the first state (if the animation is not cyclic, cyclicLap is 0).

Animations (opale.soya.soya3d.animation.Animations) : Animations is a collection of animation (without "s" !). This object is usefull to group and manage all the animation of a world (for example the "advance", "goBack", "turn", ... animation of a character). Animations can be saved in a specific path.
If the animations property of a world has been specified, the setAnimationFromAnimations(name) method of the world define its animation from the animations collection, to the animation with the desired name.

13. Beans and events

Most of Opale.Soya objects (like 3D elements) are javaBeans.
Warning ! Contrary to a common idea, Beans are not limited to "visual" components, like AWT or Swing ! Any object can be (and is) a Bean (cf java.beans package doc).
The integrated Beans editor (opale.soya.editor) can edit a property list from any Bean :
Object bean = [...];
opale.soya.editor.Editor.edit(bean);

Opale.Soya uses an eventsystem very close to AWT and javaBeans one.
All Beans have the addPropertyChangeListener and removePropertyChangeListener methods, in order to add or remove an event listener (java.beans.PropertyChangeListener). The propertyChange method of the listener(s) will be called whenever a bean's property will be modified (by a set*(*) method).

Move, orientate or resize events : If, for example, the z property of a 3D graphical element is modified (with setX(float)), a java.beans.PropertyChangeEvent is created and sent to the propertyChange method of the listener(s), with "z" as property name (getPropertyName()).
However, it is often more interesting to know that the element has been moved, rather than to know that its x, y or z property has changed. In this case, just check if the event object is an instance of opale.soya.soya3d.event.MoveEvent. Similarly, there are opale.soya.soya3d.event.OrientateEvent when an element is rotated, and opale.soya.soya3d.event.ResizeEvent when it is resized.

Collection events : Opale.Soya use the opale.soya.util.Collection interface to represents collections; this interface extends the java.util.Collection collection by adding support for object addition or removment (add/remove event). In particular, those events are use by worlds (that implement opale.soya.util.Collection).

Sub-events : Sub-events are events generated by the objects of a collection, and not by the collection itself. Worlds can send sub-events for all the elements they contain.
To add a sub-events listener, call the addSubPropertyChangeListener or addSubCollectionListener listener (according to the desired kind of events : change events or collection events). The listeners are the same than normal events' listeners.

See tutorials 5 and 6 about events.

14. Files and file formats

Most of Opale.Soya objects can be saved into files. Standard serialization is always used.
Some objects are saved in files with exotic extensions (though the file format is always the same) :
.material opale.soya.soya2d.Material
.shape opale.soya.soya3d.modeling.Shape
.animations opale.soya.soya3d.animation.Animations
Any other file use the .ser extension.

Object's path : Some classes of objects can regroup their files in a path especially designed for this : all the objects that implement the opale.soya.util.StoredInPathObject interface : material, shape, animations,...
So it is possible to load or to recover those objects just by their name, with the get static method of their class (opale.soya.soya3d.model.Shape.get("myShape"),...). If an object of this class and with the given name already exists, it is returned, else it is loaded from the path.
Each of the previously quoted classes can have its own path; so there are a material path, a shape path and an animations path (opale.soya.soya3d.model.Shape.path field,...). Those paths must be defined at the initialization of your app (opale.soya.soya3d.model.Shape.setPath("/home/me/shapes/"),...).
Path are usefull, because those objects are often used by other (materials by shapes, shapes by volumes, animations by worlds...). When a complex object, like a world, is saved, the materials, the shapes and the animations... it references and uses are not saved with the world if they have a name; only their name is written, in order to recover it when loading the file, as soon as the paths are well-defined.
In this case the objects can be shared (because the get static method return the same object if the same name is given).
At the contrary, if those objects have no name, they are directly saved with the world. That can increase the size of the file and reduice performances (if the objects were used by several worlds) but avoid dependancies (all the world is in a unique file).

15. Editors

Opale.Soya includes lots of editors (3D editor and Beans editor) !
For more info about them, see the Opale.Soya editor handbook.

16. Tutorials

Opale.Soya has tutorials in opale.soya.tutorial.
The lessons before the 100th are about basic stuff, and other about special effects and and "less importants" stuff.
Don't worry, there are not 100 lessons :-)

There is still lots to say but...
That's all folks !

Artiste on the Web (A11W)