diff --git a/.gitignore b/.gitignore index 531464e..b18a082 100644 --- a/.gitignore +++ b/.gitignore @@ -68,4 +68,7 @@ build/ *.o ## Emacs backup files -*~ \ No newline at end of file +*~ + +## Packr dist folder +dist/ \ No newline at end of file diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..b151a6a --- /dev/null +++ b/Makefile @@ -0,0 +1,8 @@ +PACKR = java -jar /home/miky/Descargas/packr.jar +PACKR_CONF = packr.json + +all: + cd desktop/jni; $(MAKE) $(MFLAGS) + cd ../.. + ./gradlew desktop:dist + $(PACKR) $(PACKR_CONF) diff --git a/core/src/ve/ucv/ciens/icaro/ardemo/EviDemo.java b/core/src/ve/ucv/ciens/icaro/ardemo/EviDemo.java index 6cf59e5..c90e91e 100644 --- a/core/src/ve/ucv/ciens/icaro/ardemo/EviDemo.java +++ b/core/src/ve/ucv/ciens/icaro/ardemo/EviDemo.java @@ -13,16 +13,15 @@ import com.badlogic.gdx.graphics.g2d.SpriteBatch; import com.badlogic.gdx.graphics.g3d.Model; import com.badlogic.gdx.graphics.g3d.ModelBatch; +/** + * This is the core class of the demo. It handles all resource loading and rendering. + * + * @author Miguel Angel Astor Romero + */ public class EviDemo extends ApplicationAdapter { private static final String TAG = "EVI DEMO - CORE"; private static final String CLASS_NAME = EviDemo.class.getSimpleName(); - private static final int W = 640; - private static final int H = 360; - private static final float NEAR = 0.01f; - private static final float FAR = 10.0f; - private static final int CODE = 213; - private ImageProcessor cvProc; private Texture tex; private Pixmap frame; @@ -61,9 +60,9 @@ public class EviDemo extends ApplicationAdapter { manager = new AssetManager(); manager.load("monkey.g3db", Model.class); - camera = new CustomPerspectiveCamera(67, W, H); - camera.near = NEAR; - camera.far = FAR; + camera = new CustomPerspectiveCamera(67, ProjectConstants.W, ProjectConstants.H); + camera.near = ProjectConstants.NEAR; + camera.far = ProjectConstants.FAR; camera.translate(0.0f, 0.0f, 0.0f); camera.lookAt(0.0f, 0.0f, -1.0f); camera.update(); @@ -81,10 +80,13 @@ public class EviDemo extends ApplicationAdapter { public void render () { float focalPointX, focalPointY, cameraCenterX, cameraCenterY; - Gdx.gl.glClearColor(1, 0, 0, 1); + Gdx.gl.glClearColor(0, 0, 0, 1); Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT | GL20.GL_DEPTH_BUFFER_BIT); if(doneLoading) { + /* + * When all resources are loaded we can start the rendering. + */ if(cvProc.isCameraCalibrated()) { data = cvProc.findMarkersInFrame(); @@ -92,7 +94,7 @@ public class EviDemo extends ApplicationAdapter { if(data != null) { for(int i = 0; i < ProjectConstants.MAXIMUM_NUMBER_OF_MARKERS; i++) { - if(data.markerCodes[i] == CODE) { + if(data.markerCodes[i] == ProjectConstants.CODE) { monkey.position.set(data.translationVectors[i]); monkey.rotation.set(data.rotationMatrices[i]); monkey.applyWorldTransform(); @@ -104,7 +106,16 @@ public class EviDemo extends ApplicationAdapter { focalPointY = cvProc.getFocalPointY(); cameraCenterX = cvProc.getCameraCenterX(); cameraCenterY = cvProc.getCameraCenterY(); - camera.setCustomARProjectionMatrix(focalPointX, focalPointY, cameraCenterX, cameraCenterY, NEAR, FAR, W, H); + camera.setCustomARProjectionMatrix( + focalPointX, + focalPointY, + cameraCenterX, + cameraCenterY, + ProjectConstants.NEAR, + ProjectConstants.FAR, + ProjectConstants.W, + ProjectConstants.H + ); camera.update(camera.projection); frame = new Pixmap(data.outFrame, 0, data.outFrame.length); @@ -135,7 +146,6 @@ public class EviDemo extends ApplicationAdapter { // Save the calibration points to the samples array. for(int i = 0; i < calib.calibrationPoints.length; i += 2){ - Gdx.app.log(TAG, CLASS_NAME + ".render(): Value " + Integer.toString(i) + " = (" + Float.toString(calib.calibrationPoints[i]) + ", " + Float.toString(calib.calibrationPoints[i + 1]) + ")"); calibrationSamples[lastSampleTaken][i] = calib.calibrationPoints[i]; calibrationSamples[lastSampleTaken][i + 1] = calib.calibrationPoints[i + 1]; } @@ -164,6 +174,9 @@ public class EviDemo extends ApplicationAdapter { } } else { + /* + * Keep loading the models until the AssetsManager finishes. + */ doneLoading = manager.update(); if(doneLoading) monkey.setModel(manager.get("monkey.g3db", Model.class)); diff --git a/core/src/ve/ucv/ciens/icaro/ardemo/ProjectConstants.java b/core/src/ve/ucv/ciens/icaro/ardemo/ProjectConstants.java index 90fcb84..535e6ab 100644 --- a/core/src/ve/ucv/ciens/icaro/ardemo/ProjectConstants.java +++ b/core/src/ve/ucv/ciens/icaro/ardemo/ProjectConstants.java @@ -21,4 +21,10 @@ public abstract class ProjectConstants{ public static final int MAXIMUM_NUMBER_OF_MARKERS = 5; public static final int CALIBRATION_PATTERN_POINTS = 54; public static final int CALIBRATION_SAMPLES = 10; + + public static final int W = 640; + public static final int H = 360; + public static final float NEAR = 0.01f; + public static final float FAR = 10.0f; + public static final int CODE = 213; } diff --git a/desktop/src/ve/ucv/ciens/icaro/ardemo/desktop/CVProcessor.java b/desktop/src/ve/ucv/ciens/icaro/ardemo/desktop/CVProcessor.java index 2764c7d..50ca233 100644 --- a/desktop/src/ve/ucv/ciens/icaro/ardemo/desktop/CVProcessor.java +++ b/desktop/src/ve/ucv/ciens/icaro/ardemo/desktop/CVProcessor.java @@ -14,20 +14,54 @@ import com.badlogic.gdx.math.Vector3; import ve.ucv.ciens.icaro.ardemo.ImageProcessor; import ve.ucv.ciens.icaro.ardemo.ProjectConstants; +/** + * This class implements the glue methods needed to use the OpenCV native methods. All + * image processing is done through this class. + * + * @author Miguel Angel Astor Romero. + */ public class CVProcessor implements ImageProcessor { private static final String TAG = "NXTAR_ANDROID_MAIN"; private static final String CLASS_NAME = CVProcessor.class.getSimpleName(); + /** + * Indicates if the external native libraries were loaded successfully. + */ private static boolean ocvOn = false; + /* + * These two matrices represent the camera parameters calculated during camera calibration. + * Both parameters are needed to render the virtual objects correctly. + */ private Mat cameraMatrix; private Mat distortionCoeffs; + /* + * These objects are used to capture data from the video files. + */ private VideoCapture markerCap; private VideoCapture calibCap; + /** + * Indicates if the camera calibration procedure completed sucessfully. + */ private boolean cameraCalibrated; + /* + * This block is executed when this class is loaded by the Java VM. It attempts to load + * the external native libraries. + */ + static{ + try{ + System.loadLibrary("opencv_java248"); + System.loadLibrary("evi_10"); + ocvOn = true; + }catch(UnsatisfiedLinkError e){ + e.printStackTrace(); + ocvOn = false; + } + } + private native void getMarkerCodesAndLocations( long inMat, long outMat, @@ -51,17 +85,6 @@ public class CVProcessor implements ImageProcessor { float[] calibrationPoints ); - static{ - try{ - System.loadLibrary("opencv_java248"); - System.loadLibrary("evi_10"); - ocvOn = true; - }catch(UnsatisfiedLinkError e){ - e.printStackTrace(); - ocvOn = false; - } - } - public static boolean isOcvOn() { return ocvOn; } @@ -71,8 +94,8 @@ public class CVProcessor implements ImageProcessor { cameraMatrix = new Mat(); distortionCoeffs = new Mat(); - markerCap = new VideoCapture(arg[0]); - calibCap = new VideoCapture(arg[1]); + markerCap = new VideoCapture(arg[1]); + calibCap = new VideoCapture(arg[2]); } @Override diff --git a/desktop/src/ve/ucv/ciens/icaro/ardemo/desktop/DesktopLauncher.java b/desktop/src/ve/ucv/ciens/icaro/ardemo/desktop/DesktopLauncher.java index 4928779..8350a57 100644 --- a/desktop/src/ve/ucv/ciens/icaro/ardemo/desktop/DesktopLauncher.java +++ b/desktop/src/ve/ucv/ciens/icaro/ardemo/desktop/DesktopLauncher.java @@ -1,10 +1,17 @@ package ve.ucv.ciens.icaro.ardemo.desktop; import ve.ucv.ciens.icaro.ardemo.EviDemo; +import ve.ucv.ciens.icaro.ardemo.ProjectConstants; import com.badlogic.gdx.backends.lwjgl.LwjglApplication; import com.badlogic.gdx.backends.lwjgl.LwjglApplicationConfiguration; +/** + * This is the main class of the applicaton. It is in charge of creating the {@link CVProcessor} instance + * used throught the rest of the application and launching the {@link EviDemo} class. + * + * @author Miguel Angel Astor Romero. + */ public class DesktopLauncher{ private static final String TAG = "NXTAR_ANDROID_MAIN"; private static final String CLASS_NAME = DesktopLauncher.class.getSimpleName(); @@ -14,14 +21,14 @@ public class DesktopLauncher{ throw new RuntimeException(TAG + " : " + CLASS_NAME + ": OpenCV failed to load."); } - if(arg.length != 2) { - System.err.println("Usage: EVI07 "); + if(arg.length != 3) { + System.err.println("Usage: " + arg[0] + " "); System.exit(1); } LwjglApplicationConfiguration config = new LwjglApplicationConfiguration(); - config.width = 640; - config.height = 360; + config.width = ProjectConstants.W; + config.height = ProjectConstants.H; new LwjglApplication(new EviDemo(new CVProcessor(arg)), config); } diff --git a/packr.json b/packr.json new file mode 100644 index 0000000..27b604c --- /dev/null +++ b/packr.json @@ -0,0 +1,17 @@ +{ + "platform": "linux64", + "jdk": "/home/miky/Descargas/openjdk-1.7.0-u80-unofficial-linux-amd64-image.zip", + "executable": "Evidemo_amd64", + "appjar": "desktop/build/libs/desktop-1.0.jar", + "mainclass": "ve/ucv/ciens/icaro/ardemo/desktop/DesktopLauncher", + "vmargs": [ + "-Xmx1G", + "-Djava.library.path=." + ], + "resources": [ + "desktop/libevi_10.so", + "desktop/libopencv_java248.so" + ], + "minimizejre": "hard", + "outdir": "dist" +}