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
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 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¶
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
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
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 ...
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 :
- Scene : The root object which is a 3D space where all other object can be placed.
- Entity : A parent object which have a position a rotation and a size in the scene.
- 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.- Meshes : Class that contains geometry data loaded from .obj files and used by materials.
- Shaders : Parsing class of .glsl files to OpenGL shader which is used by programs.
- Programs : Class to mix shaders (vertex, fragment ...) to create OpenGL programs which is used by materials.
- Textures : Images used by materials.
- Materials : Regroup all required data (textures, buffers, uniforms) of GLSL shaders which is used by a drawer.
- 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.
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 :
- XML (extensions: xml)
- INI (extensions: ini)
- 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.
Members
Manager: Philippe VERLEY, Tristan Muller
Developer: Florian de Boissieu, Francois Pimont, Philippe VERLEY, Thomas ARSOUZE, Tristan Muller
Modeler: Dav Ebengo, Grégoire Vincent, James Ball
User: Timothy Devereux