A short Shapes Tutorial for Raja


Here is a quick tutorial on shapes in Raja. Actually, this page is for developers. A simple user won't find anything interesting in it. So it must be written somewhere:

Only for l33t ! :-)

Shape3D

The shapes are 3D objects that we want to draw by ray-tracing.

   Shape3D (I)
      |
      +--Solid (I)
      | 
      +--Form (I)
      |
      +--TexturedForm (I)
   

As you see on the "magnificent" ascii art figure, the Shape3D is an interface (I) which all the 3D Object implement. It contains only three methods:

* boolean contains(Point3D p)
Give true if p is in the shape OR on the surface of it, and false otherwise.

* boolean strictlyContains(Point3D p)
Give true only if p is strictly in the shape.

* boolean intersects(LightRay r)
Give true if r hit the shape, and false otherwise.

Well, the first problem is to define a simple geometrical form, as a sphere, a plane or anything else. So let's jump to Form.

Form

    Form (I)
      |
      +--BasicForm (A)
             |
             +--Plane
             |
             +--Sphere
             |
             +...
   

A Form is an interface which represent a geometric form, but we assume that it will contain information only about the general geometry of the shape. It is implemented only by BasicForm for the moment but we can imagine to add more complex Forms like gaseous, fractal, or random Forms. Form extends Shape3D with the following intersect method:

* LocaGeometry intersection(Ray r)
It is to say that when the ray r is hitting the shape, then the method is returning a LocaGeometry, or null otherwise.

A LocaGeometry, as we will see further is a way to handle the local geometry of the intersection. We hide in it the normal and the coordinates of the intersection.

Let's see BasicForm now !

BasicForm

So a BasicForm is just a simple geometric form as sphere, plane, cone, cylinder, torus, ... Actually we can define plenty of them ! We just have to know the equation of it and how to solve the intersection with a ray. It implements the intersect method for the geometric form we are considering.

Ok, what's next ? Well we have to consider the texture of the shape. So, let now jump to TexturedForm.

TexturedForm

   TexturedForm (I)
         |
         +--BasicTexturedForm
         |
         +--Complement
         |
         +--CompositeForm (A)
                 |
                 +--Intersection
                 |
                 +--Union
   

TexturedForm is an Interface too. It's just a Shape3D with a Texture linked to it. It extends Shape3D with the following intersect method:

* TexturedLocalGeometry intersection(Ray r)
It is to say that when the ray r is hitting the shape, then the method is returning a TexturedLocalGeometry, or null otherwise.

So the only difference with Form is that the intersect method returns a TexturedLocalGeometry instead of a (non textured) LocaGeometry.

We have several flavor of TexturedForms. We can have a basic one (BasicTexturedForm) which is composed of a single form. We can have the complement of a textured form (Complement). And, finally, we can put several textured forms together either in a Union, either in an Intersection of the forms.

Ok, now what is exactly a TexturedLocalGeometry ?

Let's see.

   Point3D
      |
      +--LocalGeometry (A)
              |
              +--TexturedLocalGeometry (A)
                         |
                         +--SolidLocalGeometry
   

Doh, I feel you're in need of some more details about this, aren't you ?

Point3D

Ok, everything is coming from Point3D. Basically a Point3D is just three coordinates (x,y,z). The methods are:

* static double distance(Point3D p1, Point3D p2)
Computes the distance between the two specified Point3D.

* static double distanceSq(Point3D p1, Point3D p2)
Computes the square of the distance between the two specified Point3D.

* void translate(Vector3D v)
Translates this Point3D by the specified Vector3D.

LocalGeometry

Hey, I said we have to define it later, remember ? :-)

    Point3D
       |
       +--LocalGeometry (A)
    

LocaGeometry is an abstract class to handle a point with a normal (or it can be seen as a tangent plane at this point) attached to it. With this structure you can use only the informations that you need without requiring the whole shape when you get the intersection. In a sense you handle only the local geometry of the intersection (this explains the name).

LocaGeometry has an extra abstract method:

* abstract Vector3D getNormal()
Returns the outer normal of the Form at this point.

TexturedLocalGeometry

    Point3D
      |
      +--LocalGeometry (A)
              |
              +--TexturedLocalGeometry (A)
    

The class TexturedLocalGeometry adds two extra abstract methods to get the texture of the shape:

* abstract LocalTexture getInLocalTexture()
Returns the inner texture of the shape.

* abstract LocalTexture getOutLocalTexture()
Returns the outer texture of the shape.

LocalTexture

LocalTexture is just a structure defining the local material properties of the form. It contains the local:

Here comes the SolidLocalGeometry !

SolidLocalGeometry

    Point3D
      |
      +--LocalGeometry (A)
              |
              +--TexturedLocalGeometry (A)
                         |
                         +--SolidLocalGeometry
   

This class introduces the notion of refraction. Actually we didn't need this before reaching this point. The extra methods are:

* double getInRefractiveIndex()
Return the inner refractive index.

* double getOutRefractiveIndex()
Return the outer refractive index.

* boolean inVolumeUndefined()
Return true if the inner Volume is defined and false otherwise.

* boolean outVolumeUndefined()
Return true if the outer Volume is defined and false otherwise.

To understand the goal of the methods inVolumeUndefined and outVolumeUndefined, consider the intersection of a Ray with a Sphere, but with the ray travelling inside the Sphere. At the intersection point, the inner refractive index is the refractive index of the Sphere (since the Ray is "leaving" the Sphere at the intersection). However, the outer refractive index is not known by the Sphere, and hence the Sphere will assign it to undefined.

If this Sphere is part of an Aggregate, then the Aggregate will check whether this intersection is inside another solid of the Aggregate, and if this is the case it will assign the outer refractive index (at the intersection) to the refractive index of that container Solid. Finally, when the intersection is returned from the main Aggregate of the Scene, we check whether the outer (resp. inner) Volume is undefined, and in that case we use the ambiant refractive index instead.

But, now what about the Volume ?

Volume

Volume have been introduced to handle the concept of transparent objects. We tried to be as abstract as possible to allows to define object with a refractive index that can continuously vary on the volume. I don't know if it is possible to compute the trajectory of a light ray on those object but that could be funny ! :-)

So, basically a Volume give the refractive index of a 3D object. It has only one method which is:

* double refractiveIndex(Point3D p)
Return the refractive index at the point p.

But how the Volume and the Shape3D are related ?

Let's do some ascii art again ! :-)

    Shape3D (I)          Volume (I)
      |                    |
      |                    +--IsotropicVolume
      |                    |
      +---------+----------+
                |
                +--Solid (I)
                     |
                     +--BasicSolid
                     |
                     +--Aggregate
   

Hey, not bad ! Is there some ascii art contest ? I really believe I can compete ! ;-)

So, as the nice figure show it, the class Solid is an implementation of both Shape3D and Volume. Actually, all the Raja scenes use Solid everywhere. Because it is defined by a (set of) TexturedForm(s) and by a (set of) Volume(s).

Ok, but we want to be able to build some more complex solids than simply a shape. We want to manage Aggregate. That's why we defined the class BasicSolid which is only one Solid (aka one TexturedForm and one Volume) and the class Aggregate. But Aggregate is slightly more complex, let talk about it.

Aggregate

Actually, an Aggregate is just a list of BasicSolids with a DirectedGraph.

Ok, you probably can figure that the list of BasicSolid is just all the Solid which are in this Aggregate. But what the Hell is this DirectedGraph ?

Remember that we have to deal with transparency ! So when several objects are transparent in an Aggregate and that their intersection is not empty, then we have a problem !

On the intersection what refractive index must we take in account ?

How clever we are !

We just defined a DirectedGraph that can say the priority of each transparent object on the others !

Well, but there is still something puzzling me ! Did we forget some details ?

Let's see, we have the textured forms, the refractive index, the intersection, union or complement, the priority of the transparent Volumes on the others...

Yes, of course ! I forgot to define what a Texture is !

Texture

Ok, let be more specific about the textures now. There is one class Texture:

   Texture (I)
      |
      +--PlainTexture
   

It contains one method which is:

* LocalTexture getLocalTexture(Point3D p)
Return the LocalTexture for a particular Point3D p from the Texture.

Actually when you call a method getInLocalTexture or getOutLocalTexture you call the method getLocalTexture on the Texture (in or out) linked to the shape. The Texture contains the way to fill all the fields of a LocalTexture according to the Point3D we are considering (see the description of LocalTexture above).

Well, now I think we have completed this tour of Raja Objects ! Ok, let see now the complete class hierarchy of shapes.

Get ready,...

START !

                                 
   Shape3D (I)          Volume (I)
      |                    |
      |                    +--IsotropicVolume
      |                    |
      +---------+----------+
      |         |
      |         +--Solid (I)
      |              |
      |              +--BasicSolid
      |              |
      |              +--Aggregate
      |
      +--Form (I)
      |    |
      |    +--BasicForm (A)
      |          |
      |          +--Plane
      |          |
      |          +--Sphere
      |          |
      |          +...
      |
      +--TexturedForm (I)
              |
              +--BasicTexturedForm
              |
              +--Complement
              |
              +--CompositeForm (A)
                      |
                      +--Intersection
                      |
                      +--Union
   

I must get an award on ascii art for this ! Don't you think ? :o)

And that's all folks !



Comments to Webmaster
Thu Jan 16th 2003, 06:30:13 PM