StarDust class on the wiki

See below for working Stardust + Alpha / distance.

I know this is an old post, but I'd like to see if anyone can help me getting this to work.  It renders the stars correctly, but as I move along the x axis the stars get left behind.  Here's the code, updated from above so it compiles with the latest version of JME2:


import java.io.IOException;
import java.util.Random;

import com.jme.bounding.BoundingBox;
import com.jme.math.Vector3f;
import com.jme.renderer.Camera;
import com.jme.renderer.ColorRGBA;
import com.jme.scene.Controller;
import com.jme.scene.Node;
import com.jme.scene.Point;
import com.jme.scene.Spatial;
import com.jme.scene.state.*;
import com.jme.system.DisplaySystem;
import com.jme.util.export.InputCapsule;
import com.jme.util.export.JMEExporter;
import com.jme.util.export.JMEImporter;
import com.jme.util.export.OutputCapsule;
import java.nio.FloatBuffer;
import java.util.List;

/**
 * StarDust
 *
 * @author Zen, Matthew D. Hicks, thzero, ractoc, Methius
 */
public class StarDust extends Node {

    private static final long serialVersionUID = 1L;
    private static final int BLOCKSIZE = 100;
    private int blockSize;
    private Point[][][] points;
    private int numStars;
    private int oldSecX;
    private int oldSecY;
    private int oldSecZ;
    private Camera cam;
    public StarDust(String name, int numStars, int blockSize,
                     boolean randomizeSize, Camera cam, DisplaySystem display) {
        super(name);

        this.cam = cam;
        this.blockSize = blockSize;
        this.numStars = numStars;
        points = new Point[3][3][3];

        setIsCollidable(false);

        // A star field
        //
        // in this first edition, just use the standard 'point' class
        // but in future would like to have a custom drawn one - where intensity
        // is related to distance?
        Random r = new Random();

        Vector3f[] vertexes = new Vector3f[numStars];
        ColorRGBA[] colors = new ColorRGBA[numStars];
        for (int x = 0; x < numStars; ++x) {
            vertexes[x] = new Vector3f((r.nextFloat()) * blockSize, (r.nextFloat()) * blockSize, (r.nextFloat()) * blockSize);
            colors[x] = ColorRGBA.white.clone();
        //colors[x].a = .4f + .6f * r.nextFloat();// .5f + .5f *
        // r.nextFloat();
        }

        // all dust particles are white
        MaterialState ms = DisplaySystem.getDisplaySystem().getRenderer().createMaterialState();

        float alpha = 1.0f; //.5f + r.nextFloat()*.5f;

        ms.setEmissive(new ColorRGBA(0.0f, 0.0f, 1.0f, alpha));
        ms.setDiffuse(new ColorRGBA(0.0f, 0.0f, 1.0f, alpha));
        ms.setEnabled(true);

        BlendState as = display.getRenderer().createBlendState();
        as.setBlendEnabled(true);
        as.setSourceFunction(BlendState.SourceFunction.SourceAlpha);
        as.setDestinationFunction(BlendState.DestinationFunction.OneMinusSourceAlpha);
        as.setTestEnabled(false);
        as.setEnabled(true);

        for (int k = 0; k < 3; ++k) {
            for (int j = 0; j < 3; ++j) {
                for (int i = 0; i < 3; ++i) {
                    Node sector = new Node("sector" + i + j + k);
                    points[i][j][k] = new Point("stardust " + i + "" + j + "" + k, vertexes, null, colors, null);
                    if (randomizeSize) {
                    //points[i][j][k].setPointSize(1.0f+(float)Math.random() * .7f);
                       points[i][j][k].setPointSize(1.0f);
                    }
                    points[i][j][k].setLocalTranslation(new Vector3f((i - 1) * blockSize, (j - 1) * blockSize, (k - 1) * blockSize));
                    points[i][j][k].setModelBound(new BoundingBox());
                    points[i][j][k].updateModelBound();

                    sector.attachChild(points[i][j][k]);
                    sector.setModelBound(new BoundingBox());
                    sector.updateModelBound();

                    attachChild(sector);
                }
            }
        }

        // We don't want the light to affect our dust
        updateWorldBound();
        this.setLightCombineMode(Spatial.LightCombineMode.Off);
        setRenderState(ms);
        setRenderState(as);
        StarDustController dustController = new StarDustController(this, cam);
        this.addController(dustController);
    }
    // ensure the viewer is surrounded by stars!
    public void update(Vector3f viewer) {
        // note: funny things happen when scaling things about the origin,
        // so for our purposes we compensate. (we could have used -0.5..0.5)
        // what we want is: -1000..0 -> -1
        // 0..1000 -> 0
        // 1000..2000 -> 1
        int secX = (int) ((viewer.x / blockSize) + ((viewer.x > 0) ? 0 : -1));
        int secY = (int) ((viewer.y / blockSize) + ((viewer.y > 0) ? 0 : -1));
        int secZ = (int) ((viewer.z / blockSize) + ((viewer.z > 0) ? 0 : -1));

        // reduce garbage collection...
        if ((secX != oldSecX) || (secY != oldSecY) || (secZ != oldSecZ)) {
            getLocalTranslation().set(secX * blockSize, secY * blockSize,
                    secZ * blockSize);
            oldSecX = secX;
            oldSecY = secY;
            oldSecZ = secZ;
        }

        updateAlpha(viewer);

    }
    public void updateAlpha(Vector3f viewer) {

        // loop through all the points
        for (int k = 0; k < 3; ++k) {
            for (int j = 0; j < 3; ++j) {
                for (int i = 0; i < 3; ++i) {
                    Point p = points[k][j][i];

                    FloatBuffer fb = p.getVertexBuffer();
                    fb.position(0);
                    FloatBuffer c = p.getColorBuffer();
                    c.position(0);

                    // in each point loop through all the stars
                    for (int l = 0; l < numStars; l++) {

                        float xs = fb.get();
                        float ys = fb.get();
                        float zs = fb.get();

                        float x = viewer.x - ((xs + p.getLocalTranslation().x)+getLocalTranslation().x);
                        float y = viewer.y - ((ys + p.getLocalTranslation().y)+getLocalTranslation().y);
                        float z = viewer.z - ((zs + p.getLocalTranslation().z)+getLocalTranslation().z);

                        float distance = (float) Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2) + Math.pow(z, 2));
                        // once we have the distance to the viewer, we can calculate the new alpha

                        float calcdist = (distance -(cam.getFrustumFar()/2)) / (cam.getFrustumFar()/2);
                        if (calcdist  < 0f){
                            calcdist=0f;
                        } else if (calcdist > 1f){
                            calcdist=1f;
                        }
                        float alpha = 1f - calcdist;

                        c.put(1f);
                        c.put(1f);
                        c.put(1f);
                        c.put(alpha);

                        // put the new alpha back in the color buffer
                        p.setColorBuffer(c);
                    }
                    // update the render state of the point.
                    p.updateRenderState();
                }
            }
        }
    }
    public void write(JMEExporter e) throws IOException {
        super.write(e);

        OutputCapsule cap = e.getCapsule(this);
        cap.write(blockSize, "blockSize", BLOCKSIZE);
    }
    @SuppressWarnings("unchecked")
    public void read(JMEImporter e) throws IOException {
        super.read(e);

        InputCapsule cap = e.getCapsule(this);
        blockSize = cap.readInt("blockSize", BLOCKSIZE);
    }

    private class StarDustController extends Controller {

        /**
         * Used to track the StarField view direction
         */
        private Camera cam = null;
        private StarDust dust = null;
        public StarDustController(StarDust dust, Camera cam) {

            this.dust = dust;
            this.cam = cam;
        }
        @Override
        public void update(float time) {
            dust.update(cam.getLocation());
        }
    }
}

Seems to work ok,

just make the stardust big enough, so you don't see new sections spawning into your view.



    public static void main(String[] args) {
       StandardGame game = new StandardGame("StarDustTest");
       game.getSettings().setSamples(4);
       game.getSettings().setHeight(640);
       game.getSettings().setWidth(800);
       game.getSettings().setVerticalSync(true);
       game.start();
       
       StardustGameState gs = new StardustGameState();
       GameStateManager.getInstance().attachChild(gs);
       GameStateManager.getInstance().activateAllChildren();
    }
   
}

class StardustGameState extends BasicGameState {
   StarDust sdNode;
   DisplaySystem disp = DisplaySystem.getDisplaySystem();
   Camera cam = disp.getRenderer().getCamera();
   private FirstPersonHandler inputHandler;
   
   public StardustGameState() {
      super("stardust GS");
      cam.update();
      
      // create InputHandler to move with w,a,s,d / mouse
      inputHandler = new FirstPersonHandler(cam, 500, 1);
      
      // create the stardust
      sdNode = new StarDust("sd node", 150, 1000, true,
            disp.getRenderer().getCamera(),   disp);
      
      rootNode.attachChild(sdNode);
   }
   
   @Override
   public void update(float tpf) {
      inputHandler.update(tpf);
      super.update(tpf);
   }
}

Anyone willing to update this for JME3? Ive had a play but its getting very hairy for a new user of JMonkey like me…



Seems like the Point class doesnt exist anymore, tried to swap them for Vector3f… but then later new Point is called with vars that Vector3f doesnt take of course



Is the Point class something that will come along later in JME3? or has it been dumped?





Regards,

maybe you could try to use point sprites somehow, see TestPointSprite

1 Like

Sorry :frowning: Can i be painful and ask where is TestPointSprite ? is that on the SVN thing (i think you guys call it)

Ive had a fairly good look on my hdd and on the forums (forums indicate Point Sprites are on the way for JME3, but maybe still not available yet??).



Either way, its sounds like it could be a good solution to this!





Regards,

http://hub.jmonkeyengine.org/groups/development-discussion-jme3/forum/topic/how-to-use-point-sprites-in-jme3/