Microbe3D.library: Alain Thellier - Paris - FRANCE - 2011-2015

Bump-mapping on OS4 + playing a.bvh animation

Colored Lights + bones
Microbe3D: Micro 3D Engine for Wavefront .OBJ files using Warp3D 
Microbe3D is a layer above Warp3D. This simplifies the use of 3D

Why Microbe3D?
Microbe3D is a small engine that displays directly Wavefront .OBJ 3D files.
MICROBE3D means "MICRo. OBj Engine for warp3D" 

The general philosophy is "Keep it simple and still make it simpler" 
0) Microbe 3D is fast and beautiful 
1) No need to know hundreds of functions as with OpenGL
2) No need to try to understand how Warp3D may work
3) No need to set lots of "States" to obtain a particular effect 
4) OpenGL is "drawing" oriented: you always draw faces, points, colors, etc. .. 
But Microbe3D is 3D-Object oriented: just load the 3D Objects in the Scene then draw the whole Scene with a single function 
5) If Microbe3D contains 50 functions so my goal is "Can it be done with 45 functions to make it easier?" 
6) So when a function does something similar to another, I try to make a generic function that can handle different "Things" 
7) No need to know what you are manipulating: all structures are private. The developer only handles generic pointers (APTR = a memory address) 
8) When you call a function with a pointer to a "Thing", then Microbe3D guesses automatically what this "Thing" is (Object, Scene, Light, Instance) 
9) Microbe3D is 3D-Object oriented but you do not draw or build your 3D Objects in Microbe3D = just create them with your favorite 3D applications (like Blender) 
Then export as .OBJ. .MTL JPG 
[Blender Menu : File/Export/Wavefront(.OBJ)] 
10) Now (August 2014) Microbe3D has 43 fnctions, but in fact you'll need less than 10 Microbe3D functions to make a 3D program that works 
11) With Microbe3D you can easily add a moving 3D-Object (rotating logo, etc...) to your Amiga applications
12) But Microbe3D is still a small 3D engine so do not expect to create "Quake" with it
13) You can write Microbe3D programs with Arexx
 

Microbe3D: Micro Moteur 3D pour les fichiers Wavefront .OBJ utilisant Warp3D
Microbe3D est une couche par dessus Warp3D. Elle simplifie l'utilisation de la 3D 

Pourquoi Microbe3D?
Microbe3D est un petit moteur 3D qui affiche directement des fichiers Wavefront .OBJ
MICROBE3D veut dire "MICRo .OBj Engine for warp3D" (Micro Moteur Warp3D pour fichiers .OBJ)

La philosophie générale est "Faire simple et toujours plus simple"
0) Microbe 3D est rapide et beau
1) Pas besoin de connaitre des centaines de fonctions comme avec OpenGL
2) Pas besoin  d'essayer de comprendre comment peut donc fonctionner Warp3D
3) Pas besoin de mettre plein de "States" pour obtenir un effet particulier
4) OpenGL est  orienté "traçage" : En parmanence vous tracez des faces, des points, des couleurs, etc ..
Mais Microbe3D est orienté objet 3D : il suffit de charger un objet 3D dans la Scene puis de tracer la Scene entière avec une seule fonction
5) Si Microbe3D contient 40 fonctions alors mon but est "Peut-il être fait avec 35 fonctions pour le rendre encore plus simple?"
6) Ainsi quand une fonction fait quelque chose de similaire à une autre, j'essaye de faire une fonction générique qui pourrait traiter différentes "Things" (choses)
7) Pas besoin de savoir ce que vous manipulez: toutes les structures sont privées. Ainsi le programmeur manipule seulement des pointeurs génériques (APTR  = une adresse mémoire)
8) Lorsque vous appelez une fonction avec un pointeur sur une "Thing", alors Microbe3D devinera automatiquement ce qu'est cette "Thing"  (Objet, Scene, Light, Instance)
9) Microbe3D est orienté objet 3D vous ne dessinez pas ni construisez vos objets 3D dans Microbe3D = il suffit de les créer avec vos applications 3D favorites  (comme Blender)
Puis de les exporter sous  .OBJ. .MTL JPG
  [Menu Blender: Fichier/Exporter/Wavefront (  .OBJ)]
10) Maintenant (Mars 2014) Microbe3D a 43 fonctions, mais en fait, vous aurez besoin de moins de 10 fonctions Microbe3D pour faire un programme 3D qui marche 
11) Avec Microbe3D vous pouvez facilement ajouter un objet 3D  en mouvement (logo tournant, etc ..) à vos applications Amiga
12) Mais Microbe3D est encore un petit moteur 3D alors ne vous attendez à créer "Quake" avec ;-)
13) one peut écrire des programmes  Microbe3D en  Arexx


   Microbe3D & Wazp3D vidéos on YouTube
   Microbe3D & Wazp3D en vidéos sur YouTube
Here it is what do the demos
 demo-Simpler:  simple prog load/turn a logo
 demo-window: same but in a part of a personal window
 demo-clock: load objects, creates hierarchical bodies animates according to the current time
 demo-harm: load objects, creates hierarchical bodies such as an arm, anime it with the mouse and key i
 demo-map: load objects, creates a map, fills tiles like a chessboard
 demo-map-heli: same prog jusr adds an helicopter object above and anime mouse
 demo-boing:  handmade creation of an object with microbe3D (a boing) turns it, displays a background
 demo-bones: handmade creation of bones on an object ,creates hierarchical bodies like a snake, anime it with mouse button and key i
 demo-fonts: from one object and 4 textures creates full set of objects (one letter per object), put the text in a map and anime it
 demo-view: Object viewer : load/ edit / modify / save 3D objects and motion capture

 demo-arexx1: same as demo-Simpler but in arexx
 demo-arexx2: Load a bear object, creates two instances, animate it with a motion-capture
 demo-arexx2: Load a bimbo object, creates one instance, and changes the positions of 2 lights, animate all with a motion-capture
 demo-arexx4: same as demo-map but in arexx

 data/-Add-AmigaLogo.rexx same as demo-simpler but as an arexx plugin executable from demo-view

Voici ce que font les demos
demo-simpler: charge/tourne un logo = prog simple
demo-window: idem mais dans une partie d'une fenetre perso 
demo-clock: charge des objets, crée des instances hierarchiques, les anime selon l'heure courante
demo-harm: charge des objets, crée des instances hierarchiques comme un bras, l'anime avec la souris et touche i
demo-map: charge des objets,crée une map, la remplit de tiles comme un damier
demo-map-heli: idem ajoute un objet helicoptere au dessus et l'anime avec la souris
demo-boing: crée à la main un objet avec microbe3D (un boing) le tourne, affiche un background
demo-bones: crée à la main des bones sur un objet crée des instances hierarchiques comme un serpent, l'anime avec la souris et touche i
demo-fonts: à partir d'un seul objet et 4 textures crée plein d'objets (un objet par lettre), les mets dans une map selon un texte, anime
demo-view: charge/edite/modifie/sauve des objets 3D et motion-capture

demo-arexx1: idem demo-simpler
demo-arexx2: charge un objet ours, en crée 2 instances, les anime avec 2 motion-captures
demo-arexx2: charge un objet bimbo, en crée 1 instance, la positionne et change 2 lights,l'anime avec une motion capture
demo-arexx4: idem demo-map

data/-Add-AmigaLogo.rexx idem que demo-simpler mais comme plugin executable depuis demo-view
 

First Microbe3D program

int main(int argc, char *argv[]) 

APTR Scene; 
APTR Object; 
APTR Instance; 
ULONG VanillaKey; 

Scene =U3D_EasyOpenScene("Amiga Logo",480,480);   /* open a scene in a 480x480 pixels window */ 

Object=U3D_Read(Scene,"data/AmiLogo.obj");    /* load a 3D object */ 
if(Object==NULL) goto panic;      /* if not loaded then exit */ 

Instance=U3D_AddInstance(Scene,Object,"Instance");   /* add to scene */ 

printf(" Esc for quit \n"); 
while(VanillaKey!=27) 

U3D_Rotate(Instance,3.0,1.0,4.0,U3D_CHANGE);    /* rotate logo */ 
U3D_DrawScene(Scene);       /* draw all */ 
VanillaKey =U3D_QueryValue(Scene,U3D_VANILLAKEY); /* get keyboard value */ 

panic: 
U3D_Delete(Scene);  /* close all */ 
return 0; 

Premier programme Microbe3D

int main(int argc, char *argv[])
{
APTR  Scene;
APTR  Objet;
APTR  Instance;
ULONG VanillaKey;

 Scene =U3D_EasyOpenScene("Amiga Logo",480,480);  /* open a scene in a 480x480 pixels window */

 Objet=U3D_Read(Scene,"data/AmiLogo.obj");   /* load a 3D object */
 if(Objet==NULL) goto panic;     /* if not loaded then exit */

 Instance=U3D_AddInstance(Scene,Objet,"Instance");  /* add to scene */

 printf(" Esc for quit \n");
 while(VanillaKey!=27)
 {
  U3D_Rotate(Instance,3.0,1.0,4.0,U3D_CHANGE);   /* rotate logo */
  U3D_DrawScene(Scene);      /* draw all */
  VanillaKey =U3D_QueryValue(Scene,U3D_VANILLAKEY); /* get keyboard value */
 }
panic:
 U3D_Delete(Scene);      /* close all */
 return 0;

}

Tutorial

Scene
Everything you load or create is stored in a Scene (something like a GL context or Warp3D context ....) 
The Scene also includes an Amiga window and an Amiga bitmap which is used as a back buffer. 
So the first step to start a program is to open a Microbe3D Scene 
Scene is necessary as a parameter for various Microbe3D functions 
But some functions do not need to specify the Scene like 
U3D_Write (MyObject, "myObject.obj"); 
as MyObject is already defined in a particular Scene 

Object
Microbe3D uses 3D Objects loaded from .OBJ/;GEO/.LWO files only 
But there are many converters available on the Internet that can convert different 3D formats to the .OBJ format 
You can use Blender to create or import/convert/export Objects 
Blender menu: File/Export/Wavefront (.OBJ) 

Material
Microbe3D uses standard 3D Materials loaded from .MTL files 
So you can have Materials like copper, marble, glass .... . 
Microbe3D can't directly manipulate nor create materials. 
But just use any 3D application (such as Blender) to create materials and then load them from a .MTL file 

Group
Group is a list of triangles using a material. 
So a Group defines the part of an Object using a specific material. 
Microbe3D can not directly manipulate Groups. 
But just use any 3D application (such as Blender) to create Groups, and then load them from the .OBJ file 

Light
There are 8 lights in the Scene that can be disabled/enabled/modified as you want 
The lighting in Microbe3D follows (mostly) the OpenGL rules.

Instance
This is something (Thing) that is displayed on the Scene and can be moved/rotated/scaled. 
Instances usually display Objects 
MyObject = U3D_Read (Scene, "eagle.obj") /* loaded into memory * / 
Instance = U3D_AddInstance (Scene, MyObject, "MyInstance") /* displayed on screen * / 
You can have multiple Instances of the same Object: so you can display the same Object in different sizes and positions 
Maps and Instances are the only things really displayed in a Scene
Instances behave like mechanical axis (or joints).
If an Object (or a Map) is attached to an Instance then the Instance is visible (eg robot arm)
But we can also just put Instances attached hierarchically to each other so (most without Objet3D) allowing to create a more complex movement
Then the 3 actions (U3D_Rotate/Translate/Scale) only move those axes 
v33: On peut affecter une Motion-Capture à une Instance

 

Tutoriel

Scene
Tout ce que vous chargez ou créez est stocké dans une Scene (un peu comme un contexte GL  ou Warp3D ....)
La Scene comprend également une fenêtre Amiga et une bitmap Amiga qui est utilisé comme back buffer.
Donc la première étape pour démarrer un programme Microbe3D est d'ouvrir une Scene
Scene est alors nécessaire en tant que paramètre pour diverses fonctions Microbe3D
Mais certaines fonctions n'ont pas besoin de spécifier la Scene comme
 U3D_Write(MyObject,"myobject.obj"); 
comme MyObject est déjà défini dans une Scene particulière

Objet
Microbe3D utilise des objets 3D chargés à partir de fichiers  .OBJ uniquement
Mais il y a plusieurs convertisseurs disponibles sur Internet qui pourront convertir différents formats vers le format .OBJ
Vous pouvez utiliser Blender pour créer ou importer/convertir/exporter des objets
Menu Blender: Fichier/Exporter/Wavefront (.OBJ)

Material
Microbe3D utilise des Matériaux 3D standards chargés à partir de fichiers .MTL 
Vous pourrez donc avoir du cuivre, du marbre, du verre .... comme Matériaux.
Microbe3D ne peux pas manipuler directement ni créer des Matériaux.
Mais il suffit d'utiliser n'importe quelle application 3D (comme Blender) pour créer des Matériaux, puis les charger à partir du fichier .OBJ/.MTL

Group
Group est une liste de triangles qui utilisent un Matériau.
Un Group défini donc la partie d'un objet utilisant un Matériau particulier.
Microbe3D ne peux pas manipuler directement les Groups.
Mais il suffit d'utiliser n'importe quelle application 3D (comme Blender) d'y créer des Groups, puis les charger à partir du fichier  .OBJ.

Light
Il y a 8 lumières dans la Scene qui peuvent être désactivées/activées/ modifiées comme vous voulez
L'éclairage dans Microbe3D suit (essentiellement) les règles OpenGL.

Instance
C'est quelque chose (Thing) qui est affiché sur la Scene et peut être déplacé/tourné/redimensionné.
Généralement les Instances affichent des objets
 MyObject=U3D_Read(Scene,"eagle.obj");    /* chargé en mémoire */
 Instance=U3D_AddInstance(Scene,MyObject,"myinstance"); /* affiché à l'écran */
Vous pouvez avoir plusieurs Instances d'un même objet: ainsi on peut afficher le même objet dans des tailles/positions différentes
Carte et Instances sont les seules choses vraiment affichées à l'écran dans une Scene
Les Instances se comportent en fait comme des axes mécaniques (ou des articulations). 
Si un objet (ou une Map) est accroché à une Instance alors l'Instance est visible (exemple du bras de robot) 
Mais sinon on peut juste mettre des Instance accrochées les unes aux autres de manière hierarchiques (la plupart sans Objet3D) juste pour créer un mouvement plus complexe 
Après les 3 actions (U3D_Rotate/Translate/Scale) ne font que remuer ces axes
v33: On peut affecter une Motion-Capture à une Instance


How Microbe3D works

env-cube Material
Map
A map is used for a video game: it defines a grid that displays several Objects like a chess game 
A Map can be 2D or 3D 
A Map is filled with Tiles 
Maps and Instances are the only things displayed in a Scene 

Tile
Is a square of a Map that contains just a number (=TileNum) or 0 if it is empty 

TileDef
TileDef defines what will be displayed (= Object) if a tile contains a particular value (= TileNum) 

Thing
Thing is a generic function parameter defined as an APTR (void* pointer) 
An address pointer (APTR also called void* pointer) defines a memory address where your Thing is stored.
A function that uses a Thing works with an Object or Instance or Light, etc. .. 
 

Map
Une carte est utilisée pour un jeu vidéo: cela défini une grille qui affiche plusieurs objets comme un jeu d'échecs
Une carte peut être 2D ou 3D
Une carte est remplie avec des Tiles
Carte et Instances sont les seules choses affichées dans une Scene

Tile
Est une case d'une Map qui contient juste un numéro (=TileNum) ou 0 si elle est vide

TileDef
Un TileDef défini ce qui sera affiché (=Objet) si un Tile contient une valeur particulière (=TileNum)

Thing
Thing est un paramètre de fonction générique défini comme un APTR (pointeur void*)
Un pointeur d'adresse APTR (Adresse Pointer aussi nommé pointeur void*) designe une adresse mémoire quelconque où est stockée votre Thing.
Une fonction qui peut utiliser une Thing fonctionne avec un objet ou une Instance ou une Light, etc .. 

Bone
A Bone define an Axis inside an Object that will move a part of the Object

Skin
A Skin affect a Vertex to a Bone. So a Bone with several Skins move a part of the Object as flesh. So they are the points from an Object that move with a given Bone

Motion-Capture
A Motion-Capture animation move the bones automatically. You can load Motion-Capture from .BVH files
A Frame is a single position in an animation. 
The FPS (Frames par seconde) speed is the animation speed 
So an animation with 300 Frames and a 30 FPS speed will run 10 seconds 

 

Bone
Un Bone(=os) definit un axe (une articulation) dans un même Objet qui bougera donc cette partie de l'Objet

Skin
Un Skin(=peau) affecte un point (un vertex) a un Bone. Ainsi un Bone a plusieurs Skins qui font bouger une partie de l'Objet comme une peau. Ce sont les points de l'Objet qui bougent avec un Bone donné

Motion-Capture
Une Motion-Capture (capture de mouvement) est une animation qui bouge les Bones automatiquement. Vous pouvez charger une Motion-Capture depuis des fichiers .BVH
Une Frame correspond a une position de l'animation. 
La vitesse FPS (Frames par seconde) correspond a la vitesse de l'animation 
Ainsi une animation de 300 Frames à 30 FPS durera 10 secondes 
 


Bear with bones + Lights

Playing a .bvh file on a the same bear with bones
Functions to start a program/create a Scene

APTR U3D_EasyOpenScene(UBYTE* name, UWORD width, UWORD height); 
Easily create a Scene 
Creates a Scene, a window, a bitmap (backbuffer) of the given size 
Scene = U3D_EasyOpenScene ("My first Microbe3D program ", 320,240); 
Be careful : if you use this function Microbe3D will also manage window's IDCMP messages 
Return value: a Scene or NULL 

APTR U3D_OpenScene(APTR win, APTR bm, UWORD x, UWORD y, UWORD width, UWORD height,ULONG flags);
Creates a Scene for specialists 
You give an already opened Amiga window and an already created Amiga bitmap as backbuffer 
(width x height = bitmap size) 
The backbuffer bitmap will be copied in the given window at x y 
Be careful if you use this function then Microbe3D won't manage window's IDCMP messages. It is up to you to create/manage IDCMP messages 
Flags is 0 for this version. 
Return value: a Scene or NULL 

Fonctions pour démarrer un programme/créer une Scene

APTR U3D_EasyOpenScene(UBYTE* name, UWORD width, UWORD height);
Crée une Scene facilement
Création de la Scene, de la fenêtre, de la bitmap (backbuffer) de la taille donnée
 Scene = U3D_EasyOpenScene ("Mon premier programme Microbe3D", 320,240);
Attention si vous utilisez cette fonction alors Microbe3D gérera aussi les IDCMP messages de la fenêtre
Valeur de retour: une Scene ou NULL

APTR U3D_OpenScene(APTR win, APTR bm, UWORD x, UWORD y, UWORD width, UWORD height,ULONG flags);
Crée une Scene pour les spécialistes
Vous donnez une fenêtre Amiga (window) déjà ouverte et un bitmap Amiga comme backbuffer déjà créé 
(width x height = largeur x hauteur)
Le Bitmap backbuffer sera copié en x y dans la fenêtre donnée
Attention si vous utilisez cette fonction alors Microbe3D ne gére pas la fenêtre : c'est à vous de la créer/gérer
Flags vaut 0 dans cette version
Valeur de retour: une Scene ou NULL
 

Functions to fill the Scene 

APTR U3D_Read(APTR Scene, UBYTE* filename); 
Reads the Wavefront file (.OBJ) named filename and reads the file. MTL with Materials. Now also works for .GEO file 
Now in Microbe3D v33 you can load .BVH motion-captures files and .BON files (bones description) and simple .LWO files
Return value: an Object or NULL 
/* new in V35 */
Can load .u3d  files 
So can  load quickly any Things on the Scene
U3D_Read(Scene,"myobject.u3d"); 
U3D_Read(Scene,"mywholescene.u3d"); 

APTR U3D_AddInstance(APTR ParentInstance, APTR Thing,UBYTE* name); 
Adds an Instance named "name" in the Scene 
Thing is an Object or Map or NULL 
ParentInstance is the Scene or an other Instance 
Return Value: An Instance or NULL 

Fonctions pour remplir la Scene

APTR U3D_Read(APTR Scene, UBYTE* filename);
Lit le fichier Wavefront ( .OBJ) nommé filename lit aussi le fichier correspondant .MTL avec ses Matériaux
Désormais lit aussi les fichiers .GEO
Désormais dans Microbe3D v33 vous pouvez aussi lire des fichiers de Motion-Capture .BVH des fichiers .BON (description de Bones ) et des fichiers simples .LWO (LightWawe)
Valeur de retour: un Objet ou NULL

APTR U3D_AddInstance(APTR ParentInstance, APTR Thing,UBYTE* name);
Ajoute une Instance nommée name dans la Scene 
Thing est un Objet ou une Map ou NULL
ParentInstance est la Scene
Valeur de retour: une Instance ou NULL


Bump-mapping on OS4

Materials effects : wireframe,toon-shading,normal
Functions to modify the Scene

/* changed in v35 : this fonction*/
void U3D_SetInstance(APTR Instance,APTR Thing,ULONG type); 
Modify an existing Instance 
The Instance will now display/move the supplied Thing. 
Thing can be a pointer on this:
Object or Map that will be moved with this Instance
Material that will be used to display all this Instance
MotionCapture that will animate this Instance
Sound that will played with this Instance
Light that will be moved with this Instance axis (a given light can attached to only one instance at a time) 

Thing can be NULL but you must then specify the type of the Thing to be removed
 U3D_SetInstance(MyHero,NULL,U3D_MOCAPTURE); /* remove the MotionCapture on this Instance */

So this function changes what is displayed by an Instance or modifies his appearance. 

APTR U3D_SetLight(APTR Light, BOOL Enabled, float* Color); 
Changes or enables/disables a light 
Light is an existing Light. The Scene got eight Lights numbered 1 to 8. 
If parameter Light=Scene then we modify the ambient color of the entire Scene and enable/disable all lighting. Enabled is TRUE/FALSE 
Color is the desired light color defined as 3 RGB floats 
Return Value: The Light parameter or NULL 

APTR U3D_SetLightPlus(APTR Light,float SpotExponent,float SpotCutoff,float ConstantAttenuation,float LinearAttenuation,float QuadraticAttenuation);
Modifies the special parameters of a light: functions reserved for specialists. 
Light is an existing Light. The Scene got eight Lights numbered 1 to 8. 
SpotExponent, SpotCutoff, ConstantAttenuation, LinearAttenuation, QuadraticAttenuation are the same as OpenGL 
Return Value: The Light parameter or NULL 

Fonctions pour modifier la  Scene

void  U3D_SetInstance(APTR Instance, APTR Thing, ULONG Material);
Modification d'une Instance existante
Affiche maintenant la Thing donnée avec ce Matériau qui sera utilisé pour afficher toute cette Instance
parmet donc de changer ce qu'affiche une Instance existante ou de modifier globalement son aspect.
Thing est un Objet ou une Map ou NULL
Materiau  est un des Matériaux existant 

APTR U3D_SetLight(APTR Light, BOOL Enabled, float* Color);
Modifie ou active/désactive une lumière
Light est une des huit Lights numérotées de 1 à 8.
Si le parametre Light=Scene alors on modifie la couleur ambiente de toute la Scene et on active/desactive tout l'éclairage.
Enabled est TRUE/FALSE
Color est la couleur RGB de la lumière définie comme 3 floats 
Valeur de retour: Le parametre Light ou NULL

APTR U3D_SetLightPlus(APTR Light,float SpotExponent,float SpotCutoff,float ConstantAttenuation,float LinearAttenuation,float QuadraticAttenuation);
Modifie les paramétres speciaux d'une lumière : fonctions à réserver aux specialistes.
Light une des huit Lights numérotées de 1 à 8.
SpotExponent,SpotCutoff,ConstantAttenuation,LinearAttenuation,QuadraticAttenuation sont les mêmes que ceux de OpenGL
Valeur de retour: une Light (ou la Scene) ou NULL


A detailled model

Colored Lights + bones
Function to draw a Scene

void U3D_DrawScene(APTR Scene); 
Draw all Instances & Maps defined in a Scene: Draw all. 

Fonction parmettant de dessiner une Scene

void  U3D_DrawScene(APTR Scene);
Trace toutes les Instances et Maps définies dans une Scene: Trace Tout.

Function that delete Things/Close program 

void U3D_Delete(APTR Thing); 
For a given Thing clear away & free the used memory 
Thing may be Scene/Object/Instance/Light/Map 
Object: removed from the Scene and removed from memory 
Instance: removed from the Scene and removed from memory 
Map: removed from the Scene and removed from memory 
Light: just disabled
Scene: The Scene and all are removed and all the used memory is freed. Window and bitmap are closed/freed.

Fonction de suppression de Things/Fermeture du programme

void  U3D_Delete(APTR Thing);
Efface & libère en mémoire la Thing donnée
Thing peut être Scene/Objet/Instance/Light/Map
Objet: le retire de la Scene et le libère en mémoire
Instance: le retire de la Scene et le libère en mémoire
Map: le retire de la Scene et le libère en mémoire
Light: juste la désactive
Scene: La Scene et tout le reste sont libérés en mémoire. Fenêtre et bitmap sont fermées/libérées.


Transparent material + env-cube

Toon-shading Material + textured Material
Functions to modify position/scale factor

void U3D_Translate(APTR Thing, float x, float y, float z,ULONG mode); 
Translation of the given Thing 
Thing can be Object/Instance/Light 
Object: modifies the original loaded Object (destructive action) 
Instance: just change its current position 
Light: changes its position 
In the case of an Object the mode is ignored 
In the case of an Instance/Light if the mode is U3D_RESET then xyz values completely replace the old translation. 
But for Light also takes into account the default position (the OpenGL default position ). 
If the mode is U3D_CHANGE then xyz values are added to the old xyz translation. 

void U3D_Rotate(APTR Thing, float x, float y, float z,ULONG mode); 
Rotation of the given Thing 
Thing can be Object/Instance/Light 
Object: modifies the original loaded Object (destructive action) 
Instance: just change its current rotation 
Light: changes its direction 
In the case of an Object the mode is ignored 
In the case of an Instance/Light if the mode is U3D_RESET then xyz values completely replace the old rotation. 
But for Light also takes into account the default position (the OpenGL default position ). 
If the mode is U3D_CHANGE then xyz values are added to the old xyz rotation. 

void U3D_Scale(APTR Thing, float x, float y, float z,ULONG mode); 
Resizing of the given Thing 
Thing can be Object/Instance 
Object: modifies the original loaded Object (destructive action) 
Instance: just change its current size 
In the case of an Object the mode is ignored 
In the case of an Instance if the mode is U3D_RESET then xyz values completely replace the old xyz scale. 
If the mode is U3D_CHANGE then xyz values are multiplied by the old xyz scale. 

 

Fonctions de modification de position/redimensionnement

void  U3D_Translate(APTR Thing, float x, float y, float z,ULONG mode);
Translation de la Thing donnée
Thing peut être Objet/Instance/Light
Objet: modifie l'objet original chargé (action destructrice)
Instance:  modifie juste sa position actuelle
Light: modifie sa position
Pour un Objet le mode est ignoré
Pour une Instance/Light si le mode est U3D_RESET alors les valeurs x y z remplacent totalement les anciens x y z de translation. Mais pour une Light prend aussi en compte la position par défaut (le défaut OpenGL)
Pour une Instance/Light si le mode est U3D_CHANGE alors les valeurs x y z s'ajoutent aux anciens x y z de translation.

void  U3D_Rotate(APTR Thing, float x, float y, float z,ULONG mode);
Rotation de la Thing donnée
Thing peut être Objet/Instance/Light
Objet: modifie l'objet original chargé (action destructrice)
Instance:  modifie juste sa rotation actuelle
Light: modifie sa direction
Pour un Objet le mode est ignoré
Pour une Instance/Light si le mode est U3D_RESET alors les valeurs x y z remplacent totalement les anciens x y z de rotation.Pour une Light prend aussi en compte la position par défaut (le défaut OpenGL)
Pour une Instance/Light si le mode est U3D_CHANGE alors les valeurs x y z s'ajoutent aux anciens x y z de rotation.

void  U3D_Scale(APTR Thing, float x, float y, float z,ULONG mode);
Redimensionnement de la Thing donnée
Thing peut être Objet/Instance
Objet: modifie l'objet original chargé (action destructrice)
Instance: modifie juste sa taille actuelle
Pour un Objet le mode est ignoré
Pour une Instance si le mode est U3D_RESET alors les valeurs x y z remplacent totalement les anciens x y z de redimensionnement.
Pour une Instance si le mode est U3D_CHANGE alors les valeurs x y z se multiplient aux anciens x y z de redimensionnement.


toon-shading

Materials: normal,wireframe,plots
Fonctions that modify Object data 
WARNING: These actions will truly change the original loaded Object (destructive action)

void U3D_ReverseWinding(APTR Object); 
Change hidden face side: clockwise or counterclockwise 

void U3D_SetSpecialMaterial(APTR Object, APTR Material, APTR Material2, ULONG MatMode); 
Defined a special material in this Object. 
Material is a Material that exists in that Object. 
Material2 is a Material that exists in that Object. 
Material2 for U3D_TEXCUBIC/U3D_MATENVCUBE is the first face that defines a cube-env otherwise is NULL 
(See an example in materials-list.mtl) 
For U3D_MATBUMP Material2 defines the bump material 
MatMode can be 
U3D_TEXLINEARX  Makes a linear texturing among x axis 
U3D_TEXLINEARY  Makes a linear texturing among y axis 
U3D_TEXLINEARZ  Makes a linear texturing among z axis 
U3D_TEXCUBIC  Makes a spherical texturing 
U3D_TEXSPHERIC  Makes a cube texturing 
U3D_MATENVCUBE  Makes an environment cube-mapping(dynamic) 
U3D_MATTOON   Makes a toon shading (dynamic) 
U3D_MATBUMP   Makes a bump Mapping (dynamic) 
U3D_MATBACKGROUND  Material will be used as screen background
U3D_MATZGREY   grey level = z value
U3D_MATSOLID  display Material as filled triangles 
U3D_MATWIREFRAME  display Material as triangles maded with lignes 
U3D_MATPLOT   display Material as plots
U3D_MATFLAT   Flat Material no lighting 
U3D_MATSTANDARD  Material with lighting
U3D_MATTEXTUREDFLAT Flat Material with texture 
U3D_MATTEXTURED  Material with lighting and texture 
U3D_MATTOGROUP  Affect this Material to this Group 
U3D_MATLIGHTFAST  Material with a fast lighting (=lightmap)
U3D_MATINVISIBLE   Hide an Object 

void U3D_Weld(APTR Object, float WeldV, float WeldN, float WeldUV); 
Eliminate (weld) vertices that are closer than the WeldV distance 
This simplifies an Object by removing unnecessary vertices 
This can be done with the vertices and/or normal and/or UV values 
Principle: For each vertex if a vertex is closer than the distance to WeldV 
from another vertex then the first vertex is kept and the second vertex is removed.
Same for vertex-normals with WeldN 
Same for the UV texture values with WeldUV 

void U3D_GridWeld(APTR Object, float GridV, float AngleN, float GridUV);
Same as U3D_Weld but at first it aligns existing points on a grid then it calls U3D_Weld() 
GridV GridUV are the grid steps for the vertices values and UV texture values 
AngleN is the desired angular resolution (as degree) for normals 
AngleN generates GridN = the minimum distance required to represent this AngleN 
(GridN = sin (AngleN Pi/180.0 *) ;) 
Typically for removing double points which are not visible on the screen will be done: 
Scene = U3D_EasyOpenScene ("My first program Microbe3D", 320,240); 
float PixelResolution = 1.0/(float) 320; 
MyObject = U3D_Read (Scene, "myObject.obj"); /* loaded into memory * / 
U3D_GridWeld (MyObject, PixelResolution,0.0.0.0); 

void U3D_Unitize(APTR Object, float size);
Forces the Object to fit into a cube of the given size 
Typically in order to adjust an Object to the screen (so -1.0 to 1.0) we do 
U3D_Unitize (Object, 2.0); 

void U3D_Box(APTR Object, float x, float y, float z); 
Like U3D_Unitize() but forces the Object to fit in a box with dimensions x y z 
A dimension can be 0.0 and thus remains unchanged 
U3D_Box (Object, 0.2,0.2,0.0); /* Size of the Object x is 0.2, will be in 0.2, but z is unchanged * /

void U3D_SwapAxis(APTR Object, ULONG mode); 
Permutes all values of the vertices 
if mode = U3D_SWAPYZ then y and z are swapped 
if mode = U3D_SWAPXZ then x and z are swapped 
if mode = U3D_SWAPXY then x and y are swapped 
if mode = U3D_SWAPUV then u and v are swapped 

void U3D_ObjectNormals(APTR Object, float SmoothAngle); 
Generates normals for the Object so allowing lighting 
if SmoothAngle = 0.0 then generates just a normal per triangle 
if SmoothAngle > 0.0 then generates a "normal vertex" for the faces if AngleFaces < SmoothAngle
So allow Gouraud lighting and rounded faces. 
if SmoothAngle < 0.0 then it deletes all existing normals and therefore all lighting 
Note: In this version SmoothAngle is the same for the whole Object and not adapted to each Material 

void U3D_Write(APTR Object, UBYTE* filename); 
Saves the Object as a .OBJ and. MTL files 
Do not save texture pictures.
/* new in V35 */
Can save as .u3d format a binary packed IFF-like format 
So can save or load quickly any Things on the Scene
U3D_Write(Object,"myobject.u3d"); 
U3D_Write(Scene,"mywholescene.u3d"); 

/* new in V35 */
void U3D_DoObjectFX(APTR Thing,ULONG mode); 
Do several special effects(FX) on an Object
Those are destructive effects : the Object will never looks again the same after using an effect

type==U3D_OBJECT mode==U3D_FXGROUPASOBJECT
  Convert each Group as a new Object but the Materials are still shared among the Objects

type==U3D_OBJECT mode==U3D_FXAUTOSKIN
  AutosSkin feature started manually
  Create the vertex-skin an vertexnormal-skin from the existing Bones. 
  Points that are nearer than radius from Bone axis are included in this Bone's skin
  Points force may be shared between Parent Bone and Children Bones if position on the Bone segment is not in Bone's min/max

type==U3D_OBJECT mode==U3D_FXPACKOBJECT
  All the lists that make an Object (vertex,normals,uv,triangles,etc...) and the Object itself are re-allocated in a single
  memory block. 
  So all Object data are in the same memory area so should give better performance (not the case...)

type==U3D_INSTANCE mode==U3D_FXPOINTSFROMSKINS
  For an Object displayed with an Instance and that got Bones & Skins: Get the current vertices position and save them as vertices base position
  So do a snapshot of the given vertices position
  Can serve to create a static object in a new position 

type==U3D_SCENE mode==U3D_FXBONEROTBASE
  For an Object displayed with an Instance and that got Bones & Skins: get Bones RotationBase from current Instances rotation
  So define the basic Bones positions when nothing had moved them

Fonctions de modification de données d'objets
AVERTISSEMENT: Ces actions vont véritablement modifier l'objet chargé original (actions destructrices)

void  U3D_ReverseWinding(APTR Objet);
Inverse les faces: sens horaire ou antihoraire

void  U3D_SetSpecialMaterial(APTR Objet, APTR Material, APTR Material2, ULONG MatMode);
Défini un Matériau spécial dans cet Objet.
Material  est un Matériau existant dans cet Objet.
Material2 est un Matériau existant dans cet Objet.
Pour U3D_TEXCUBIC/U3D_MATENVCUBE Material2 définit la première face d'un env-cube sinon mettre NULL
(Voir un exemple dans materials-list.mtl )
Pour U3D_MATBUMP Material2 définit le bump material de base
MatMode peut être
U3D_TEXLINEARX Fait un texturing linéaire selon l'axe x
U3D_TEXLINEARY Fait un texturing linéaire selon l'axe y
U3D_TEXLINEARZ Fait un texturing linéaire selon l'axe z
U3D_TEXCUBIC Fait un texturing sphérique
U3D_TEXSPHERIC Fait un texturing cube 
U3D_MATENVCUBE Fait un environnement cube mapping (dynamique)
U3D_MATTOON Fait un ombrage toon (dynamique)
U3D_MATBUMP Fait un bump mapping (dynamique)
U3D_MATBACKGROUND Materiau sert de fond d'écran 
U3D_MATZGREY   niveau de gris selon z 
U3D_MATSOLID  affiche le Material comme des triangles pleins 
U3D_MATWIREFRAME  affiche le Material comme des triangles en lignes 
U3D_MATPLOT   affiche le Material comme des points 
U3D_MATFLAT   Material à plat sans ombrage 
U3D_MATSTANDARD  Material avec ombrage 
U3D_MATTEXTUREDFLAT Material à plat avec texture 
U3D_MATTEXTURED  Material avec ombrage et texture 
U3D_MATTOGROUP  Affecte ce Material à ce Group 
U3D_MATLIGHTFAST  Material avec ombrage rapide 
U3D_MATINVISIBLE   Cache un objet 

void  U3D_Weld(APTR Objet, float WeldV, float WeldN, float WeldUV);
Élimine (weld=souder) des sommets qui sont plus proches que la distance WeldV
Cela simplifie un objet par la suppression de sommets inutiles 
Cela peut se faire avec les sommets et/ou les normales et/ou les valeurs UV
Principe: Pour chaque sommet si un sommet est plus proche que la distance WeldV à 
partir d'un autre sommet alors garde le premier sommet et retire le deuxième sommet
Idem pour les normales de sommets avec WeldN
Idem pour les valeurs de texture UV avec WeldUV

void  U3D_GridWeld(APTR Objet, float GridV, float AngleN, float GridUV);
Identique à U3D_Weld, mais aligne d'abord les points existants sur une grille puis appele U3D_Weld()
GridV et GridUV sont les pas de la grille pour les valeurs des sommets et les valeurs de texture UV
AngleN est la résolution angulaire(degré) voulue pour les normales
AngleN génère un GridN = la distance minimale nécessaire pour représenter cet AngleN 
(GridN = sin (AngleN* Pi/180.0);)
Typiquement pour enlever les points doubles qui ne sont pas visibles à l'écran on fera:
 Scene = U3D_EasyOpenScene ("Mon premier programme Microbe3D", 320,240);
 float PixelResolution = 1.0/(float) 320;
 MyObject = U3D_Read (Scene, "myobject.obj"); /* chargé en mémoire* /
 U3D_GridWeld (MyObject,PixelResolution.0.0.0.0);

void  U3D_Unitize(APTR Objet, float size);
Force l'objet à tenir dans un cube de dimension = size
Typiquement pour ajuster un objet dans l'écran donc de -1.0 à 1.0
 U3D_Unitize (Objet,2.0);

void  U3D_Box(APTR Objet, float x, float y, float z);
Comme U3D_Unitize () mais force l'objet à tenir dans une boîte avec des dimensions x y z
Une dimension peut être 0.0 et ainsi rester inchangée
 U3D_Box (Objet,0.2,0.2,0.0); /* Taille de l'objet en x sera 0.2, en y sera 0.2, mais en z sera inchangée */

void  U3D_SwapAxis(APTR Objet, ULONG mode);
parmute toutes les valeurs des sommets
si mode=U3D_SWAPYZ alors les y et z sont parmutés
si mode=U3D_SWAPXZ alors les x et z sont parmutés
si mode=U3D_SWAPXY alors les x et y sont parmutés
si mode=U3D_SWAPUV alors les u et v sont parmutés

void  U3D_ObjectNormals(APTR Objet, float SmoothAngle);
Génére des normales pour l'objet parmettant ainsi l'éclairage
si SmoothAngle = 0.0 alors génére juste une normale par triangle
si SmoothAngle  > 0.0 alors génère une "normale de sommet" par sommet pour les faces dont AngleFaces < SmoothAngle. Donc permet l'éclairage Gouraud et des faces arrondies.
si SmoothAngle <  0.0 alors supprimera toutes les normales existantes et donc l'éclairage
Note: Dans cette version SmoothAngle est le même pour tout l'objet et non pas adapté à chaque Material

void  U3D_Write(APTR Objet, UBYTE* filename);
Enregistre l'objet comme un fichier .OBJ et un .MTL
Ne sauvegarde pas les images des textures


Bump-mapping on OS4

Bump-mapping on OS4
Query functions 

void U3D_Dimensions(APTR Object, Vertex3D *min,Vertex3D *max,Vertex3D *size); 
Gives the dimensions of the Thing 
Thing can be Object/Group/Material 
min->x contains the smallest x value in the Thing (same for min->y min->z) 
min->x contains the biggest x value in the Thing (same for max->y max->z) 
size->x = (max->x - min->x); (same for size->y size->z) 

APTR U3D_Find (APTR BaseThing, ULONG type, UBYTE* name); 
Retrieves the pointer to an existing Thing from its name 
BaseThing can be Scene/Object/Group/Instance. BaseThing is where we seek. 
type is the name of the desired type of thing 
If BaseThing is Scene then type can be U3D_OBJECT,U3D_INSTANCE,U3D_MAP,U3D_LIGHT 
If BaseThing is an Object then type can be U3D_MATERIAL,U3D_GROUP 
If BaseThing is a Group then type can be U3D_MATERIAL 
If BaseThing is an Instance then type can be U3D_THING 
Object=U3D_Find (Scene,U3D_OBJECT, "teapot.obj"); 
RubyMaterial=U3D_Find (Object,U3D_MATERIAL, "mat_ruby_transp"); 
EnvCubeMaterial=U3D_Find (Object,U3D_MATERIAL, "mat_cubemapxpos"); 
U3D_SetSpecialMaterial(Object,RubyMaterial,EnvCubeMaterial,U3D_MATENVCUBE); 
Return Value: A NULL or an Object/Instance/Map/Material/Group/Light/Vector3D/Thing 

APTR U3D_Get(APTR BaseThing, ULONG type, ULONG Tnum); 
Finds the pointer on a existing Thing from its number (Tnum = Thing number) 
Works as U3D_Find() 
Object=U3D_Find (Scene,U3D_OBJECT,3); 
Note: Scene/U3D_MOUSEVECTOR returns a pointer to the normalized mouse position 
Vertex3D* MouseVector; 
MouseVector=U3D_Get(Scene,U3D_MOUSEVECTOR,0); 
If Tnum is greater than or equal to the number of existing Things it returns NULL 
Return Value: An Object/Instance/Map/Material/Group/Light/Thing or NULL 

UBYTE* U3D_Name(APTR Thing); 
Gives the name of an existing thing 
Warning: The names are less than 80 characters 
Return value: an *UBYTE pointer to the name or NULL 

LONG U3D_QueryValue(APTR BaseThing,ULONG type) ;
Returns the value of different variables in the Scene 
like the number of triangles, points, etc. of an Object, or the FPS rate of Scene (Frames Per Second) or the mouse position, etc ... 
Searchable fields are : 

To obtain their count: 
U3D_INSTANCE 
U3D_OBJECT 
U3D_MATERIAL 
U3D_GROUP 
U3D_TRIANGLE 
U3D_VERTEX 
U3D_UV 
U3D_VNORMAL 
U3D_FNORMAL 
U3D_LIGHT 
U3D_MAP 
U3D_TILEDEF 
U3D_TILE 

For speed 
U3D_FPS Frames per second (Speed display) 
U3D_FPS50 Frames per second (average on 50 frames) 
U3D_TRISDONE Triangles drawn per second 
U3D_TRIS50 Triangles drawn per second (average on 50 frames) 
U3D_TPF Time per frame in milliseconds (Display speed) 
U3D_TPF50 Time per frame in milliseconds (Display speed) (average on 50 frames) 

For information
U3D_FRAMETIME Elapsed time counted as 1/25th second 
U3D_MEMSIZE Memory usage 
U3D_VERSION Microbe3D version 

If you used U3D_EasyOpenScene() then those fields are automatically filled 
U3D_MOUSEX U3D_MOUSEY mouse position in pixels 
U3D_MOUSEBUTTONS Mouse buttons 
U3D_VANILLAKEY Keyboard key 
U3D_MENUCOMMAND Menu of the selected menu command 
U3D_GADGETID Selected gadget Id 

see Microbe3D.h & demo-view.c

Fonctions d'interrogation

void U3D_Dimensions(APTR Objet, Vertex3D *min,Vertex3D *max,Vertex3D *size);
Donne les dimensions de la Thing
Thing peut être Objet/Groupe/Material
min->x contient le plus petit x de la Thing (idem pour min->y min->z) 
max->x contient le plus grand x de la Thing (idem pour max->y max->z)
size->x = (max->x - min->x);    (idem pour size->y size->z) 

APTR U3D_Find (APTR BaseThing, ULONG type, UBYTE* name); 
Retrouve le pointeur d'une chose existante à partir de son nom (name)
BaseThing peut être Scene/Objet/Group/Instance c'est là où on cherche.
type est le nom du type de chose recherchée
Si BaseThing est une Scene alors type peut être U3D_OBJECT,U3D_INSTANCE,U3D_MAP,U3D_LIGHT
Si BaseThing est un Objet alors type peut être U3D_MATERIAL,U3D_GROUP
Si BaseThing est un Group  alors type peut être U3D_MATERIAL
Si BaseThing est une Instance  alors type peut être U3D_THING
 Objet=U3D_Find (Scene,U3D_OBJECT, "teapot.obj");
 RubyMaterial=U3D_Find (Objet,U3D_MATERIAL, "mat_ruby_transp");
 EnvCubeMaterial=U3D_Find (Objet,U3D_MATERIAL, "mat_cubemapxpos");
 U3D_SetSpecialMaterial(Objet,RubyMaterial,EnvCubeMaterial,U3D_MATENVCUBE);
Valeur de retour: un Objet/Instance/Map/Material/Group/Light/Vector3D/Thing ou NULL

APTR U3D_Get(APTR BaseThing, ULONG type, ULONG Tnum); 
Retrouve le pointeur d'une chose existante à partir de son numéro (Tnum=Thing numéro)
Fonctionne comme U3D_Find()
 Objet=U3D_Find (Scene,U3D_OBJECT,3);
Note: Scene/U3D_MOUSEVECTOR renvoie un pointeur sur la position souris normalisée
 Vertex3D* MouseVector;
 MouseVector=U3D_Get(Scene,U3D_MOUSEVECTOR,0);
Si Tnum est supérieur ou égal au nombre de choses existantes renvoie NULL
Valeur de retour: un Objet/Instance/Map/Material/Group/Light/Thing ou NULL

UBYTE* U3D_Name(APTR Thing); 
Donne le nom d'une chose existante
Attention: Les noms font moins de 80 caractères maximum
Valeur de retour: un pointeur UBYTE* sur le nom ou NULL

LONG U3D_QueryValue(APTR BaseThing,ULONG type);
Renvoie la valeur de différentes variables de la Scene
Comme le nombre de triangles,points,etc d'un Objet,comme le taux FPS de la Scene (Frames par Second), comme la position souris,etc...
Les champs interrogeables sont 

Pour obtenir leur nombre:
U3D_INSTANCE
U3D_OBJECT
U3D_MATERIAL
U3D_GROUP
U3D_TRIANGLE
U3D_VERTEX
U3D_UV
U3D_VNORMAL
U3D_FNORMAL
U3D_LIGHT
U3D_MAP
U3D_TILEDEF
U3D_TILE

Pour obtenir la rapidité
U3D_FPS   Frames par second (Vitesse d'affichage)
U3D_FPS50 Frames par second en moyenne sur 50 frames
U3D_TRISDONE Triangles tracés par seconde
U3D_TRIS50 Triangles tracés par seconde moyenne sur 50 frames
U3D_TPF Time par Frame en millisecondes (Vitesse d'affichage) 
U3D_TPF50 Time par Frame en millisecondes (Vitesse d'affichage) en moyenne sur 50 frames */

Pour des infos
U3D_FRAMETIME  Temps écoulé compté en 1/25éme seconde
U3D_MEMSIZE Mémoire utilisée
U3D_VERSION version de Microbe3D

Si vous avez utilisé U3D_EasyOpenScene() ces champs sont remplis automatiquement
U3D_MOUSEX U3D_MOUSEY Position souris en pixel
U3D_MOUSEBUTTONS Boutons souris 
U3D_VANILLAKEY Touche clavier
U3D_MENUCOMMAND Menu command du menu sélectionné
U3D_GADGETID Gadget ID du gadget sélectionné

voir dans Microbe3D.h & demo-view.c


Loading a big textured .OBJ file

Applying a transparent + env-cube Material
Functions for Map & Tiles 

APTR U3D_AddMap(APTR Scene,UBYTE *name,Vertex3D *TileSize,ULONG width,ULONG height,ULONG depth); 
Creates a new Map for a game 
TileSize is the size for each Tile in the Map 
width, height, depth are the Map dimensions in Tiles
A 2D Map (like a chess game) has a height of 1 
ChessMap=U3D_AddMap(Scene,8,1,8); 
Map and Instance are the only Things displayed in a Scene 
Return value: A Map or NULL 

void U3D_SetTileDef(APTR Map, ULONG TileNum, APTR Thing); 
In a Map define which object will be used to represent a Tile for a given TileNum. 
BlackSquareObject=U3D_Read(Scene,"MyBlackSquare.obj"); 
WhiteSquareObject=U3D_Read(Scene,"MyWhiteSquare.obj"); 
U3D_SetTileDef(ChessMap,1,BlackSquareObject); 
U3D_SetTileDef(ChessMap,2,WhiteSquareObject); 
NOTE: TileNum can not be 0 since this value is reserved for empty Tiles 

void U3D_SetTile(APTR Map, ULONG x, ULONG y, ULONG z, ULONG TileNum); 
To a given position in the Map define the Tile 

for(i=0;i<8;i++) 
for(j=0;j<8;j++) 

if((i+j) % 2) 
U3D_SetTile(Map,i,0,j,1); 
else 
U3D_SetTile(Map,i,0,j,2); 

ULONG U3D_GetTile(APTR Map, ULONG x, ULONG y, ULONG z); 
To a given position in the Map read the Tile 

TileNum=U3D_GetTile(ChessMap,4,0,5);
if(TileNum=1) 
printf("Is black square\n"); 
if(TileNum=2) 
printf("Is white square\n"); 
Return Value: A TileNum or 0 

Fonctions pour Map & Tiles

APTR U3D_AddMap(APTR Scene,UBYTE *name,Vertex3D *TileSize,ULONG width,ULONG height,ULONG depth);
Crée une nouvelle carte pour un jeu
TileSize est la taille de chaque Tile de la Map
width,height,depth sont les dimensions de la Map en nombre de Tile
Une Map 2D (comme un jeu d'échecs) a une height de 1
 ChessMap=U3D_AddMap(Scene,8,1,8);
Carte et Instances sont les seules Things affichées
Valeur de retour: une Map ou NULL

void  U3D_SetTileDef(APTR Map, ULONG TileNum, APTR Thing);
Dans une carte défini quel objet sera utilisé pour représenter un Tile pour un TileNum donné.
 BlackSquareObject=U3D_Read(Scene,"MyBlackSquare.obj");
 WhiteSquareObject=U3D_Read(Scene,"MyWhiteSquare.obj");
 U3D_SetTileDef(ChessMap,1,BlackSquareObject);
 U3D_SetTileDef(ChessMap,2,WhiteSquareObject);
REMARQUE: TileNum ne peux pas être égal à 0 puisque cette valeur est réservé pour des cases(Tile) vides

void  U3D_SetTile(APTR Map, ULONG x, ULONG y, ULONG z, ULONG TileNum);
A une position donnée dans la carte défini le Tile

 for(i=0;i<8;i++)
 for(j=0;j<8;j++)
 {
 if((i+j) % 2)
  U3D_SetTile(Map,i,0,j,1);
 else
  U3D_SetTile(Map,i,0,j,2);
 }

ULONG U3D_GetTile(APTR Map, ULONG x, ULONG y, ULONG z);
A une position donnée dans la carte lire le Tile

 TileNum=U3D_GetTile(ChessMap,4,0,5);
 if(TileNum=1)
  printf("Is black square\n");
 if(TileNum=2)
  printf("Is white square\n");
Valeur de retour: un TileNum ou 0


Creating a simple map

Creating a map for game

loading a Lightwave Object + 2 Lights

toon-shading
Function to create Objects from scratch
NOTE: Usually you do not need these functions as Objects are loaded from .OBJ files
These functions can be used only to create Objects from scratch for 3D expert-coders. 
CAUTION: You can not modify an Object loaded from an OBJ file with these functions. 

APTR U3D_AddObject(APTR Scene, UBYTE* name,ULONG Pnb,ULONG MATnb); 
Creates a new empty Object named "name" in the Scene 
This Object will have Pnb points (Pnb=Points count) 
This Object will have MATnb materials (MATnb=Materials count). The Materials are defined by default as greyscale 
Creating a cube request 6 squares = 12 triangles = 36 points 
CubeObjet=U3D_AddObject(Scene,"cube",36,1); 
Note: Once the Object is finished U3D_Weld() will remove all duplicates points 
Return value: an Object or NULL 

APTR U3D_AddGroup(APTR Object, UBYTE* name,APTR Material); 
Creates a new empty Group named "name" in the Object 
This group will use the material Material and therefore contain all faces that use this material 

void U3D_AddFace(APTR Object); 
Creates a new empty Face in this Object/Group 

void U3D_AddPoint(APTR Object, Vertex3D* V, Vertex3D* VN, Uv3D* UV); 
Creates a new Point in the Object/Group/Face 
V contains the x y z vertex values 
VN contains the x y z vertex-normal values 
UV contains the u v texturing values 
Note: If you dont have values for VN and/or UV then set those pointers to NULL 
 

Fonction de création d'objets à partir de zéro
NOTE: Habituellement vous n'avez pas besoin de ces fonctions comme des objets sont chargés à partir de fichier .OBJ.
Ces fonctions ne servent qu'à créer des objets à partir de zéro pour les codeurs spécialistes en 3D.
ATTENTION: vous ne pouvez pas modifier un objet chargé à partir d'un fichier OBJ avec ces fonctions.

APTR U3D_AddObject(APTR Scene, UBYTE* name,ULONG Pnb,ULONG MATnb);
Crée un nouvel objet vide nommé name dans cette Scene
Cet objet aura Pnb points (Pnb=Points nombre) 
Cet objet aura MATnb materiaux (MATnb=Materiaux nombre) ces Materiaux sont définis par défaut comme des niveaux de gris
La création d'un cube demande 6 carrés = 12 triangles = 36 points
 CubeObjet=U3D_AddObject(Scene,"cube",36,1);
Note: une fois l'objet fini U3D_Weld() pourra supprimer tous les points en doublons
Valeur de retour: un Objet ou NULL

APTR  U3D_AddGroup(APTR Objet, UBYTE* name,APTR Material);
Crée un nouveau Groupe vide nommé name dans cet Objet
Ce Groupe utilisera le materiau Material et contiendra donc toutes les faces qui utilisent ce Matériau

void  U3D_AddFace(APTR Objet);
Crée une nouvelle face vide dans cet Objet/Groupe

void  U3D_AddPoint(APTR Objet, Vertex3D* V, Vertex3D* VN, Uv3D* UV);
Crée un nouveau point dans cet Objet/Groupe/Face
V  contient les valeurs x y z du sommet
VN contient les valeurs x y z de la "normale de sommet" 
UV contient les valeurs u v de texturing
Remarque: Si vous n'avez pas de valeurs VN et/ou de valeurs UV alors mettre ces pointeurs à NULL
 


Creating a boing Object from Scratch + background

Rotating Logo +env-cube + background

A detailled model

Hierarchical Instances + animation
Functions for Bones/Skins/Motion-captures (v33)
Now in Microbe3D v33 you can create bones/skins and load .bvh motion-captures files
A Bone define an Axis inside an Object that will move a part of the Object
A Skin affect a Vertex to a Bone. So a Bone with several Skins move a part of the Object
You can define manually all the SkinS yourself with U3D_AddSkin() 
or 
never use this function and use U3D_SetBoneInfluence() for all Bones then 
let the AutoSkin feature create all the Skins for you
or
never use those functions but U3D_Read() a .BON file containing the bones description then 
let the AutoSkin feature create all the Bones/Skins for you
A .BVH file contain a Bones description and the moving (a position + one rotation per Bone) for each frame

APTR U3D_AddBone(APTR Object,UBYTE* name,APTR ParentBone,Vertex3D* AxisPos,Vertex3D* EndPos,ULONG Pnb); 
Creates a new empty Bone named "name" in the Object
AxisPos define where the Bone start and move in the Object . EndPos define the Bone extremity
Pnb (points count) define how many points (are planned to) will be moved with this Bone
If you load your Bones/Skins from a file certainly you know how much points will be moved with each Bone. 
Else just set Pnb to the points count of the Object like this:
 Pnb=U3D_QueryValue(Object,U3D_VERTEX);
 U3D_AddBone(Object,"bone2",Bone1,AxisPos,EndPos,Pnb); 

void U3D_SetAmplitude(APTR Bone,Vertex3D* PosMin,Vertex3D* PosMax,Vertex3D* RotMin,Vertex3D* RotMax,float ScaleMin,float ScaleMax); 
Define moving amplitude for this Bone. The Bone cant move outside the range [min max]
PosMin,PosMax range for position (translation) of the Bone (usually unused)
RotMin,RotMax range for rotation of the Bone
ScaleMin,ScaleMax range for scaling of the Bone (usually unused)

void U3D_SetBoneInfluence(APTR Bone,float radius,float min,float max);
Define how the AutoSkin feature will manage this Bone 
AutoSkin automatically create Skins for an Object based upon Bone to Vertex distance
Something like "if point is near leg then this point will be moved with the leg"
radius : All vertices nearer that radius distance are skinned to this Bone
min: a value like 0.2 will mean that the first 20% of the Bone will be force-shared with parent Bone
min: a value like 0.7 will mean that the last  30% of the Bone will be force-shared with childs Bones
Dont use this function if you define all your Skins manually with U3D_AddSkin()

void U3D_SetBoneEquivalence(APTR Bone,UBYTE* MCname,Vertex3D* RotBase);
Define how the .bvh motion-capture file will be mapped with this Bone
A .bvh file have his own Bones description so the goal of this function is to describe how use yours Bones with the .bvh Bones
MCname is the Bone-name used in the motion-capture (MC) file
RotBase is the rotation to apply to your Bone to obtain the same position as the Bone used in the motion-capture file

APTR U3D_AddSkin(APTR Bone,ULONG Vnum,float force);
NOTE: Usually you do not need this function as Skins are loaded from .BON files with the the AutoSkin feature
Create manually a Skin for this Bone
A Skin is a point that you want to be moved with this Bone 
Vnum is the Vertex number 
force is how much the point will be moved with this Bone
force is a float value in the range 0.0 to 1.0
Some points may be shared on several Bones
  U3D_AddSkin(Bone1,Vnum,0.4);
  U3D_AddSkin(Bone2,Vnum,0.6);  /* this point will be moved with Bone1 and Bone2 almost equally */
Important: for a given Vnum all forces  must sum to 1.0
Dont use U3D_SetBoneInfluence() if you use U3D_AddSkin() for creating all Skins
 
 
 
 
 
 

 

Fonctions pour les Bones/Skins/Motion-Captures (v33)
Désormais dans Microbe3D v33 vous pouvez aussi lire des fichiers de Motion-Capture .BVH et des fichiers .BON (description de Bones )
Un Bone (=os)definit un axe (une articulation) dans un même Objet qui bougera donc cette partie de l'Objet
Un Skin (=peau)affecte un point(vertex) a un Bone. Ainsi un Bone a plusieurs Skins qui font bouger une partie de l'Objet
Vous pouvez définir vous même manuellement tout les SkinS avec U3D_AddSkin() 
ou
Ne jamais utiliser cette fonction et utiliser U3D_SetBoneInfluence() pour tout les Bones et laisser la fonctionnalité intégrée AutoSkin créer tout les Skins pour vous
ou
Ne jamais utiliser ces fonctions mais plutôt U3D_Read() d'un fichier .BON contenant une description des Bones et laisser la fonctionnalité intégrée AutoSkin créer tout les Bones et Skins pour vous
Un fichier .bvh contient la description de ses Bones et le mouvement (une position + une rotation par Bone) pour chaque frame

APTR U3D_AddBone(APTR Objet,UBYTE* name,APTR ParentBone,Vertex3D* AxisPos,Vertex3D* EndPos,ULONG Pnb); 
Crée un nouveau Bone(=Os) vide nommé "name" dans cet Objet
AxisPos (position axe) définit où commence le Bone et où cela bouge dans l'Objet . EndPos (position fin) définit l'extremité du Bone
Pnb (nombre de points) définit combien de points vont (sont prévus pour) bouger avec ce Bone
Si vous chargez vos Bones/Skins depuis un fichier alors certainement vous connaissez le nombre de points bougés par Bones. 
Sinon mettre juste par défaut le nombre de points de tout l'Objet comme ça:
 Pnb=U3D_QueryValue(Objet,U3D_VERTEX);
 U3D_AddBone(Objet,"bone2",Bone1,AxisPos,EndPos,Pnb); 

void U3D_SetAmplitude(APTR Bone,Vertex3D* PosMin,Vertex3D* PosMax,Vertex3D* RotMin,Vertex3D* RotMax,float ScaleMin,float ScaleMax); 
Définit l'amplitude du mouvement de ce Bone(=Os). Le Bone ne peut bouger en dehors des limites [min max]
PosMin,PosMax amplitude de position (translation) du Bone (normalement inutilisé)
RotMin,RotMax amplitude de rotation du Bone
ScaleMin,ScaleMax amplitude pour redimimensionnement du Bone (normalement inutilisé)

void U3D_SetBoneInfluence(APTR Bone,float radius,float min,float max);
Définit comment la fonction AutoSkin va gérer ce Bone(=Os)
AutoSkin créée automatiquement les Skins d'un Objet selon la distance des points aux Bone
Selon cette méthode "si ce point est proche de la jambe alors ce point bougera avec la jambe"
radius : Tout les points plus proche en distance que ce rayon (=radius) seront dans la peau (Skin) de ce Bone
min: une valeur comme 0.2 signifiera que les premiers 20% (=0.2) du Bone auront un partage de force avec le Bone parent 
max: une valeur comme 0.7 signifiera que les derniers 30% (=1.0-0.7) du Bone auront un partage de force avec les Bone enfants 
N'utilisez pas cette fonction si vous définissez toutes vos Skins manuellement avec U3D_AddSkin()

void U3D_SetBoneEquivalence(APTR Bone,UBYTE* MCname,Vertex3D* RotBase);
Définit comment le fichier .bvh de motion-capture sera appliqué à ce Bone(=Os)
Un fichier .bvh a lui aussi sa propre description de ses propres Bones 
Donc le but de cette fonction est de décrire comment utiliser nos Bones avec les Bones du .bvh
MCname est le nom du Bone utilisé dans le fichier .bvh de motion-capture 
RotBase est la rotation à appliquer à votre Bone pour avoir la même position que le Bone décrit dans le fichier .bvh de motion-capture 

APTR U3D_AddSkin(APTR Bone,ULONG Vnum,float force);
NOTE: Généralement vous n'aurez pas besoin de cette fonction comme les Skins sont créés par la fonctionnalité AutoSkin depuis les bones décrits dans une fichier .BON 
Ajoute manuellement un Skin à ce Bone
Un Skin est un point de l'Objet que vous voulez bouger avec ce Bone
Vnum est le Numéro du Point (Vertex number)
force indique avec quelle intensité ce point sera bougé par ce Bone
force est une valeur float dans la limite [0.0 à 1.0]
Ainsi des points peuvent être utilisés par plusieurs Bones (partage de force)
  U3D_AddSkin(Bone1,Vnum,0.4);
  U3D_AddSkin(Bone2,Vnum,0.6);  /* ce point sera bougé par le Bone1 et le Bone2 presque également */
Important: Pour un Vnum donné (un point donnée) l'ensemble des forces appliquées doit avoir un total de 1.0
Ne pas utiliser U3D_SetBoneInfluence() si vous utilisez U3D_AddSkin() pour créer tout les Skins manuellement


Applying bones and skins to a mesh

Bones + Skins + Lights as wirefframe

Bones + Skins as wirefframe


Bones + Skins + animated Lights + detailled model + .bvh animation
void U3D_SetValue(APTR Thing,ULONG var,ULONG value);
This function is reserved for 3D expert-coders 
Set some Microbe3D internal parameters

For a Material you can redefine the Warp3D states with those vars (see Warp3D docs for more infos)
This allow to create very special Materials
U3D_STZMODE
U3D_STBLENDMODE
U3D_STTEXENVMODE
U3D_STUSEGOURAUD
U3D_STUSECOLORS
U3D_STPERSPMODE
U3D_STCULLINGMODE
U3D_STPRIMITIVE
U3D_STFOGMODE
U3D_STPOINTSIZE
U3D_STLINESIZE
U3D_STFOGZMIN
U3D_STFOGZMAX
U3D_STFOGDENSITY
U3D_STFOGRGBA
U3D_STCURRENTRGBA
U3D_STENVRGBA

For a Scene you can display internal structures on screen with those boolean vars (for debugging purpose)
U3D_SHOWNORMALS
U3D_SHOWLIGHTS
U3D_SHOWINSTANCES

For a Scene you can disable the drawing operations with those boolean vars (for benchmarking purpose)
U3D_CLEARZBUFFER
U3D_CLEARBITMAP
U3D_DRAWSCENE
U3D_OSDRAW
 

void U3D_SetValue(APTR Thing,ULONG var,ULONG value);
Cette fonction est réservée aux coders experts en 3D
Fixe une valeur à un des parametres internes de Microbe3D

Pour un Material vous pouvez redéfinir les states Warp3D avec ces variables (voir la doc Warp3D pour plus d'infos)
This allow to create very special Materials
U3D_STZMODE
U3D_STBLENDMODE
U3D_STTEXENVMODE
U3D_STUSEGOURAUD
U3D_STUSECOLORS
U3D_STPERSPMODE
U3D_STCULLINGMODE
U3D_STPRIMITIVE
U3D_STFOGMODE
U3D_STPOINTSIZE
U3D_STLINESIZE
U3D_STFOGZMIN
U3D_STFOGZMAX
U3D_STFOGDENSITY
U3D_STFOGRGBA
U3D_STCURRENTRGBA
U3D_STENVRGBA

Pour une Scene vous pouvez afficher à l'écran ses structures internes avec ses variables booléenes (sert qu'au deboguage)
U3D_SHOWNORMALS
U3D_SHOWLIGHTS
U3D_SHOWINSTANCES

Pour une Scene vous pouvez désactiver ces opérations de tracer avec ses variables booléenes (sert qu'au deboguage)
U3D_CLEARZBUFFER
U3D_CLEARBITMAP
U3D_DRAWSCENE
U3D_OSDRAW


Nice model

Colored Lights + bones
Functions for Motion-Capture animations (v33)
Those functions return a new Motion-Capture or NULL
see demo-view.c for examples

APTR U3D_MotionCaptureCut(APTR MoCapture,UBYTE* name,ULONG start,ULONG end);
Keep only the animation part between frame start and end

APTR U3D_MotionCaptureJoin(APTR MoCapture,APTR MoCapture2,UBYTE* name,ULONG FRnb);
join two animations in a new one. FRnb is the time (as frames) added between the two animation. The two Animations must use same bones and fps speed. The new added frames interpolate between MoCapture end position and Mocapture2 start position
/* new in V35 */
If MoCapture2 is NULL then the new added frames interpolate between MoCapture end position and Mocapture start position so creating a "looping" animation

APTR U3D_MotionCaptureFx(APTR MoCapture,UBYTE* name,APTR Thing,float param,ULONG mode);
Apply a special effect to this Motion-Capture
mode can be 
U3D_MOCAPTURE_CLEAN then clean this Motion-Capture for this Instance(=Thing): just keep bones animations that exists in this instance so use less memory
U3D_MOCAPTURE_REVERT revert this Motion-Capture animation
U3D_MOCAPTURE_RESAMPLE recompute the animation for this frame speed(=param): A 120 fps Motion-Capture converted to 20 fps will use 6 time less memory

There is also
U3D_SetValue(MoCapture,U3D_FPS,30);
that will only set a new speed for an animation but the data and memory usage will stay unchanged

/* new in V35 */
APTR U3D_AddMotionCapture(APTR Scene,UBYTE* name,ULONG BONEnb,ULONG FRnb,float fps);
Create a new empty MotionCapture that will serve to move some bones 
BONEnb : bones count 
FRnb: frames count
fps: frame per second speed

void U3D_SetMotionCapture(APTR MoCapture,APTR Instance,ULONG FRnum);
FRnum: frame number
The current position of this Instance will be saved in this MotionCapture at this frame number position
This is a way to set a position in a (new) MotionCapture
 

Function parameters
see Microbe3D.h 

Fonctions for Motion-Capture animations (v33)
Toutes ces fonctions renvoient une nouvelle Motion-Capture ou NULL
Voir demo-view.c pour des exemples

APTR U3D_MotionCaptureCut(APTR MoCapture,UBYTE* name,ULONG start,ULONG end);
Garde la partie de l'animation entre les frames de début et fin spécifiées (start et end)

APTR U3D_MotionCaptureJoin(APTR MoCapture,APTR MoCapture2,UBYTE* name,ULONG FRnb);
Joint deux animations dans une nouvelle animation. FRnb est le temps (en frames) ajouté entre les 2 animations. Les deux Animations doivent avoir les mêmes Bones et vitesse (exprimée en Fps)

APTR U3D_MotionCaptureFx(APTR MoCapture,UBYTE* name,APTR Thing,float param,ULONG mode);
Applique une effet spécial (FX) à cette Motion-Capture
mode peut être 
U3D_MOCAPTURE_CLEAN alors nettoye la Motion-Capture pour cette Instance(à mettre dans Thing): en gardant que les animations des Bones qui existent vraiment dans cette Instance donc économise la mémoire
U3D_MOCAPTURE_REVERT retourne l'animation Motion-Capture à l'envers
U3D_MOCAPTURE_RESAMPLE recalcule l'animation pour cette vitesse FPS (à mettre dans param): Ainsi une  Motion-Capture de 120 fps convertie à 20 fps utilisera 6 fois moins de mémoire

On peut aussi faire
U3D_SetValue(MoCapture,U3D_FPS,30);
qui définit juste une nouvelle vitesse FPS (ici 30) pour une animation mais laisse les données de l'animation et donc sa consommation mémoire inchangée

Parametres de fonctions
voir dans Microbe3D.h


Colored Lights + bones + .bvh animation

Nice model + Lights + background
Using AREXX

Now with  v33 you can use Arexx to write Microbe3D programs: no need to know the C langage

See Demo-arexx.rexx to Demo-arexx4.rexx for examples like this one

/*=================================================================*/
/* Microbe3D loading */
if ~show('l',"Microbe3D.library") then
   addlib("Microbe3D.library",0,-30,0)
/*=================================================================*/
NULL=0
TRUE=1
FALSE=0
Scene=0
Object=0
Instance=0
Material=0
Material2=0
VanillaKey=0

/* U3D_SetValue(Scene,U3D_REXXDEBUG,TRUE) */
    Scene =U3D_EasyOpenScene('Rexx Demo',300,300)
 

    Object=U3D_Read(Scene,'data/AmiLogo.obj')        /* load a 3D object */
    U3D_Unitize(Object,2.0)                                    /* fit to screen (ie -1.0 +1.0) */
    U3D_Normals(Object,0.0)                                    /* do simple face normals */
    U3D_GridWeld(Object,(1.0/300.0),0.001,0.001)                    /* will remove the double points not visible on screen¤¤*/

    Material =U3D_Find(Object,U3D_MATERIAL,'mat_white_plastic')            /* obtain current logo's material */
    Material2=U3D_Find(Object,U3D_MATERIAL,'mat_cubemapxpos')            /* find the env mapping cube called 'mat_cubemapxpos' */
    U3D_SetSpecialMaterial(Object,Material,Material2,U3D_MATENVCUBE)        /* apply cub env mapping */

    Instance=U3D_AddInstance(Scene,Object,'Instance')                /* add to scene */

    U3D_SetValue(Scene,U3D_FPSLIMIT,10)

    echo 'Esc for quit '
    do while(VanillaKey < 1)
       U3D_Rotate(Instance,3.0,1.0,4.0,U3D_CHANGE)                /* rotate logo */
        U3D_DrawScene(Scene)                                /* draw all */
        VanillaKey    =U3D_QueryValue(Scene,U3D_VANILLAKEY)            /* get keyboard value */
    end

    U3D_Delete(Scene)

Microbe3D need a 80000 bytes stack so it patch Arexx (rexxsyslib.library) to make it use such a stack.
So the first time an Arexx program is started it may fail because the patch has not been yet applied
To avoid that I have created the RexxSysStack program :

  RexxSysStack 80000
will apply the patch to Arexx

  RexxSysStack OFF
will restaure Arexx to default (4096 stack) 
 

Utilisation avec AREXX

Désormais ave la v33 on peut utiliser Arexx pour écrire des progs Microbe3D : sans connaitre le C

Voir Demo-arexx.rexx to Demo-arexx4.rexx pour des exemples comme celui ci

/*=================================================================*/
/* Microbe3D loading */
if ~show('l',"Microbe3D.library") then
   addlib("Microbe3D.library",0,-30,0)
/*=================================================================*/
NULL=0
TRUE=1
FALSE=0
Scene=0
Object=0
Instance=0
Material=0
Material2=0
VanillaKey=0

/* U3D_SetValue(Scene,U3D_REXXDEBUG,TRUE) */
    Scene =U3D_EasyOpenScene('Rexx Demo',300,300)
 

    Object=U3D_Read(Scene,'data/AmiLogo.obj')        /* load a 3D object */
    U3D_Unitize(Object,2.0)                                    /* fit to screen (ie -1.0 +1.0) */
    U3D_Normals(Object,0.0)                                    /* do simple face normals */
    U3D_GridWeld(Object,(1.0/300.0),0.001,0.001)                    /* will remove the double points not visible on screen¤¤*/

    Material =U3D_Find(Object,U3D_MATERIAL,'mat_white_plastic')            /* obtain current logo's material */
    Material2=U3D_Find(Object,U3D_MATERIAL,'mat_cubemapxpos')            /* find the env mapping cube called 'mat_cubemapxpos' */
    U3D_SetSpecialMaterial(Object,Material,Material2,U3D_MATENVCUBE)        /* apply cub env mapping */

    Instance=U3D_AddInstance(Scene,Object,'Instance')                /* add to scene */

    U3D_SetValue(Scene,U3D_FPSLIMIT,10)

    echo 'Esc for quit '
    do while(VanillaKey < 1)
        U3D_Rotate(Instance,3.0,1.0,4.0,U3D_CHANGE)                /* rotate logo */
        U3D_DrawScene(Scene)                                /* draw all */
        VanillaKey    =U3D_QueryValue(Scene,U3D_VANILLAKEY)            /* get keyboard value */
    end

    U3D_Delete(Scene)

Microbe3D a besoin d'une stack(pile) de 80000 octets donc il patche Arexx (rexxsyslib.library) pour lui faire utiliser une telle stack.
Ainsi au premier lancement d'un prog Arexx cela peut échouer car le patch a pas été encore appliqué
Pour éviter ça j'ai créé le programme RexxSysStack :

  RexxSysStack 80000
applique le patch à Arexx

  RexxSysStack OFF
restaure Arexx à sa stack par default (4096 stack) 

Microbe3D Rexx Support Functions
Microbe3D was intended to be used with C langage. 
So some manipulations of data may be impossible with Arexx (pointers, reading/writing structures in memory, etc...)
So to help Arexx coders I have added some Rexx Support Functions for manipulating data in memory (pointer is a memory adresse)
The RexxSetXXX functions write in memory. The RexxGetXXX functions read in memory. 

x=RexxGetFloat(pointer) 
name=RexxGetName(pointer) 
ok=RexxSetColor(pointer,0.50,0.40,1.00,1.00)
ok=RexxSetFloat(pointer,0.2) 
ok=RexxSetName(pointer,'new name') 
ok=RexxSetVertex(pointer,0.9,0.9,0.9) 

MoCapture1=U3D_Get(Scene,U3D_MOCAPTURE,1)
say "MC1:"MoCapture1
NamePtr1=U3D_Name(MoCapture1)
say "MC1:"U3D_RexxGetName(NamePtr1)

U3D_REXXMEMORY
Also as memory/allocation freeing is not very easy with Arexx I have created a small memory buffer in the Scene that can be used for manipulating data in memory
This buffer acts like a 256 bytes array

   Color1=U3D_Get(Scene,U3D_REXXMEMORY,0)            /*  memory position 0  in arexx reserved memory */
    Color2=U3D_Get(Scene,U3D_REXXMEMORY,16)           /*  memory position 16 in arexx reserved memory */

Example of usage

    Color1=U3D_Get(Scene,U3D_REXXMEMORY,0)            /* use 16 bytes (=4 floats) at memory position 0 in arexx reserved memory */
    Light=U3D_Get(Scene,U3D_LIGHT,1)
    U3D_RexxSetColor(Color1,1.00,0.50,0.00,1.00)        /* orange */
    U3D_SetLight(Light,TRUE,Color1)
    U3D_Translate(Light,-0.93,0.93,1.00,U3D_RESET) 

    Color2=U3D_Get(Scene,U3D_REXXMEMORY,16)            /* use 16 bytes (=4 floats) at memory position 16 in arexx reserved memory */
    Light=U3D_Get(Scene,U3D_LIGHT,2)
    U3D_RexxSetColor(Color2,0.50,0.40,1.00,1.00)        /* light blue */
    U3D_SetLight(Light,TRUE,Color2)
    U3D_Translate(Light,0.93,-0.93,1.00,U3D_RESET) 
 

Fonctions Support Rexx de Microbe3D
Microbe3D a été conçu pour être utilisé avec le langage C. Ainsi certaines manipulations de données peuvent être impossibles avec Arexx (pointeurs, lecture / écriture de structures en mémoire, etc ...)
Alors pour aider les codeurs AREXX j'ai ajouté quelques fonctions de soutien Rexx pour manipuler des données en mémoire (pointeur est une adresse en mémoire)
Les fonctions RexxSetXXX vont écrire en mémoire. Les fonctions RexxGetXXX vont lire en mémoire.

x = RexxGetFloat (pointeur)
nom = RexxGetName (pointeur)
ok = RexxSetColor (pointeur, 0.50,0.40,1.00,1.00)
ok = RexxSetFloat (pointeur, 0,2)
ok = RexxSetName (pointeur, 'nouveau nom')
ok = RexxSetVertex (pointeur, 0.9,0.9,0.9)

MoCapture1=U3D_Get(Scene,U3D_MOCAPTURE,1)
say "MC1:"MoCapture1
NamePtr1=U3D_Name(MoCapture1)
say "MC1:"U3D_RexxGetName(NamePtr1)

U3D_REXXMEMORY
Comme l'allocation/libération de mémoire est pas très facile avec Arexx J'ai créé une petite mémoire tampon dans la scène qui peut être utilisé pour manipuler des données en mémoire
Ce tampon agit comme un tableau de 256 octets

    Color1=U3D_Get(Scene,U3D_REXXMEMORY,0)            /*  memory position 0  in arexx reserved memory */
     Color2=U3D_Get(Scene,U3D_REXXMEMORY,16)           /*  memory position 16 in arexx reserved memory */

Example d'utilisation

    Color1=U3D_Get(Scene,U3D_REXXMEMORY,0)            /* use 16 bytes (=4 floats) at memory position 0 in arexx reserved memory */
    Light=U3D_Get(Scene,U3D_LIGHT,1)
    U3D_RexxSetColor(Color1,1.00,0.50,0.00,1.00)        /* orange */
    U3D_SetLight(Light,TRUE,Color1)
    U3D_Translate(Light,-0.93,0.93,1.00,U3D_RESET) 

    Color2=U3D_Get(Scene,U3D_REXXMEMORY,16)            /* use 16 bytes (=4 floats) at memory position 16 in arexx reserved memory */
    Light=U3D_Get(Scene,U3D_LIGHT,2)
    U3D_RexxSetColor(Color2,0.50,0.40,1.00,1.00)        /* light blue */
    U3D_SetLight(Light,TRUE,Color2)
    U3D_Translate(Light,0.93,-0.93,1.00,U3D_RESET)