Overview

AMAPVox, LiDAR data voxelisation software

Moved to https://forge.ird.fr/amap/amapvox

Copyright (c) https://www.ird.fr (Institut de Recherche pour le Développement) 2016-2023

https://amapvox.org

Reference

Research paper first describing AMAPVox:

Vincent, G., Antin, C., Laurans, M., Heurtebize, J., Durrieu, S., Lavalley, C., & Dauzat, J. (2017). Mapping plant area index of tropical evergreen forest by airborne laser scanning. A cross-validation study using LAI2200 optical sensor. Remote Sensing of Environment, 198, 254-266.

https://doi.org/10.1016/j.rse.2017.05.034

Up-to-date description of PAD/LAD estimators implemented in AMAPVox:

VINCENT, Gregoire; PIMONT, François; VERLEY, Philippe, 2021, "A note on PAD/LAD estimators implemented in AMAPVox 1.7", https://doi.org/10.23708/1AJNMP, DataSuds, V1

Contact

For questions, feedback and bug reporting

Senior scientist: Grégoire Vincent (IRD) gregoire dot vincent at ird.fr

Main developper: Philippe Verley (IRD) philippe dot verley at ird.fr

Download

We recommend using AMAPVox through dedicated R package AMAPVox https://amapvox.org

Java binaries at http://amap-dev.cirad.fr/projects/amapvox/files

Release history http://amap-dev.cirad.fr/projects/amapvox/wiki/Release_history

Source code (access on demand)

git clone http://amap-dev.cirad.fr/git/amapvox.git

Requirement

A 64 bit Operating System and a 64 bit java binary are mandatory.

License

AMAPVox is governed by the CeCILL-B license under French law and abiding by the rules of distribution of free software. You can use, modify and/ or redistribute the software under the terms of the CeCILL-B license as circulated by CEA, CNRS and INRIA at the following URL "http://www.cecill.info".


amapvox: README

AMAPVox readme file

http://www.amapvox.org

LiDAR data voxelisation software.

Copyright (c) IRD (Institut de Recherche pour le Développement) 2016-2019

Reference

Vincent, G., Antin, C., Laurans, M., Heurtebize, J., Durrieu, S., Lavalley, C., & Dauzat, J. (2017). Mapping plant area index of tropical evergreen forest by airborne laser scanning. A cross-validation study using LAI2200 optical sensor. Remote Sensing of Environment, 198, 254-266.

https://doi.org/10.1016/j.rse.2017.05.034

Contact

For questions, feedback and bug reporting contact@amapvox.org

Senior scientist: Grégoire Vincent (IRD) gregoire dot vincent at ird.fr

Main developper: Philippe Verley (IRD) philippe dot verley at ird.fr

Download

Binaries at http://amap-dev.cirad.fr/projects/amapvox/wiki

Source code git clone http://amap-dev.cirad.fr/git/amapvox.git

Requirement

A 64 bit Operating System and a 64 bit java binary are mandatory.

License

AMAPVox is governed by the CeCILL-B license under French law and abiding by the rules of distribution of free software. You can use, modify and/ or redistribute the software under the terms of the CeCILL-B license as circulated by CEA, CNRS and INRIA at the following URL "http://www.cecill.info".

EOF

commons-spds: README

SpDS

Spatial data structures to speed up the searches.

Installation with Maven

Add the following repository :

<repository>
    <id>amap-maven-central</id>
    <name>libs-release</name>
    <url>http://manosque.cirad.fr:8081/artifactory/libs-release-local</url>
</repository>

And the following dependency:

<dependency>
    <groupId>fr.amap.commons</groupId>
    <artifactId>commons-spds</artifactId>
    <version>1.0.0</version>
</dependency>

Usage

//create an octree with a maximum number of points of 50 for a leaf node
Octree<Point3D> octree = new Octree(50);

//set array of points
octree.setPoints(new Point3D[]{});

try {
    //don't forget to build the octree
    octree.build();

    //search the closest point of the given point within the given search radius
    Point3D nearestPoint = octree.searchNearestPoint(new Point3D(5.0, 1.0, 6), Octree.INCREMENTAL_SEARCH, 0.0001f);
    if(nearestPoint != null){
        System.out.println("Point found : ("+ nearestPoint.x+" "+nearestPoint.y+" "+nearestPoint.z+")");
    }

} catch (Exception ex) {
    Logger.getLogger(Octree.class.getName()).log(Level.SEVERE, null, ex);
}

format-riegl: README

JRiegl

Installation with Maven

Add the following repository :

<repository>
    <id>amap-maven-central</id>
    <name>libs-release</name>
    <url>http://manosque.cirad.fr:8081/artifactory/libs-release-local</url>
</repository>

And the following dependency:

<dependency>
    <groupId>fr.amap.lidar</groupId>
    <artifactId>format-riegl</artifactId>
    <version>1.0.1</version>
</dependency>

Usage

Use case : read a Riscan Project File (*.rsp) :


Rsp rsp = new Rsp();

try {
    rsp.read(new File("/media/forestview01/BDLidar/TLS/Paracou2014/FTH2014.RiSCAN/project.rsp"));

    System.out.println("Riscan project POP matrix : \n"+rsp.getPopMatrix().toString()+"\n");

    ArrayList<Scans> rxpList = rsp.getRxpList();

    System.out.println("Scans list :\n");

    for(Scans scans : rxpList){

        System.out.println("Scan name :"+scans.getName());

        System.out.println("Scan SOP matrix :\n"+scans.getSopMatrix());

        System.out.println("Rxp file path :"+scans.getScanFull().getAbsolutePath()+"\n");
    }

} catch (JDOMException ex) {
    Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
} catch (IOException ex) {
    Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
}

Use case : read a *.rxp file :

RxpExtraction rxpReader = new RxpExtraction();

try {
    rxpReader.openRxpFile(new File("/home/Documents/sample.rxp"), RxpExtraction.REFLECTANCE, RxpExtraction.AMPLITUDE, RxpExtraction.DEVIATION, RxpExtraction.TIME); //select echoes attrbutes to import

    Iterator<Shot> iterator = rxpReader.iterator();

    while(iterator.hasNext()){

        Shot shot = iterator.next();

        int ptIndex = 0;

        for(double range : shot.ranges){

            double ptX = shot.origin.x + shot.direction.x * range;
            double ptY = shot.origin.y + shot.direction.y * range;
            double ptZ = shot.origin.z + shot.direction.z * range;

            System.out.println(ptX+"\t"+ptY+"\t"+ptZ+"\t"+shot.reflectances[ptIndex]+"\t"+
                    shot.deviations[ptIndex]+"\t"+shot.amplitudes[ptIndex]+"\t"+shot.times[ptIndex]);

            ptIndex++;
        }                
    }

} catch (Exception ex) {
    Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
}finally{
    rxpReader.close();
}

format-las: README

JLas

Installation with Maven

Add the following repository :

<repository>
    <id>amap-maven-central</id>
    <name>libs-release</name>
    <url>http://manosque.cirad.fr:8081/artifactory/libs-release-local</url>
</repository>

And the following dependency:

<dependency>
    <groupId>fr.amap.lidar</groupId>
    <artifactId>format-las</artifactId>
    <version>1.0.0</version>
</dependency>

Usage

The JLas library allows to read files in the .las or .laz format from Java language in the most easiest way.
The .las reader is using pure Java language, however the .laz reader uses a wrapper of the laszip library.

Las reader features:

Read las header
Read las format until 1.4
Read las point format until format 3

You cannot :

Write las file

Laz reader features:

Read las format until 1.4
Read las point format until format 1.0
Read las point attributes : x, y, z, echo range, echo number, echo recording time, echo intensity, echo classification

You cannot :

Write laz file
Read other attributes than x, y, z, echo range, echo number, echo recording time, echo intensity, echo classification
Use this library with 32 bits JVM, and other systems than Windows and Linux.

Use case : read a *.laz file :

LazExtraction lazReader = new LazExtraction();

try {

    lazReader.openLazFile(new File("/home/Documents/sample.laz"));

    //read header
    LasHeader header = lazReader.getHeader();

    System.out.println("Number of point records : "+header.getNumberOfPointrecords());

    //get the points from the file 
    Iterator<LasPoint> iterator = lazReader.iterator();

    while(iterator.hasNext()){

        LasPoint point = iterator.next();

        double ptX = header.getxOffset() + point.x * header.getxScaleFactor();
        double ptY = header.getyOffset() + point.y * header.getyScaleFactor();
        double ptZ = header.getzOffset() + point.z * header.getzScaleFactor();

        System.out.println(ptX+"\t"+ptY+"\t"+ptZ);
    }

} catch (Exception ex) {
    Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
}finally{
    lazReader.close();
}

Use case : read a *.las file :

LasReader lasReader = new LasReader();

try {
    lasReader.open(new File("/home/Documents/sample.las"));

    LasHeader header = lasReader.getHeader();

    Iterator<PointDataRecordFormat> iterator = lasReader.iterator();

    while(iterator.hasNext()){

        PointDataRecordFormat point = iterator.next();

        double ptX = header.getxOffset() + point.getX() * header.getxScaleFactor();
        double ptY = header.getyOffset() + point.getY() * header.getyScaleFactor();
        double ptZ = header.getzOffset() + point.getZ() * header.getzScaleFactor();

        System.out.println(ptX+"\t"+ptY+"\t"+ptZ);
    }

} catch (Exception ex) {
    Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
}

format-gridded: README

JGridScan

Installation with Maven

Add the following repository :

<repository>
    <id>amap-maven-central</id>
    <name>libs-release</name>
    <url>http://manosque.cirad.fr:8081/artifactory/libs-release-local</url>
</repository>

And the following dependency:

<dependency>
    <groupId>fr.amap.lidar</groupId>
    <artifactId>format-gridded</artifactId>
    <version>1.0.0</version>
</dependency>

Usage

Use case: read a *.ptg file :

PTGReader ptgReader = new PTGReader();

try {
    File ptgFile = new File("/home/Documents/scan-1.ptg");

    ptgReader.openPTGFile(ptgFile);

    if(ptgReader.isAsciiFile()){ //the opened file contains the scan list

        List<File> scanList = ptgReader.getScanList();

        System.out.println("Scan list :\n");

        for(File file : scanList){
            System.out.println(file.getAbsolutePath());
        }

    }else{ //the opened file is a binary scan

        PTGScan scan = new PTGScan();

        try {
            scan.openScanFile(ptgFile);

            PTGHeader header = scan.getHeader();

            //get the transformation matrix of the scan
            Mat4D transfMatrix = header.getTransfMatrix();

            Iterator<LPoint> iterator = scan.iterator();

            while(iterator.hasNext()){

                LPoint point = iterator.next();

                double ptX, ptY, ptZ;

                if(header.isPointInFloatFormat()){
                    ptX = ((LFloatPoint)point).x;
                    ptY = ((LFloatPoint)point).y;
                    ptZ = ((LFloatPoint)point).z;
                }else{
                    ptX = ((LDoublePoint)point).x;
                    ptY = ((LDoublePoint)point).y;
                    ptZ = ((LDoublePoint)point).z;
                }

                Vec4D ptTransformed = Mat4D.multiply(transfMatrix, new Vec4D(ptX, ptY, ptZ, 1));

                System.out.println(ptTransformed.x+"\t"+ptTransformed.y+"\t"+ptTransformed.z);
            }


        } catch (Exception ex) {
            Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

} catch (IOException ex) {
    Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
}

Use case : read a *.ptx file :

PTXReader ptxReader = new PTXReader();

try {
    ptxReader.openPTXFile(new File("/home/Documents/sample.ptx"));

    List<PTXScan> singlesScans = ptxReader.getSinglesScans();

    if(ptxReader.getNbScans() > 0){

        PTXScan scan = singlesScans.get(0);
        PTXHeader header = scan.getHeader();

        Mat4D transfMatrix = header.getTransfMatrix();

        Iterator<LPoint> iterator = scan.iterator();

        while(iterator.hasNext()){

            LPoint point = iterator.next();

            double ptX, ptY, ptZ;

            if(header.isPointInFloatFormat()){
                ptX = ((LFloatPoint)point).x;
                ptY = ((LFloatPoint)point).y;
                ptZ = ((LFloatPoint)point).z;
            }else{
                ptX = ((LDoublePoint)point).x;
                ptY = ((LDoublePoint)point).y;
                ptZ = ((LDoublePoint)point).z;
            }

            Vec4D ptTransformed = Mat4D.multiply(transfMatrix, new Vec4D(ptX, ptY, ptZ, 1));

            System.out.println(ptTransformed.x+"\t"+ptTransformed.y+"\t"+ptTransformed.z);
        }
    }

} catch (IOException ex) {
    Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
}

threed-viewer: README

ThreedViewer

Simple 3D viewer based on jogl.

Installation with Maven

Add the following repository :

<repository>
    <id>amap-maven-central</id>
    <name>libs-release</name>
    <url>http://manosque.cirad.fr:8081/artifactory/libs-release-local</url>
</repository>

And the following dependency:

<dependency>
    <groupId>fr.amap.threed</groupId>
    <artifactId>threed-viewer</artifactId>
    <version>1.0.0</version>
</dependency>

Usage

1. Create a window with an OpenGL context

final Viewer3D viewer3D = new Viewer3D(0, 0, 500, 400, "OpenGL window");
viewer3D.show();

The code above create a window at location 0, 0 with a size of 500x400 and creates an OpenGL context.

2. Add a scene object

final Viewer3D viewer3D = new Viewer3D(0, 0, 500, 400, "OpenGL window");

SceneObject cube = new SimpleSceneObject(GLMeshFactory.createCube(2));        
viewer3D.getScene().addSceneObject(cube);
viewer3D.show();

The code above create a new SceneObject with a mesh representing a cube.
GLMeshFactory provides some methods to generate current primitives.

3. Bind a shader to an object

SceneObject cube = new SimpleSceneObject(GLMeshFactory.createCube(2));

//use a global shader, shared by any objects using this shader
cube.setShader(Scene.colorShader);

//or use an unique shader
cube.setShader(new ColorShader());

viewer3D.getScene().addSceneObject(cube);
Shader Variables Usage
SimpleShader uniform mat4 viewMatrix Camera transformation
uniform mat4 projMatrix Camera projection
uniform mat4 transformation Object transformation
uniform vec3 color Unique color
attribute vec4 position Vertex positions
ColorShader uniform mat4 viewMatrix Camera transformation
uniform mat4 projMatrix Camera projection
uniform mat4 transformation Object transformation
uniform vec3 color Vertex colors
attribute vec4 position Vertex positions
PhongShader uniform mat4 viewMatrix Camera transformation
uniform mat4 projMatrix Camera projection
uniform mat4 transformation Object transformation
uniform vec3 color Vertex colors
attribute vec3 position Vertex positions
attribute vec3 normal Vertex normales
InstanceShader/InstanceLightedShader uniform mat4 viewMatrix Camera transformation
uniform mat4 projMatrix Camera projection
attribute vec3 position Vertex positions
attribute vec3 instance_position Position of the object's instance
attribute vec4 instance_color Color of the object's instance
TextureShader uniform mat4 viewMatrixOrtho Camera transformation
uniform mat4 projMatrixOrtho Camera projection
attribute vec4 position Vertex positions
attribute vec2 textureCoordinates Vertex linked texture coordinates

The SimpleShader can be used when you want to draw an object with a single color and be able to move the object.

The ColorShader can be used to draw an object with a different color for each vertex.
This shader allows the object transformation too.

The PhongShader simulates a light with a phong model, built with specular, diffuse and ambiant colors. Those color values are fixed in the shader.

The InstanceShader/InstanceLighted shaders both allows to render multiple instances of an object, those instances can only be parametrized with their locations.
The InstanceLightedShader is the same as InstanceShader but simulate a prebuilt light. This one is specific and should not be used.

TextureShader is a shader handling texture coordinates. It can be used to draw head up display (HUD) on the screen.

Global uniforms :

The uniforms « viewMatrix » and « projMatrix » are updated from the Scene when the camera is updated.
This means you can create your own shader and those two variables will be automatically udpated.
In another hand, if you want to update your own view matrix and projection matrix, don't name your variables like the two above.

4. Scene object types

4.1. PointCloudSceneObject

Represents a point cloud.

-Provides methods to add points with attributes easily.

-Can be mouse pickable (explained after).

Use case : spherical point cloud creation with mouse picking

final Viewer3D viewer3D = new Viewer3D(0, 0, 500, 500, "3d view");
viewer3D.setDynamicDraw(true);
viewer3D.getAnimator().setUpdateFPSFrames(1, null);

PointCloudSceneObject pointCloud = new PointCloudSceneObject();
pointCloud.setMousePickable(true);

for (int i = 1; i < 180; i++) {

    for (int j = -179; j < 179; j++) {

        double theta = Math.toRadians(i);
        double phi = Math.toRadians(j);

        float x = (float)(10*Math.sin(theta)*Math.cos(phi));
        float y = (float)(10*Math.sin(theta)*Math.sin(phi));
        float z = (float)(10*Math.cos(theta));

        pointCloud.addPoint(x, y ,z);
        pointCloud.addValue("attribut", (float) (Math.random()*255));

    }
}

pointCloud.initMesh();
pointCloud.setShader(Scene.colorShader);

viewer3D.getScene().addSceneObject(pointCloud);

SceneObjectListener pointcloudListener = new SceneObjectListener() {
    @Override
    public void clicked(SceneObject sceneObject, MousePicker mousePicker) {

        Point3F point = (Point3F) sceneObject.doPicking(
                viewer3D.getScene().getMousePicker());

        if(point != null){
            viewer3D.getScene().getCamera().setLocation(
                    new Vec3F(point.x, point.y, point.z));
        }
    }
};

pointCloud.addSceneObjectListener(pointcloudListener);
viewer3D.show();

4.2. VoxelSpaceSceneObject

Scene object dedicated to display voxels.

-All voxels are drawn with a single draw call (instance rendering)
-Can be mouse pickable
-Handle filtering

4.3. RasterSceneObject

Represents a DTM.

-Is mouse pickable

Use case : load a dtm from a file and handle selection events
```java
final Viewer3D viewer3D = new Viewer3D(0, 0, 500, 500, "3d view");
viewer3D.setDynamicDraw(false);

RasterSceneObject dtm = new RasterSceneObject(
AsciiGridHelper.readFromAscFile(
new File("/media/example.asc")));

dtm.setMousePickable(true);

viewer3D.getScene().addSceneObject(dtm);

//add a camera listener
viewer3D.getScene().getCamera().addCameraListener(new CameraAdapter() {
@Override
public void locationChanged(Vec3F location) {
viewer3D.getScene().setLightPosition(viewer3D.getScene().getCamera().getLocation());
}
});

//add a scene object listener
SceneObjectListener objectListener = new SceneObjectListener() {
@Override
public void clicked(SceneObject sceneObject, MousePicker mousePicker) {

    Integer index = ((RasterSceneObject)sceneObject).doPicking(mousePicker);

    if(index != null){
        Point3F position = ((RasterSceneObject)sceneObject).getVertex(index);
        System.out.println(position.x + " "+position.y+ " "+position.z);
    }
}

};

dtm.addSceneObjectListener(objectListener);

viewer3D.show();
```

4.4. SimpleSceneObject

Represents a simple scene object.

-Draw the provided mesh

Use case : create a colored triangle

final Viewer3D viewer3D = new Viewer3D(0, 0, 500, 500, "3d view");
viewer3D.setDynamicDraw(false);

GLMesh mesh = new SimpleGLMesh();

float vertexData[] = new float[]
{-2.0f, 2.0f, 2.0f,
2.0f, 2.0f, 2.0f,
-2.0f, -2.0f, -2.0f};

float colorData[] = new float[]
{1.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f,
0.0f, 0.0f, 1.0f};

int indexData[] = new int[]
{0, 1, 2};

mesh.setVertexBuffer(Buffers.newDirectFloatBuffer(vertexData));
mesh.indexBuffer = Buffers.newDirectIntBuffer(indexData);
mesh.colorBuffer = Buffers.newDirectFloatBuffer(colorData);
mesh.vertexCount = indexData.length;

SimpleSceneObject sceneObject = new SimpleSceneObject(mesh);
sceneObject.setShader(new ColorShader());

viewer3D.getScene().addSceneObject(sceneObject);

viewer3D.show();

5. Set up camera

The default implemented camera is a trackball camera.
You can configure the target of the camera (where it looks at) and its position.

final Viewer3D viewer3D = new Viewer3D(0, 0, 500, 500, "3d view");
viewer3D.setDynamicDraw(false);

SimpleSceneObject sceneObject = new SimpleSceneObject(GLMeshFactory.createCube(2));

//set the scene object as the pivot
viewer3D.getScene().getCamera().setPivot(sceneObject);

//set the camera location
viewer3D.getScene().getCamera().setLocation(new Vec3F(10, 50, 40));

viewer3D.getScene().addSceneObject(sceneObject);

viewer3D.show();

By default the pivot of the camera is the first scene object added to the scene.
Its default location is configured as the first scene object gravity center, plus x, y, z offsets.

6. Set up light

This part is useful if you use the phong shader, because this shader use the light position information to compute the mesh color.

final Viewer3D viewer3D = new Viewer3D(0, 0, 500, 500, "3d view");
viewer3D.setDynamicDraw(false);

SimpleSceneObject sceneObject = new SimpleSceneObject(GLMeshFactory.createCube(2));
sceneObject.setShader(new PhongShader());

sceneObject.setMousePickable(true);

viewer3D.getScene().addSceneObject(sceneObject);

//add a camera listener
viewer3D.getScene().getCamera().addCameraListener(new CameraAdapter() {
    @Override
    public void locationChanged(Vec3F location) {
        viewer3D.getScene().setLightPosition(
                viewer3D.getScene().getCamera().getLocation());
    }
});

viewer3D.show();

This code display a cube with a shader that handles light, and move the light according to the camera position.

7. Add keyboard, mouse, window listeners

To get access to the windows events ( window resizing, keyboard, mouse), you should get the GLRenderFrame. It provides access to all of those.

7.1. Add a mouse listener

viewer3D.getRenderFrame().addMouseListener(new MouseListener() {
    @Override
    public void mouseClicked(MouseEvent e) {}

    @Override
    public void mouseEntered(MouseEvent e) {}

    @Override
    public void mouseExited(MouseEvent e) {}

    @Override
    public void mousePressed(MouseEvent e) {}

    @Override
    public void mouseReleased(MouseEvent e) {}

    @Override
    public void mouseMoved(MouseEvent e) {}

    @Override
    public void mouseDragged(MouseEvent e) {}

    @Override
    public void mouseWheelMoved(MouseEvent e) {}
});

7.2. Add a keyboard listener

viewer3D.getRenderFrame().addKeyListener(new KeyListener() {
    @Override
    public void keyPressed(KeyEvent e) {}

    @Override
    public void keyReleased(KeyEvent e) {}
});

7.3. Add a window listener

viewer3D.getRenderFrame().addWindowListener(new WindowListener() {
    @Override
    public void windowResized(WindowEvent e) {}

    @Override
    public void windowMoved(WindowEvent e) {}

    @Override
    public void windowDestroyNotify(WindowEvent e) {}

    @Override
    public void windowDestroyed(WindowEvent e) {}

    @Override
    public void windowGainedFocus(WindowEvent e) {}

    @Override
    public void windowLostFocus(WindowEvent e) {}

    @Override
    public void windowRepaint(WindowUpdateEvent e) {}
});

8. Handling events

The Viewer3D add automatically a default event manager at instantiation.
This default event manager provides the following functionnalities :

Command Action
Middle Mouse button clicked update mouse picker
Left mouse button down + mouse dragging rotate camera
Right mouse button down + mouse dragging camera side translation
Mouse wheel down/up  camera forward translation
D key down move light to the right
Q key down move light to the left
Z key down move light to top
S key down move light to bottom
Numpad 1 pressed set camera to look at the front side
Numpad 1 pressed + ctrl left down set camera to look at the back side
Numpad 3 pressed set camera to look at the right side
Numpad 3 pressed + ctrl left down Set camera to look at the left side
Numpad 7 pressed set camera to look at the top side
Numpad 7 pressed + ctrl left down set camera to look at the bottom side

If you wish you can override the default comportment with the call to « viewer3D.removeDefaultEventManager() ».
Then you can add your event manager.

//remove the default event manager
viewer3D.removeDefaultEventManager();

viewer3D.addEventListener(new EventManager(new InputMouseAdapter(), new InputKeyListener()) {
    @Override
    public void updateEvents() {
        //handle the events here

        //get access to the mouse
        mouse.isButtonDown(InputMouseAdapter.Button.LEFT);

        //get access to the keyboard
        keyboard.isKeyDown(KeyEvent.VK_E);
    }
});

engine3d: README

AMAPVox - Engine 3D

logo

3D engine that can be used to display different kind of models with an
high optimization. By default it is used by AMAPVox to display wide group of voxels.

Features

  • Multiple draw mode (see the image below)
  • Optimization of the drawing functions (opengl: instancing).
  • Easily expandable heart (entity / component system).
  • Construction of "scenes" in high level programming and abstraction of complex low level systems.
  • Multi-cameras.
  • Import 3D models in obj format.
  • Discarding transparency.
  • Skyboxes, textures, inputs ...

drawingMatrix

Third-party libraries

  • JOGL - with OpenGL version 3
  • JOML - Mathematics for 3d rendering

Architecture

The project is divided into two big sections : behaviours and resources :

  • The behaviours contains all "controller" classes organized hierarchycally like that :

    1. Scene : The root object which is a 3D space where all other object can be placed.
    2. Entity : A parent object which have a position a rotation and a size in the scene.
    3. Component : An object which is added to an entity to perform some task and communicate with others components.
  • The resources contains all "data" classes that can be loaded
    from a file and used by a component.

    1. Meshes : Class that contains geometry data loaded from .obj files and used by materials.
    2. Shaders : Parsing class of .glsl files to OpenGL shader which is used by programs.
    3. Programs : Class to mix shaders (vertex, fragment ...) to create OpenGL programs which is used by materials.
    4. Textures : Images used by materials.
    5. Materials : Regroup all required data (textures, buffers, uniforms) of GLSL shaders which is used by a drawer.
    6. Drawers : Mix a mesh and a material to display one with respect to the other.
      • PointDrawer : Draw pixels only.
      • DraftDrawer : Draw lines and pixels.
      • LitDrawer : Draw quads or triangles or lines or pixels automatically.

architecture

Getting started

The start point to use this project is to create an Application3D object (or extends it).
The next step is to create a scene in the onLoad() method.

After that, you just have to see each "resources" and "behaviours" class,
like described above. All you need will be explain to you as you going through the documentation.

/* Create an Application3D object with AWT containers */
new Application3D() {
    /* Implement onLoad to create the scene */
    @Override
    protected void onLoad() throws Exception {
        /* Create resources */
        final Mesh mesh = new FacedCube();
        final SimpleMaterial material = new SimpleMaterial();

        /* Create entities */
        final Entity cameraControllerEntity = new Entity();
        cameraControllerEntity.addComponent(new RotationController());
        addEntity(cameraControllerEntity);

        final Entity cameraEntity = new Entity();
        cameraEntity.getTransform().getPosition().set(0, 0, 5);
        cameraEntity.setParent(cameraControllerEntity);
        final Camera camera = new Camera();
        camera.addLayout(Layout.DEFAULT);
        cameraEntity.addComponent(camera);
        cameraEntity.addComponent(new CameraZoomController());
        addEntity(cameraEntity);

        final Entity rendererEntity = new Entity();
        rendererEntity.setLayout(Layout.DEFAULT);
        final Renderer renderer = new Renderer(
                new LitDrawer(material, mesh));

        rendererEntity.addComponent(renderer);
        addEntity(rendererEntity);
    }

    /* Specify what happen when the application stop (optionnal) */
    @Override
    protected void onExit() {
        System.exit(0);
    }
}.getFrame3D().setVisible(true); /* Use the AWT element you want */

Licence

This software is governed by the CeCILL-B license under French law and
abiding by the rules of distribution of free software. You can use, modify
and/ or redistribute the software under the terms of the CeCILL-B license as
circulated by CEA, CNRS and INRIA at the following URL "http://www.cecill.info".

As a counterpart to the access to the source code and rights to copy, modify
and redistribute granted by the license, users are provided only with a
limited warranty and the software's author, the holder of the economic
rights, and the successive licensors have only limited liability.

In this respect, the user's attention is drawn to the risks associated with
loading, using, modifying and/or developing or reproducing the software by
the user in light of its specific status of free software, that may mean that
it is complicated to manipulate, and that also therefore means that it is
reserved for developers and experienced professionals having in-depth
computer knowledge. Users are therefore encouraged to load and test the
software's suitability as regards their requirements in conditions enabling
the security of their systems and/or data to be ensured and, more generally,
to use and operate it in the same conditions as regards security.

The fact that you are presently reading this means that you have had
knowledge of the CeCILL-B license and that you accept its terms.

serialization: README

AMAPVox - Serialization

AMAPVox Serialization, as his name suggests,
is a system to perform serialization.

The goal is to write and read entire objects,
built like classes with an unlimited hierarchy.
And make it possible to do that with all available formats
in java.

Getting started

1. Create a serializable class

The first things we need, is somethings to serialize. To do that,
we need to use @Serializable annotation like so :

@Serializable(name = "mySerializable") // serializable class
class MySerializable {
    @Serializable(name = "name") // serializable field
    private String name;

    @Serializable(name = "value") // serializable field with serializable type
    private mySerializableClass value;

    private boolean enabled; // not serializable field
}

The types of object you can set as @Serializable
are limited to (others types will be ignored) :

  • Primitives types (int, float, double, long, short, byte, char, String).
  • Arrays of primitives and serializables objects (ex. MySerializable[] array).
  • Collections of primitives and serializables objects.

2. Perform reading and writting processes

Now you just have to create an object of MySerializable :

    MySerializable s = new MySerializable();
    // change properties... s.setName([...]) etc...

To write or read this object you can use the Serialization class :

    Serialization.write("data.xml", s, XMLFormat.class); // write to XML file
    MySerializable readed = Serialization.read("data.xml", XMLFormat.class); // read from XML file

And it's done !

Availables formats

In the version 1.0.0, there is 3 formats availables :

  1. XML (extensions: xml)
  2. INI (extensions: ini)
  3. Properties (extensions: properties)

But it is possible to create new formats yourself by creating a sub class of Formatter :

public class MyFormatter extends Formatter<MyWriter, MyReader> {
    @Override
    protected MyWriter createWriter() {
        // return a writter object (ex. FileWriter)
    }

    @Override
    protected MyWriter writeNode(MyWriter writer, String[] parentNames, 
            String name, String description, String value) {
        // write a node (ex. <xml_node />) and return the writer.
    }

    @Override
    protected void writeFile(MyWriter writer, File file) {
        // write the file with the writer
    }

    @Override
    protected MyReader createReader(File file) {
        // return a reader object (ex. BufferedFileReader)
    }

    @Override
    protected MyReader readNode(MyReader reader, String name) {
        // read a node (ex. <xml_node />
    }

    @Override
    protected String readValue(MyReader reader, 
            String[] parentNames, String name) {
        // read a node value (ex. ini_node.value=value)
    }
}

Licence

This software is governed by the CeCILL-B license under French law and
abiding by the rules of distribution of free software. You can use, modify
and/ or redistribute the software under the terms of the CeCILL-B license as
circulated by CEA, CNRS and INRIA at the following URL "http://www.cecill.info".

As a counterpart to the access to the source code and rights to copy, modify
and redistribute granted by the license, users are provided only with a
limited warranty and the software's author, the holder of the economic
rights, and the successive licensors have only limited liability.

In this respect, the user's attention is drawn to the risks associated with
loading, using, modifying and/or developing or reproducing the software by
the user in light of its specific status of free software, that may mean that
it is complicated to manipulate, and that also therefore means that it is
reserved for developers and experienced professionals having in-depth
computer knowledge. Users are therefore encouraged to load and test the
software's suitability as regards their requirements in conditions enabling
the security of their systems and/or data to be ensured and, more generally,
to use and operate it in the same conditions as regards security.