Android Open Source - geoar-app A R Object






From Project

Back to project page geoar-app.

License

The source code is released under:

Apache License

If you think the Android project geoar-app listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

/**
 * Copyright 2012 52North Initiative for Geospatial Open Source Software GmbH
 */* ww  w . j  a va 2 s .c  o m*/
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.n52.geoar.ar.view;

import java.util.List;

import javax.microedition.khronos.opengles.GL10;

import org.n52.geoar.ar.view.gl.ARSurfaceViewRenderer.OpenGLCallable;
import org.n52.geoar.ar.view.gl.GLESCamera;
import org.n52.geoar.newdata.DataSourceInstanceHolder;
import org.n52.geoar.newdata.SpatialEntity2;
import org.n52.geoar.newdata.Visualization;
import org.n52.geoar.newdata.Visualization.FeatureVisualization;
import org.n52.geoar.newdata.vis.DataSourceVisualization.DataSourceVisualizationCanvas;
import org.n52.geoar.tracking.location.LocationHandler;
import org.n52.geoar.view.geoar.gl.mode.RenderFeature2;

import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.location.Location;
import android.opengl.GLU;
import android.opengl.Matrix;
import android.view.View;
import android.view.View.MeasureSpec;
import android.view.ViewGroup.LayoutParams;
import android.widget.RelativeLayout;

import com.vividsolutions.jts.geom.Geometry;

/**
 * 
 * @author Arne de Wall <a.dewall@52North.org>
 *
 */
public class ARObject implements OpenGLCallable {

  private static float getScaleByDistance(float distance) {
    // XXX TODO FIXME reworking scaling function
    int x = org.n52.geoar.view.geoar.Settings.BUFFER_MAPINTERPOLATION;
    if (distance > x) {
      return 0.5f;
    }
    float scale = 1 - (distance / (x * 2));
    return Math.max(0.5f, scale);
  }

  private static Paint distancePaint = new Paint();
  static {
    distancePaint.setAntiAlias(true);
    distancePaint.setColor(Color.GRAY);
    distancePaint.setAlpha(100);
  }

  /** Model Matrix of this feature */
  private final float[] modelMatrix = new float[16];
  /** Model view Matrix of this feature */
  private final float[] modelViewMatrix = new float[16];
  /** Model-View-Projection Matrix of our feature */
  private final float[] mvpMatrix = new float[16];
  /** temporary Matrix for caching */
  private final float[] tmpMatrix = new float[16];

  private float distanceTo;
  private float featureDetailsScale;
  private final float[] newPosition = new float[4];
  private final float[] screenCoordinates = new float[3];

  private volatile boolean isInFrustum = false;

  // XXX Why mapping by Class? Compatible with multiinstancedatasources?
  // private final Map<Class<? extends ItemVisualization>, VisualizationLayer>
  // visualizationLayers = new HashMap<Class<? extends ItemVisualization>,
  // VisualizationLayer>();

  private final SpatialEntity2<? extends Geometry> entity;
  private DataSourceVisualizationCanvas canvasFeature;
  private List<RenderFeature2> renderFeatures;
  private FeatureVisualization visualization;
  private View featureDetailView;
  private Bitmap featureDetailBitmap;
  private DataSourceInstanceHolder dataSourceInstance;

  // TODO FIXME XXX task: ARObject gains most functionalities of RenderFeature
  // (-> RenderFeature to be more optional)
  public ARObject(SpatialEntity2<? extends Geometry> entity,
      Visualization.FeatureVisualization visualization,
      List<RenderFeature2> features,
      DataSourceVisualizationCanvas canvasFeature,
      DataSourceInstanceHolder dataSourceInstance) {
    this.entity = entity;
    this.renderFeatures = features;
    this.canvasFeature = canvasFeature;
    this.visualization = visualization;
    this.dataSourceInstance = dataSourceInstance;

    onLocationUpdate(LocationHandler.getLastKnownLocation());
  }

  public FeatureVisualization getVisualization() {
    return visualization;
  }
  
  public DataSourceInstanceHolder getDataSourceInstance() {
    return dataSourceInstance;
  }
  
  public SpatialEntity2<? extends Geometry> getEntity() {
    return entity;
  }

  public ARObject(SpatialEntity2<? extends Geometry> entity,
      Visualization.FeatureVisualization visualization,
      List<RenderFeature2> features,
      DataSourceVisualizationCanvas canvasFeature, View featureDetailView, DataSourceInstanceHolder dataSourceInstance) {
    this.entity = entity;
    this.renderFeatures = features;
    this.canvasFeature = canvasFeature;
    this.visualization = visualization;
    this.dataSourceInstance = dataSourceInstance;

    if (featureDetailView != null) {
      this.featureDetailView = featureDetailView;

      this.featureDetailView.setLayoutParams(new LayoutParams(
          RelativeLayout.LayoutParams.WRAP_CONTENT,
          RelativeLayout.LayoutParams.WRAP_CONTENT));

      this.featureDetailView.setDrawingCacheEnabled(true);
      this.featureDetailView.measure(
          MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED),
          MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));

      this.featureDetailView.layout(0, 0,
          this.featureDetailView.getMeasuredWidth(),
          this.featureDetailView.getMeasuredHeight());

      this.featureDetailView.buildDrawingCache(true);

      featureDetailBitmap = Bitmap.createBitmap(this.featureDetailView
          .getDrawingCache());
      this.featureDetailView.setDrawingCacheEnabled(false);

    }

    onLocationUpdate(LocationHandler.getLastKnownLocation());
  }

  @Override
  public void onPreRender() {
    // TODO Auto-generated method stub

  }

  @Override
  public void render(final float[] projectionMatrix,
      final float[] viewMatrix, final float[] parentMatrix,
      final float[] lightPosition) {

    /** set the matrices to identity matrix */
    Matrix.setIdentityM(modelMatrix, 0);
    Matrix.setIdentityM(modelViewMatrix, 0);
    Matrix.setIdentityM(mvpMatrix, 0);
    Matrix.setIdentityM(tmpMatrix, 0);

    // TODO i think position[0] must be translated negatively -> Check
    Matrix.translateM(modelMatrix, 0, -newPosition[0], newPosition[1],
        newPosition[2]);

    if (parentMatrix != null) {
      Matrix.multiplyMM(tmpMatrix, 0, parentMatrix, 0, modelMatrix, 0);
      System.arraycopy(tmpMatrix, 0, modelMatrix, 0, 16);
      Matrix.setIdentityM(tmpMatrix, 0);
    }

    Matrix.multiplyMM(modelViewMatrix, 0, viewMatrix, 0, modelMatrix, 0);
    Matrix.multiplyMM(mvpMatrix, 0, projectionMatrix, 0, modelViewMatrix, 0);

    // TODO XXX FIXME frustum test
    if (newPosition != null) {
      float[] vec = new float[] { 0, 0, 0, 1 };
      Matrix.multiplyMV(vec, 0, modelMatrix, 0, vec, 0);
      if (!GLESCamera.frustumCulling(vec)) {
        isInFrustum = false;
        return;
      }
      /** object is in Frustum - update screen coordinates */
      isInFrustum = true;
      updateScreenCoordinates();
    }
    // isInFrustum = true;

    // TODO XXX FIXME are just active visualizations called !? -> check
    // for (VisualizationLayer layer : visualizationLayers.values()) {
    for (RenderFeature2 feature : renderFeatures) {
      feature.render(mvpMatrix, modelViewMatrix, lightPosition);
    }
    // }
  }

  public void initializeRendering() {
    for (RenderFeature2 feature : renderFeatures) {
      feature.onCreateInGLESThread();
    }
  }

  private final void updateScreenCoordinates() {
    float[] screenPos = new float[3];
    // TODO FIXME XXX i think newPosition[2] has to be negative
    int result = GLU.gluProject(-newPosition[0], newPosition[1],
        newPosition[2], modelMatrix, 0, GLESCamera.projectionMatrix, 0,
        GLESCamera.viewportMatrix, 0, screenPos, 0);

    if (result == GL10.GL_TRUE) {
      screenCoordinates[0] = screenPos[0];
      screenCoordinates[1] = GLESCamera.viewportMatrix[3] - screenPos[1];
    }
  }

  public boolean thisObjectHitted(float cx, float cy) {
    float dx = screenCoordinates[0] - cx;
    float dy = screenCoordinates[1] - cy;
    float length = (float) Math.sqrt(dx * dx - dy * dy);

    if (length <= 20) {
      return true;
    } else {
      return false;
    }
  }

  public void onLocationUpdate(Location location) {
    if (entity == null || location == null)
      return;

    final double longitude = entity.getLongitude();
    final double latitude = entity.getLatitude();
    int altitude = (int) entity.getAltitude();

    /** calc the distance XXX */
    final float[] x = new float[1];
    Location.distanceBetween(location.getLatitude(),
        location.getLongitude(), latitude, longitude, x);
    distanceTo = x[0];
    x[0] = 0;

    /** set scaling */
    this.featureDetailsScale = getScaleByDistance(distanceTo);

    /** just the distance -> length 1 */
    Location.distanceBetween(location.getLatitude(),
        location.getLongitude(), location.getLatitude(), longitude, x);

    /** just the distance -> length 1 */
    final float[] z = new float[1];
    Location.distanceBetween(location.getLatitude(),
        location.getLongitude(), latitude, location.getLongitude(), z);

    // correct the direction according to the poi location, because we just
    // get the distance in x and z direction
    if (location.getLongitude() < longitude)
      x[0] *= -1;
    if (location.getLatitude() < latitude)
      z[0] *= -1;
    if (altitude == 0)
      altitude = (int) location.getAltitude();
    // testen

    newPosition[0] = x[0];
    newPosition[1] = (float) (altitude - location.getAltitude());
    // FIXME XXX TODO and here the third position has to be negative i think
    newPosition[2] = z[0];

    for (RenderFeature2 renderFeature : renderFeatures)
      renderFeature.setRelativePosition(newPosition);

    this.newPosition[0] = newPosition[0]; // - GLESCamera.cameraPosition[0];
    this.newPosition[1] = newPosition[1] - GLESCamera.cameraPosition[1];
    this.newPosition[2] = newPosition[2]; // - GLESCamera.cameraPosition[2];
  }

  public void renderCanvas(Paint poiRenderer, Canvas canvas) {
    // FIXME TODO XXX distanceTo has to be in the Settings
    if (isInFrustum) {
      /**
       * scale the direction indicator of the ARObject with the distance
       * scale
       */
      canvas.save(Canvas.MATRIX_SAVE_FLAG);

      canvas.scale(featureDetailsScale, featureDetailsScale,
          screenCoordinates[0], screenCoordinates[1]);

      canvasFeature.onRender(screenCoordinates[0], screenCoordinates[1],
          canvas);
      canvas.restore();

      // canvas.drawRect(screenCoordinates[0] - 20,
      // screenCoordinates[1] - 10, screenCoordinates[0] + 20,
      // screenCoordinates[1] + 10, distancePaint);

      /** draw the featureDetailsView bitmap */
      if (featureDetailBitmap != null)
        canvas.drawBitmap(featureDetailBitmap, screenCoordinates[0],
            screenCoordinates[1], null);
    }
  }

  public void setLightPosition(float[] lightPosInEyeSpace) {
    // GLES20.glUniform3f(renderfe, lightPosInEyeSpace[0],
    // lightPosInEyeSpace[1], lightPosInEyeSpace[2]);

  }

}




Java Source Code List

.DataSourcesOverlay.java
.VisualizationOverlayItem.java
org.n52.geoar.AboutDialog.java
org.n52.geoar.DataSourceListAdapter.java
org.n52.geoar.GeoARActivity.java
org.n52.geoar.GeoARApplication.java
org.n52.geoar.ar.view.ARFragment.java
org.n52.geoar.ar.view.ARObject.java
org.n52.geoar.ar.view.ARView.java
org.n52.geoar.ar.view.DataSourceVisualizationHandler.java
org.n52.geoar.ar.view.IntroController.java
org.n52.geoar.ar.view.IntroViewer.java
org.n52.geoar.ar.view.gl.ARSurfaceViewRenderer.java
org.n52.geoar.ar.view.gl.ARSurfaceView.java
org.n52.geoar.ar.view.gl.GLESCamera.java
org.n52.geoar.ar.view.gl.MultisampleConfigs.java
org.n52.geoar.ar.view.gl.SurfaceTopology.java
org.n52.geoar.ar.view.overlay.ARCanvasSurfaceView.java
org.n52.geoar.ar.view.overlay.GUIDrawable.java
org.n52.geoar.ar.view.overlay.Radar.java
org.n52.geoar.exception.UnsupportedGeometryType.java
org.n52.geoar.map.view.DataSourceOverlayHandler.java
org.n52.geoar.map.view.GeoARMapView.java
org.n52.geoar.map.view.MapActivityContext.java
org.n52.geoar.map.view.MapFragment.java
org.n52.geoar.map.view.overlay.DataSourceOverlay.java
org.n52.geoar.map.view.overlay.DataSourcePointOverlay.java
org.n52.geoar.map.view.overlay.DataSourcePolygonOverlay.java
org.n52.geoar.map.view.overlay.DataSourcePolylineOverlay.java
org.n52.geoar.map.view.overlay.DataSourcesOverlay.java
org.n52.geoar.map.view.overlay.OverlayType.java
org.n52.geoar.map.view.overlay.PointOverlayType.java
org.n52.geoar.map.view.overlay.PolygonOverlayType.java
org.n52.geoar.map.view.overlay.PolylineOverlayType.java
org.n52.geoar.newdata.CheckList.java
org.n52.geoar.newdata.DataCache.java
org.n52.geoar.newdata.DataSourceHolder.java
org.n52.geoar.newdata.DataSourceInstanceHolder.java
org.n52.geoar.newdata.DataSourceInstanceSettingsDialogActivity.java
org.n52.geoar.newdata.InstalledPluginHolder.java
org.n52.geoar.newdata.PluginActivityContext.java
org.n52.geoar.newdata.PluginContext.java
org.n52.geoar.newdata.PluginDialogFragment.java
org.n52.geoar.newdata.PluginDownloadHolder.java
org.n52.geoar.newdata.PluginDownloader.java
org.n52.geoar.newdata.PluginFragment.java
org.n52.geoar.newdata.PluginGridAdapter.java
org.n52.geoar.newdata.PluginHolder.java
org.n52.geoar.newdata.PluginLoader.java
org.n52.geoar.newdata.PluginLogger.java
org.n52.geoar.newdata.PluginStateInputStream.java
org.n52.geoar.newdata.Tile.java
org.n52.geoar.settings.DateTimeSettingsViewField.java
org.n52.geoar.settings.DateUtils.java
org.n52.geoar.settings.NumberSettingsViewField.java
org.n52.geoar.settings.SettingsException.java
org.n52.geoar.settings.SettingsHelper.java
org.n52.geoar.settings.SettingsViewField.java
org.n52.geoar.settings.SettingsView.java
org.n52.geoar.settings.SpinnerSettingsViewField.java
org.n52.geoar.settings.StringSettingsViewField.java
org.n52.geoar.tracking.camera.CameraView.java
org.n52.geoar.tracking.camera.RealityCamera.java
org.n52.geoar.tracking.location.AdaptiveLowPassSensorBuffer.java
org.n52.geoar.tracking.location.LocationHandler.java
org.n52.geoar.tracking.location.LowPassSensorBuffer.java
org.n52.geoar.tracking.location.MeanSensorBuffer.java
org.n52.geoar.tracking.location.SensorBuffer.java
org.n52.geoar.view.InfoView.java
org.n52.geoar.view.geoar.CalibrationControlView.java
org.n52.geoar.view.geoar.Settings.java
org.n52.geoar.view.geoar.gl.mode.BilligerColorShader.java
org.n52.geoar.view.geoar.gl.mode.BilligerLightShader.java
org.n52.geoar.view.geoar.gl.mode.BilligerTextureShader.java
org.n52.geoar.view.geoar.gl.mode.BoundingBox.java
org.n52.geoar.view.geoar.gl.mode.FeatureShader.java
org.n52.geoar.view.geoar.gl.mode.PhongFeatureShader.java
org.n52.geoar.view.geoar.gl.mode.RenderFeature2.java
org.n52.geoar.view.geoar.gl.mode.Spatial.java
org.n52.geoar.view.geoar.gl.mode.TextureFeatureShader.java
org.n52.geoar.view.geoar.gl.mode.Texture.java
org.n52.geoar.view.geoar.gl.mode.features.CubeFeature2.java
org.n52.geoar.view.geoar.gl.mode.features.FlatCircleFeature.java
org.n52.geoar.view.geoar.gl.mode.features.HeightMapFeature.java
org.n52.geoar.view.geoar.gl.mode.features.NewGridFeature.java
org.n52.geoar.view.geoar.gl.mode.features.ReferencedGridFeature.java
org.n52.geoar.view.geoar.gl.mode.features.SphereFeature.java
org.n52.geoar.view.geoar.gl.mode.features.TriangleFeature.java