com.mousebird.maply.MaplyStarModel.java Source code

Java tutorial

Introduction

Here is the source code for com.mousebird.maply.MaplyStarModel.java

Source

/*
 *  MaplyStarModel.java
 *  WhirlyGlobeLib
 *
 *  Created by jmnavarro
 *  Copyright 2011-2015 mousebird consulting
 *
 *  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 com.mousebird.maply;

import android.app.Activity;
import android.content.res.AssetManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import org.apache.commons.io.IOUtils;

import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.TimeZone;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class MaplyStarModel {

    private class SingleStar {
        float mag;
        float ra, dec;
    }

    private static final String vertexShaderTriPoint = "uniform mat4  u_mvpMatrix;" + "uniform float u_radius;" + ""
            + "attribute vec3 a_position;" + "attribute float a_size;" + "" + "varying vec4 v_color;" + ""
            + "void main()" + "{" + "   v_color = vec4(1.0,1.0,1.0,1.0);" + "   gl_PointSize = a_size;"
            + "   gl_Position = u_mvpMatrix * vec4(a_position * u_radius,1.0);" + "}";

    private static final String fragmentShaderTriPoint = "precision lowp float;" + "" + "varying vec4      v_color;"
            + "" + "void main()" + "{" + "  gl_FragColor = v_color;" + "}";

    private static final String fragmentShaderTexTriPoint = "precision lowp float;" + ""
            + "uniform sampler2D s_baseMap0;" + "varying vec4      v_color;" + "" + "void main()" + "{"
            + "  gl_FragColor = v_color * texture2D(s_baseMap0, gl_PointCoord);" + "}";

    ArrayList<SingleStar> stars;
    ParticleSystem particleSystem;
    ComponentObject particleSystemObj;
    GlobeController viewC;
    MaplyBaseController.ThreadMode addedMode;
    Bitmap image;

    public MaplyStarModel(String fileName, String imageName, Activity activity) throws IOException {
        AssetManager assetMgr = activity.getAssets();
        InputStream inputStream = null;
        String[] paths = assetMgr.list("maplystarmodel");
        for (String path : paths) {
            if (path.equals(imageName)) {
                //image
                BufferedInputStream bufferedInputStream = null;
                try {
                    inputStream = assetMgr.open("maplystarmodel/" + path);
                    bufferedInputStream = new BufferedInputStream(inputStream);
                    image = BitmapFactory.decodeStream(bufferedInputStream);
                } finally {
                    if (bufferedInputStream != null) {
                        try {
                            bufferedInputStream.close();
                        } catch (IOException e) {
                        }
                    }
                }
            }
            if (path.equals(fileName)) {
                //data
                Matcher m;
                try {
                    inputStream = assetMgr.open("maplystarmodel/" + path);
                    String stars = IOUtils.toString(inputStream, Charset.defaultCharset());
                    Pattern p = Pattern.compile("[-]?[0-9]*\\.?[0-9]+");
                    m = p.matcher(stars);
                } finally {
                    if (inputStream != null) {
                        try {
                            inputStream.close();
                        } catch (IOException e) {
                        }
                    }
                }

                this.stars = new ArrayList<SingleStar>();
                if (m.groupCount() % 3 == 0) {
                    int i = 0;
                    SingleStar s = null;
                    while (m.find()) {
                        switch (i) {
                        case 0:
                            s = new SingleStar();
                            s.ra = Float.valueOf(m.group());
                            i++;
                            break;
                        case 1:
                            s.dec = Float.valueOf(m.group());
                            i++;
                            break;
                        case 2:
                            s.mag = Float.valueOf(m.group());
                            this.stars.add(s);
                            i = 0;
                            break;
                        default:
                            break;
                        }
                    }
                }
            }
        }
    }

    public void addToViewc(GlobeController inViewC, MaplyBaseController.ThreadMode mode) {
        this.viewC = inViewC;
        this.addedMode = mode;

        //Julian date for position calculation
        Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
        double jd = getJulianDateDouble(cal.getTimeInMillis());
        double siderealTime = Greenwich_Mean_Sidereal_Deg(jd);

        //Really simple shader
        Shader shader = new Shader("Star Shader", vertexShaderTriPoint,
                (image != null ? fragmentShaderTexTriPoint : fragmentShaderTriPoint), viewC);
        shader.setUniform("u_radius", 6.0);
        viewC.addShaderProgram(shader, "Star Shader");

        long shaderID = viewC.getScene().getProgramIDBySceneName("Star Shader");

        //Set up a simple particle system (that doesn't move)
        particleSystem = new ParticleSystem("Stars");
        particleSystem.setParticleSystemType(ParticleSystem.STATE.ParticleSystemPoint);
        particleSystem.setLifetime(1e20);
        particleSystem.setTotalParticles(stars.size());
        particleSystem.setBatchSize(stars.size());
        particleSystem.setShaderID(shaderID);

        if (image != null) {
            particleSystem.addTexture(image);
        }

        particleSystem.addParticleSystemAttribute("a_position",
                ParticleSystemAttribute.MaplyShaderAttrType.MAPLY_SHADER_ATTR_TYPE_FLOAT3);
        particleSystem.addParticleSystemAttribute("a_size",
                ParticleSystemAttribute.MaplyShaderAttrType.MAPLY_SHADER_ATTR_TYPE_FLOAT);

        particleSystemObj = viewC.addParticleSystem(particleSystem, addedMode);

        //Data arrays for particles
        //We'll clear them out in case we don't fill them out completely
        float[] posData = new float[stars.size() * 3];
        float[] sizeData = new float[stars.size()];

        for (int i = 0; i < stars.size(); i++) {
            SingleStar singleStar = stars.get(i);

            //Convert the start from equatorial to useable lon/lat
            //Note: Should check this math
            double starLon = Math.toRadians(singleStar.ra - 15 * siderealTime);
            double starLat = Math.toRadians(singleStar.dec);

            double z = Math.sin(starLat);
            double rad = Math.sqrt(1.0 - z * z);
            Point3d pt = new Point3d(rad * Math.cos(starLon), rad * Math.sin(starLon), z);

            posData[i * 3] = (float) pt.getX();
            posData[i * 3 + 1] = (float) pt.getY();
            posData[i * 3 + 2] = (float) pt.getZ();
            float mag = (float) (6.0 - singleStar.mag);
            if (mag < 0.0)
                mag = (float) 0.0;
            sizeData[i] = mag;
        }

        //Set up the particle batch
        ParticleBatch batch = new ParticleBatch(particleSystem);
        batch.addAttribute("a_position", posData);
        batch.addAttribute("a_size", sizeData);
        viewC.addParticleBatch(batch, addedMode);

    }

    public void removeFromView() {
        if (particleSystemObj != null)
            viewC.removeObject(particleSystemObj, addedMode);
    }

    public static double Greenwich_Mean_Sidereal_Deg(double mjd) {
        // calculate T
        double T = (mjd - 51544.5) / 36525.0;

        // do calculation
        double gmst = ((280.46061837 + 360.98564736629 * (mjd - 51544.5)) + 0.000387933 * T * T
                - T * T * T / 38710000.0) % 360.0;

        // make positive
        if (gmst < 0) {
            gmst += 360.0;
        }

        return gmst;
    } //Greenwich_Mean_Sidereal_Deg

    public static final int SECONDS_IN_DAY = 60 * 60 * 24;

    public static final long MILLIS_IN_DAY = 1000L * SECONDS_IN_DAY;

    public static double getJulianDateDouble(long millis) {

        TimeZone timeZone = TimeZone.getDefault();

        millis += timeZone.getOffset(millis);
        int integer = (int) (millis / MILLIS_IN_DAY);
        double fraction = (double) (millis % MILLIS_IN_DAY) / MILLIS_IN_DAY;
        integer += getInteger(2440587, 0.5);
        fraction += getFraction(2451910, 0.5);
        return (double) integer + fraction;
    }

    public static int getInteger(int i, double f) {
        int integer = i;
        int fi = (int) f;
        f -= fi;
        integer += fi;
        if (f < 0) {
            integer--;
        }
        return integer;
    }

    public static double getFraction(int i, double f) {
        int fi = (int) f;
        f -= fi;
        if (f < 0) {
            f += 1;
        }
        return f;
    }
}