Package org.pollux3d.map

Source Code of org.pollux3d.map.Planet

package org.pollux3d.map;


import org.pollux3d.cam.CamTarget;
import org.pollux3d.core.Pollux;

import com.jme3.asset.AssetManager;
import com.jme3.material.Material;
import com.jme3.material.RenderState.BlendMode;
import com.jme3.math.FastMath;
import com.jme3.math.Vector3f;
import com.jme3.renderer.queue.RenderQueue.Bucket;
import com.jme3.scene.Geometry;
import com.jme3.scene.Node;
import com.jme3.scene.Spatial;
import com.jme3.util.TangentBinormalGenerator;


/**
* This class contains the main parameters used in the shaders.
*
* @author mawi, jiyarza
*/
public class Planet extends MapEntity implements CamTarget, PlanetUpdateListener {
 
    private static final String MESH_SPHERE = "Models/Sphere.mesh.j3o";
 
    /**
     * Number of sample rays to use in integral equation
     * requires updateCalculations() on change
     */
    private int nSamples = 3;
   
    /**
     * Atmosphere size factor
     * atmosphere size = inner Radius * atmosphere size factor
     * requires updateCalculations() on change
     */
    private float atmosphereSizeFactor = 1.025f;
   
    /**
     * Rayleigh scattering constant
     * requires updateCalculations() on change
     */
    private float Kr = 0.0025f;
   
    /**
     * Mie scattering constant
     * requires updateCalculations() on change
     */
    private float Km = 0.0015f;
   
    /**
     * Sun brightness constant
     * requires updateCalculations() on change
     */
    private float ESun = 10f;
   
    /**
     * The scale depth (i.e. the altitude at which the atmosphere's average density is found)
     * requires updateCalculations() on change
     */
    private float scaleDepth = 0.25f;
   
    /**
     * TODO: add description
     * requires updateCalculations() on change
     */
    private Vector3f wavelength = new Vector3f(0.731f, 0.612f, 0.455f);
   
    /**
     * Atmosphere dim out factor
     * Atmosphere starts to dim out after an camera distance of
     * atmosphereDimOutFactor * innerRadius
     */
    private float atmosphereDimOutFactor = 6f;
   
    /**
     * The Mie phase asymmetry factor
     */
    private float G = -0.990f;
   
    /**
     * TODO: add description
     */
    private float exposure = 2f;
   
    /**
     * Planet ground radius
     */
    private float innerRadius;
   
    /**
     * Cloud rotation speed
     */
    private float rotationSpeed = 0.00002f;
   
    /**
     * The position of the planet
     */
    private Vector3f position;
   
    /**
     * Calculated by updateCalculations()
     * 1 / (outerRadius - innerRadius)
     */
    private float scale;
   
    /**
     * Calculated by updateCalculations()
     * scale / scaleDepth
     */
    private float scaleOverScaleDepth;
   
    /**
     * Calculated by updateCalculations()
     * 1 / pow(wavelength, 4) for the red, green, and blue channels
     */
    private Vector3f invWavelength4 = new Vector3f();
   
    /**
     * Calculated by updateCalculations()
     * Kr * ESun
     */
    private float KrESun;
   
    /**
     * Calculated by updateCalculations()
     * Kr * 4 * PI
     */
    private float Kr4PI;
   
    /**
     * Calculated by updateCalculations()
     * Km * ESun
     */
    private float KmESun;
   
    /**
     * Calculated by updateCalculations()
     * Km * 4 * PI
     */
    private float Km4PI;
   
    /**
     * AssetManager for textures and materials
     */
    private AssetManager assetManager;
   
    /**
     * Planet ground spatial
     */
    private Spatial ground;
   
    /**
     * Atmosphere sphere spatial
     */
    private Spatial atmosphere;

    /**
     * Cloud sphere spatial
     */
    private Spatial clouds;
   
    /**
     * Planet ground material
     */
    private Material mPlanetGround;
   
    /**
     * Atmosphere sphere material
     */
    private Material mAtmosphere;
   
    public Planet(AssetManager assetManager, String name, String groundTexture, String cloudTexture, float radius, Vector3f position, boolean useAtmosphere, Vector3f atmosphereWavelength) {
      super(name);
      this.assetManager = assetManager;
     
      if (atmosphereWavelength != null)
        wavelength = atmosphereWavelength;
     
      setRadius(radius);
      setPosition(position);
        updateCalculations();
       
        // Create spatials and materials
        if (groundTexture != null) {
          createGround(groundTexture);
            Pollux.get().getGeometryManager().registerGeometry((Geometry) ((Node) ground).getChild(0), this);

        }
        if (useAtmosphere)
          createAtmosphere();
       
        if (cloudTexture != null)
          createClouds(cloudTexture);
       
        // register with pollux core
        Pollux.get().getStateManager().getPlanetAnimation().registerPlanet(this);
       
       
        this.setCullHint(CullHint.Never);
       
        // attach the spatials
        if (groundTexture != null)
          attachChild(ground);
        if (useAtmosphere)
          attachChild(atmosphere);
        if (cloudTexture != null)
          attachChild(clouds);
    }

    /**
     * Call this method after changing parameter values
     */
    public void updateCalculations() {
        scale = 1.0f / ((innerRadius * atmosphereSizeFactor) - innerRadius);
        scaleOverScaleDepth = scale / scaleDepth;
        KrESun = Kr * ESun;
        KmESun = Km * ESun;
        Kr4PI = Kr * 4.0f * FastMath.PI;
        Km4PI = Km * 4.0f * FastMath.PI;

        invWavelength4.x = 1.0f / FastMath.pow(wavelength.x, 4.0f);
        invWavelength4.y = 1.0f / FastMath.pow(wavelength.y, 4.0f);
        invWavelength4.z = 1.0f / FastMath.pow(wavelength.z, 4.0f);
    }
   
    private void createGround(String groundTexture) {
        Spatial geom = createSphere();
        geom.scale(getInnerRadius());
        mPlanetGround = new Material(assetManager, "Common/MatDefs/Light/Lighting.j3md");
        mPlanetGround.setTexture("DiffuseMap", assetManager.loadTexture(groundTexture));
        mPlanetGround.setTexture("GlowMap", assetManager.loadTexture("Textures/Planets/Earth/Earthlights2_1280.jpg"));
        mPlanetGround.setFloat("Shininess", 0.01f); // [1,128]
        geom.setMaterial(mPlanetGround);
        geom.setLocalTranslation(getPosition());
        TangentBinormalGenerator.generate(geom);
        geom.updateModelBound();
        ground = geom;
    }
   
    private void createClouds(String cloudTexture) {
        Spatial geom = createSphere();
        geom.scale(getCloudRadius());
        Material mClouds = new Material(assetManager, "Common/MatDefs/Light/Lighting.j3md");
        mClouds.setTexture("DiffuseMap", assetManager.loadTexture(cloudTexture));
        mClouds.setFloat("Shininess", 0.01f); // [1,128]
        mClouds.getAdditionalRenderState().setBlendMode(BlendMode.AlphaAdditive);
        geom.setMaterial(mClouds);
        geom.setLocalTranslation(getPosition());
        TangentBinormalGenerator.generate(geom);
        geom.updateModelBound();
        clouds = geom;
    }

    private void createAtmosphere() {
     
      // create the spatial
      atmosphere = createSphere();
      atmosphere.scale(getOuterRadius());
      atmosphere.setLocalTranslation(getPosition());
      atmosphere.setQueueBucket(Bucket.Transparent);
      atmosphere.setMaterial(mAtmosphere);
        TangentBinormalGenerator.generate(atmosphere);
        atmosphere.updateModelBound();
       
        //create the material
        mAtmosphere = new Material(assetManager, "MatDefs/Atmosphere.j3md");
        mAtmosphere.setVector3("v3LightPos", new Vector3f(1,0,0));
        mAtmosphere.setVector3("v3Center", position);
        mAtmosphere.setVector3("v3InvWavelength", this.getInvWavelength4());
        mAtmosphere.setFloat("fKrESun", this.getKrESun());
        mAtmosphere.setFloat("fKmESun", this.getKmESun());
        mAtmosphere.setFloat("fOuterRadius", this.getOuterRadius());
        mAtmosphere.setFloat("fInnerRadius", this.getInnerRadius());
        mAtmosphere.setFloat("fOuterRadius2", this.getOuterRadius() * this.getOuterRadius());
        mAtmosphere.setFloat("fInnerRadius2", this.getInnerRadius() * this.getInnerRadius());
        mAtmosphere.setFloat("fKr4PI", this.getKr4PI());
        mAtmosphere.setFloat("fKm4PI", this.getKm4PI());
        mAtmosphere.setFloat("fScale", this.getScale());
        mAtmosphere.setFloat("fScaleDepth", this.getScaleDepth());
        mAtmosphere.setFloat("fScaleOverScaleDepth", this.getScaleOverScaleDepth());
        mAtmosphere.setFloat("fSamples", this.getfSamples());
        mAtmosphere.setInt("nSamples", this.getnSamples());
        mAtmosphere.setFloat("fg", this.getG());
        mAtmosphere.setFloat("fg2", this.getG() * this.getG());
        mAtmosphere.setFloat("fExposure", this.getExposure());
        mAtmosphere.setFloat("fCameraHeightDimOut", this.getInnerRadius()*this.getAtmosphereDimOut());
       
        atmosphere.setMaterial(mAtmosphere);
    }
   
    private Spatial createSphere() {
      Spatial sphere = assetManager.loadModel(MESH_SPHERE);
      sphere.scale(0.25f);
        return sphere;
    }
   
    public void update(float tpf, Vector3f cameraLocation, Vector3f sunLocation) {
             
        Vector3f lightPosNormalized = sunLocation.subtract(getPosition()).normalize();
        Vector3f planetToCamera = cameraLocation.subtract(getPosition());
        float cameraHeight = planetToCamera.length();
       
        // rotate the clouds
        if (clouds != null)
          clouds.rotate(0, rotationSpeed, 0);
       
        if (mAtmosphere != null) {
          // update the atmosphere material
          mAtmosphere.setVector3("v3CameraPos", cameraLocation);
          mAtmosphere.setVector3("v3LightPos", lightPosNormalized);
          mAtmosphere.setVector3("v3Center", position);
          mAtmosphere.setFloat("fCameraHeight", cameraHeight);
          mAtmosphere.setFloat("fCameraHeight2", cameraHeight * cameraHeight);
          mAtmosphere.setVector3("v3InvWavelength", getInvWavelength4());
          mAtmosphere.setFloat("fKrESun", getKrESun());
          mAtmosphere.setFloat("fKmESun", getKmESun());
          mAtmosphere.setFloat("fKr4PI", getKr4PI());
          mAtmosphere.setFloat("fKm4PI", getKm4PI());
          mAtmosphere.setFloat("fg", getG());
          mAtmosphere.setFloat("fg2", getG() * getG());
          mAtmosphere.setFloat("fExposure", getExposure());
          atmosphere.setMaterial(mAtmosphere);
        }
    }
   
    // customizable values
    public void setRadius(float radius) { this.innerRadius = radius; }
    public void setPosition(Vector3f pos) { position = pos; }
    public void setKr(float Kr) { this.Kr = Kr; }
    public void setKm(float Km) { this.Km = Km; }
    public void setESun(float ESun) { this.ESun = ESun; }
    public void setG(float G) { this.G = G; }
    public void setRed(float w) { wavelength.x = w; }
    public void setGreen(float w) { wavelength.y = w; }
    public void setBlue(float w) { wavelength.z = w; }
    public void setSamples(int n) { nSamples = n; }
    public void setExposure(float f) { exposure = f; }
    public void setRotationSpeed(float speed) { this.rotationSpeed = speed; }
    public void setAtmosphereDimOut(float factor) { this.atmosphereDimOutFactor = factor; }
    // Getters
    public float getRadius() { return innerRadius; }
    public Vector3f getPosition() { return position; }
    public int getnSamples() { return nSamples; }
    public float getfSamples() { return (float) nSamples; }
    public float getKr() { return Kr; }
    public float getKrESun() { return KrESun; }
    public float getKr4PI() { return Kr4PI; }
    public float getKm() { return Km; }
    public float getKmESun() { return KmESun; }
    public float getKm4PI() { return Km4PI; }
    public float getESun() { return ESun; }
    public float getG() { return G; }
    public float getInnerRadius() { return innerRadius; }
    public float getOuterRadius() { return innerRadius * atmosphereSizeFactor;
    public float getCloudRadius() { return innerRadius * 1.001f;
    public float getScale() { return scale; }
    public float getScaleDepth() { return scaleDepth; }
    public float getScaleOverScaleDepth() { return scaleOverScaleDepth; }
    public Vector3f getWavelength() { return wavelength; }
    public Vector3f getInvWavelength4() { return invWavelength4; }
    public float getExposure() { return exposure; }
    public float getRotationSpeed() { return rotationSpeed; }
    public float getAtmosphereDimOut() { return atmosphereDimOutFactor; }

  @Override
  public float getZoomDistance() {
    return 180;
  }
 
  public Spatial getTarget() {
    return this;
  }

  /* (non-Javadoc)
   * @see com.jme3.scene.Spatial#getLocalTranslation()
   */
  @Override
  public Vector3f getLocalTranslation() {
    return getPosition();
  }
 
 
   
}
TOP

Related Classes of org.pollux3d.map.Planet

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.