Home » Eclipse Projects » GEF3D » Draft: org.eclipse.draw3d.geometry
|Draft: org.eclipse.draw3d.geometry [message #1736]
||Wed, 01 October 2008 13:04
|| Jens von Pilgrim
Registered: July 2009
I have created a new plug-in project "org.eclipse.draw3d.geometry" at
the SVN repository of GEF3D at FernUni Hagen (As long as GEF3D has not
passed the legal review process, it is still hosted at FernUni Hagen).
Due to server capability restrictions, the SVN (at FernUni Hagen) is
not publicly available. I'll be happy to send you the information on
your request, simply write me a mail.
This project is an internal incubator project (not the Eclipse
incubtor!) for the design and implementation of 3D geometry classes
such as Vector3f. For that, Math3D in project org.eclipse.draw3d
(.geomerty) was renamed to TempVectors.
We are trying to remove all LWJGL dependencies from o.e.draw3d (and
move them into a new project to be created called o.e.draw3d.lwjgl).
That is all GLx-methods will be replaced in future versions by methods
defined in an interface (to be created) called Graphics3D. Besides
that, we have to remove all dependencies from org.lwjgl.util.vector.
Thus we have to create our own 3D geometry classes. Both refactorings
will be done by Matthias as part of his bachelor thesis. We start with
the geometry classes and then the Graphics3D stuff will be changed.
For the geometry classes, I have created this new project. Matthias can
implement the new geometry classes in this project, we can also easily
change the design there and add test cases. When the package is
finished, it will be moved into o.e.draw3d and all LWJGL geometry
classes will be replaced by out own classes. The current project
contains some example interfaces and classes, and most important a
package-info.java documentation. In this documentation I have explained
the design of our geometry classes. This design is a result of _my_
experiences with several other geometry packages (Java3D and LWJGL) and
it is a suggestion or draft.
Math3D has been renamed in the current version since this class is
expected to be implemented again in the new version. Since the new
geometry classes are to be thread-safe, the temporary vectors are to be
removed from the geometry package (they will be used by draw3d in
future versions, too).
Currently the new project isn't used by Draw3D or GEF3D.
After a short discussion phase we will implement the geometry package.
I expect this geometry package to be designed and implemented within 3
Package org.eclipse.draw3d.geometry Description
3D geometry classes. These classes are used with GEF3D, their
functionality is very similar to Java3D's vecmath package or LWJGL's
This package contains 3D geometry classes such as
Each item is represented by
- an immutable interface I..., e.g. IVector3f
- an mutable interface with the name of the item, e.g. Vector3fImpl
- an implementation ...Impl, e.g. Vector3fImpl
All these classes implement the Serializable and Cloneable interfaces.
There is no Vector2f, class org.eclipse.draw2d.geometry.Ray should be
We do not distinguish between tuple, vector, dimension, or point.
These classes define only constructors, getters and setters, cast
operations, and some basic methods; most mathematical operations are
defined in Math3D.
Explanation: This design was chosen to avoid too much operations: In
other frameworks several variants of basically the same operation is
defined, with confusing semantics. E.g. in Java3D's vecmath,
Tuple3f.absolute() makes all values of a vector absolute,
Tuple3f.absolute(Tuple3f) sets the values of the given tuple. In
Draw2D, Point.negate() negates the values of the object itself, while
Point.getNegated() returns a new instance with negated values. In
Draw3D we simply provide a single operation, that is
Math3D.abs(IVector3f, Vector3f) (or Math3D.negate(IVector3f, Vector3f)
resp.), see below for further details.
Especially for use within Draw3D, the following classes are defined:
- SyncedVector3f -- a vector3f based on a
- BoundingBox3f (with immutable and mutable interfaces)
- SyncedBounds -- a bounding box based on
The synchronized classes only stores the delta of a 3D vector and a 2D
vector, that is the floating values of the x and y attributes and the z
The synchronized classes do not store a reference to the 2D object with
which they are synchronized. This is not possible in many situations,
since the clients may not only modify the values of the 2D object
(which would cause no problem), but the reference (of the attribute) is
also changed (see org.eclipse.draw3d.Figure3D#getPreferredSize3D() and
its implementation, especially
org.eclipse.draw2d.Figure#getPreferredSize(int, int) Thus, the synced
classes cannot implement the mutable interface!
All these upper mutable classes (and interfaces) implement the interface
- Transformable, 3D version of org.eclipse.draw2d.geometry.Translatable
Most 3D operations are defined in the following class:
- Math3D -- Basic operations (such as add, mult), and 3D versions of
operations defined in Math
The vector and matrix operations are provided as static methods. For
performance reasons, these method signatures all follow this pattern:
- static MT operation(IT inParameter1, IT inParameter2, MT outParameter)
MT is to be replaced by the immutable interface, IT by the mutable
interface respectively. Simply spoken inParameter1 and inParameter2 are
handled confirming the operation, e.g. added or multiplied, and the
result is stored in outParameter. The result is also returned by the
method. If the outParameter is null, a new instance of type T is
created. There is a trap which is handled by the operations: The
outParameter can also be passed as an inParameter. In this case it may
be possible that a value of the in/out-Parameter is overwritten by a
result value -- the methods take care that the operation is correctly
calculated by using temporary variables.
All methods and classes of this package are tested using JUnit tests.
Since all classes are defined by immutable and mutable interfaces,
classes using these 3D geometry classes should use the immutable
interface where ever possible. org.eclipse.draw2d doesn't distinguish
between immutable and mutable, thus always the mutable version is
returned and we find comments such as "callers of this method must not
modify the returned Rectangle." (from
org.eclipse.draw2d.Figure#getBounds(). This problem is solved in Draw3D
by using two kind of interfaces.
Most render frameworks such as LWJGL provide their own implementations
of 3D geometry classes. Within the Draw3D adapters (e.g.
org.eclipse.draw3d.lwjgl) special adapter classes are implemented for
easily casting a draw3d 3D geometry object into an render framework
A discussion about performance issues can be found at
http://lwjgl.org/forum/index.php/topic,2456.0.html. Here is a test I
have implemented during this discussion.
Tested were two classes (or interfaces) implementing a Vector3f
version. The first class (or interface) provides a read-only access
while the second read-write access. Additional, a static method "add"
is introduced as implemented in the current Vector3f class. Three
different design alternatives were implemented:
- Concrete: The first one (called "Concrete") implements a concrete readable
class with final getters and protected fields. The writable class extends
this class providing setters.
- Abstract: The second version (called "Abstract") implements an abstract
readable class with abstract getters and no fields. The writable class
extends this class, defining the fields (public) and implementing final
getters and setters.
- Interface: The third version (called "Interface") defines a read-only
interfaces with getters, the writable class implements this interface and
defines all fields (public) and final getters and setters.
The static add method has a similar signature in all three versions:
left and right vector are passed as read-only instances, the result is
a writable instance. If the passed result is null, a temporary variable
is constructed and returned, otherwise the result is filled.
The benchmark was executed 4 times, two times with a server VM and two
times with a client VM. For each VM, 1000000 calls of the add method
and a setter were repeated 100 and 1000 times. The result are shown
below and illustrated in the image.
On OS X 10.4, the last version using interfaces is the slowest one in
all tests. Using an abstract class is more or less as fast as using a
concrete readable class. Interestingly it is even sometimes a little
bit slower! Also surprising is the fact that in some tests (with the
server VM) creating new temporary instances (i.e. passing null as
result parameter) is faster than using an in-out parameter. The server
VM is in all tests much faster than the client VM. in some cases about
5 times. Even the slowest server tests is nearly as fast as the fastest
On other machines with different JDKs and OS, different results were
Using abstract readable base classes is the winner on OS X, but not on
all machines. It is just as fast as using concrete classes. On the
other hand, interfaces are very useful if adapters are to be
implemented and may reduce the need for copying data. Since GEF3D is
not a Gaming engine, interfaces may be good enough.
Current Time: Mon Nov 19 00:33:24 GMT 2018
Powered by FUDForum
. Page generated in 0.01579 seconds