(October 2016) Monthly WIP screenshot thread

Nice work @Tryder.
Very impressed.
Keep up the good work for mobile with jME.

1 Like

It’ll definitely be available on my website, other than that I might put it up on the Amazon app store and Google Play.

It’s pretty much done, just waiting on my girlfriend to finish the French translation.

3 Likes

Hi @Tryder, if I may ask…
How did you accomplish the trails behind the spaceship?

It’s basically a particle system except the particles are connected. I have an array that saves the last 60 position/rotation of the ship and place four verts at each position, two for each trail. The color of the trail is done using vertex colors and the same shader based faux anti-aliasing used for the UI.

Like a particle each step in the trail is given a lifespan, the alpha value of the vertex color is determined by the trail point’s time alive / lifespan.

P.S. the rounded meters on either side of the HUD also use vertex colors and faux anti-aliasing. The faux anti-aliasing can be turned off in the options menu, but doesn’t have any noticeable impact on performance.

3 Likes

Thanks for the reply @Tryder.
Cool, I like it.
Please let us know when you have a playable version out. I would really like to test this.

Now that I have my laptop in front of me, here is the engine trail class:

public class EngineTrail extends Geometry {
    private static final float POINT_LIFE = 1f;
    private static final float FPS = 1 / 25f;
    
    private final float engine1Local = -1.26233f;
    private final float engine2Local = 1.26233f;
    private final Vector3f midPoint = new Vector3f(0, -0.01642f, 4.26027f);
    private final Vector3f tmp = new Vector3f();
    
    private final TrailPoint[] trail = new TrailPoint[60];
    
    private float frameTme = 0;
    
    public EngineTrail(AssetManager assetManager) {
        for (int i = 0; i < trail.length; i++) {
            trail[i] = new TrailPoint(i);
            trail[i].time = POINT_LIFE;
        }
        
        mesh = new TrailMesh();
        
        Material mat = new Material(assetManager, "MatDefs/Unshaded/trail.j3md");
        mat.setBoolean("useAA", GuiGlobals.getInstance().isSupportDerivatives());
        mat.getAdditionalRenderState().setDepthWrite(false);
        mat.getAdditionalRenderState().setBlendMode(RenderState.BlendMode.AlphaAdditive);
        setMaterial(mat);
        setCullHint(Spatial.CullHint.Never);
        setQueueBucket(RenderQueue.Bucket.Transparent);
    }
    
    public void update(Spatial node, boolean isMoving, float tpf) {
        frameTme += tpf;
        
        if (isMoving) {
            if (frameTme >= FPS) {
                for (int i = trail.length - 1; i > 0; i--) {
                    trail[i].copyFrom(trail[i - 1]);
                    trail[i].time += tpf;
                    trail[i].updateColor();
                }

                frameTme = 0;
            }
            
            TrailPoint first = trail[0];
            node.localToWorld(midPoint, first.loc);
            first.rot.set(node.getLocalRotation());
            first.pRot.set(node.getParent().getLocalRotation());
            first.updateColor();
            first.time = 0;
        } else {
            for (TrailPoint tp : trail) {
                tp.time += tpf;
                tp.updateColor();
            }
        }
        
        ((TrailMesh)mesh).updateMesh();
    }
    
    public void reCenter(Vector3f center) {
        for (TrailPoint tp : trail) {
            tp.loc.subtractLocal(center);
        }
    }
    
    private class TrailPoint {
        public final Vector3f loc = new Vector3f();
        public final Quaternion rot = new Quaternion();
        public final Quaternion pRot = new Quaternion();
        public final ColorRGBA col = new ColorRGBA(0.82f, 0, 1, 0);
        public float time = 0;
        public final float trailPerc;
        public final float scale;
        
        public TrailPoint(float listPos) {
            trailPerc = listPos / (trail.length - 1);
            float t = trailPerc / 0.1f;
            scale = GMath.smoothStopFloat(t, 0.5f, 1f);
        }
        
        public void copyFrom(TrailPoint tp) {
            loc.set(tp.loc);
            rot.set(tp.rot);
            pRot.set(tp.pRot);
            col.set(tp.col);
            time = tp.time;
        }
        
        public void updateColor() {
            float lifePerc = time < POINT_LIFE ? 1 - (time / POINT_LIFE) : 0;
            col.a = lifePerc;
            
            col.g = GMath.smoothStopFloat(trailPerc / 0.2f, 0.6f, 0f);
            col.r = GMath.smoothStopFloat(trailPerc / 0.5f, 1, 0.7f);
        }
    }
    
    private class TrailMesh extends Mesh {
        private final float width = 0.41908f;
        
        private TrailMesh() {
            createMesh();
        }
        
        private void createMesh() {
            FloatBuffer verts = BufferUtils.createVector3Buffer(trail.length * 4);
            FloatBuffer tex = BufferUtils.createVector2Buffer(trail.length * 4);
            ByteBuffer col = BufferUtils.createByteBuffer(trail.length * 4 * 4);
            ShortBuffer indices = BufferUtils.createShortBuffer((trail.length - 1) * 12);
            
            Short index = 0;
            float texInd = 0;
            for (TrailPoint tp : trail) {
                float texPerc = texInd / (trail.length - 1);
                
                //left engine left
                tmp.x = engine1Local;
                tmp.y = 0;
                tmp.z = 0;
                
                tp.rot.mult(tmp, tmp);
                
                tmp.x -= width * tp.scale;
                tp.pRot.mult(tmp, tmp);
                tmp.addLocal(tp.loc);
                
                verts.put(tmp.x);
                verts.put(tmp.y);
                verts.put(tmp.z);
                tex.put(0);
                tex.put(texPerc);
                
                //left engine right
                tmp.x = engine1Local;
                tmp.y = 0;
                tmp.z = 0;
                
                tp.rot.mult(tmp, tmp);
                
                tmp.x += width * tp.scale;
                tp.pRot.mult(tmp, tmp);
                tmp.addLocal(tp.loc);
                
                verts.put(tmp.x);
                verts.put(tmp.y);
                verts.put(tmp.z);
                tex.put(1);
                tex.put(texPerc);
                
                int colInt = tp.col.asIntABGR();
                col.putInt(colInt);
                col.putInt(colInt);
                
                //right engine left
                tmp.x = engine2Local;
                tmp.y = 0;
                tmp.z = 0;
                
                tp.rot.mult(tmp, tmp);
                
                tmp.x -= width * tp.scale;
                tp.pRot.mult(tmp, tmp);
                tmp.addLocal(tp.loc);
                
                verts.put(tmp.x);
                verts.put(tmp.y);
                verts.put(tmp.z);
                tex.put(0);
                tex.put(texPerc);
                
                //right engine right
                tmp.x = engine2Local;
                tmp.y = 0;
                tmp.z = 0;
                
                tp.rot.mult(tmp, tmp);
                
                tmp.x += width * tp.scale;
                tp.pRot.mult(tmp, tmp);
                tmp.addLocal(tp.loc);
                
                verts.put(tmp.x);
                verts.put(tmp.y);
                verts.put(tmp.z);
                tex.put(1);
                tex.put(texPerc);
                
                col.putInt(colInt);
                col.putInt(colInt);
                
                if (index < (trail.length - 1) * 4) {
                    indices.put(index);
                    indices.put((short)(index + 1));
                    indices.put((short)(index + 5));
                    indices.put((short)(index + 5));
                    indices.put((short)(index + 4));
                    indices.put(index);

                    indices.put((short)(index + 2));
                    indices.put((short)(index + 3));
                    indices.put((short)(index + 7));
                    indices.put((short)(index + 7));
                    indices.put((short)(index + 6));
                    indices.put((short)(index + 2));

                    index = (short)(index + 4);
                }
                
                texInd++;
            }
            
            verts.flip();
            VertexBuffer vb = new VertexBuffer(VertexBuffer.Type.Position);
            vb.setupData(VertexBuffer.Usage.Stream, 3, VertexBuffer.Format.Float, verts);
            setBuffer(vb);
            
            tex.flip();
            vb = new VertexBuffer(VertexBuffer.Type.TexCoord);
            vb.setupData(VertexBuffer.Usage.Static, 2, VertexBuffer.Format.Float, tex);
            setBuffer(vb);
            
            col.flip();
            vb = new VertexBuffer(VertexBuffer.Type.Color);
            vb.setupData(VertexBuffer.Usage.Stream, 4, VertexBuffer.Format.UnsignedByte, col);
            vb.setNormalized(true);
            setBuffer(vb);
            
            indices.flip();
            vb = new VertexBuffer(VertexBuffer.Type.Index);
            vb.setupData(VertexBuffer.Usage.Static, 3, VertexBuffer.Format.UnsignedShort,
                    indices);
            setBuffer(vb);
            
            updateCounts();
        }
        
        public void updateMesh() {
            VertexBuffer vb = getBuffer(VertexBuffer.Type.Position);
            FloatBuffer verts = (FloatBuffer)vb.getData();
            verts.clear();
            
            VertexBuffer cb = getBuffer(VertexBuffer.Type.Color);
            ByteBuffer col = (ByteBuffer)cb.getData();
            col.clear();
            
            for (TrailPoint tp : trail) {
                //left engine left
                tmp.x = engine1Local;
                tmp.y = 0;
                tmp.z = 0;
                
                tp.rot.mult(tmp, tmp);
                
                tmp.x -= width * tp.scale;
                tp.pRot.mult(tmp, tmp);
                tmp.addLocal(tp.loc);
                
                verts.put(tmp.x);
                verts.put(tmp.y);
                verts.put(tmp.z);
                
                //left engine right
                tmp.x = engine1Local;
                tmp.y = 0;
                tmp.z = 0;
                
                tp.rot.mult(tmp, tmp);
                
                tmp.x += width * tp.scale;
                tp.pRot.mult(tmp, tmp);
                tmp.addLocal(tp.loc);
                
                verts.put(tmp.x);
                verts.put(tmp.y);
                verts.put(tmp.z);
                
                int colInt = tp.col.asIntABGR();
                col.putInt(colInt);
                col.putInt(colInt);
                
                //right engine left
                tmp.x = engine2Local;
                tmp.y = 0;
                tmp.z = 0;
                
                tp.rot.mult(tmp, tmp);
                
                tmp.x -= width * tp.scale;
                tp.pRot.mult(tmp, tmp);
                tmp.addLocal(tp.loc);
                
                verts.put(tmp.x);
                verts.put(tmp.y);
                verts.put(tmp.z);
                
                //right engine right
                tmp.x = engine2Local;
                tmp.y = 0;
                tmp.z = 0;
                
                tp.rot.mult(tmp, tmp);
                
                tmp.x += width * tp.scale;
                tp.pRot.mult(tmp, tmp);
                tmp.addLocal(tp.loc);
                
                verts.put(tmp.x);
                verts.put(tmp.y);
                verts.put(tmp.z);
                
                col.putInt(colInt);
                col.putInt(colInt);
            }
            
            getBuffer(VertexBuffer.Type.TexCoord).getData().clear();
            
            verts.clear();
            vb.updateData(verts);
            col.clear();
            cb.updateData(col);
        }
    }
}

As for testing, I might seek out testers, but I’ll probably just post a finished version. There’s not much to it really. I’ve been running it on my phone, BLU Life One(2015), and also tested it on my tablet, Verizon QMV7B, which was just a freebie. It runs at a constant 60fps, capped, on my phone and usually in the mid thirties on the tablet sometimes dropping into the twenties, but I threw in an option to specify low, medium, or high particle detail and that helped bring the tablet back out of the twenties.

I didn’t care for Google’s EULA for Google Play so I didn’t agree to it and thus have no games installed on my phone. I wanted a game so I made my own :slight_smile:

7 Likes

Curious which parts you objected to. It seemed pretty standard stuff to me.

I haven’t read it recently, but as I recall there was a clause that allowed Google to scan your device and remotely remove any app it wanted without your knowledge. I imagine this is probably Google trying to prevent the spread of malware by automatically removing known malicious software from user devices, but Google could certainly abuse that power.

I don’t use the built-in Google search or really any Google services on my phone, didn’t even register my Google account on my phone. Google bills itself as a technology company, but really they’re an advertising agency. The whole point of Android is for Google to provide a lucrative advertising platform to its clients. Android not only provides yet another means to deliver advertisements to prospective buyers, but also collects a range of information about each buyer so advertisers can better target specific individuals.

P.S. That’s the reason there was all this hullabaloo surrounding Microsoft’s Windows 10 EULA. Microsoft is now trying to compete with Google in the advertising arena and, like Android, Windows 10 collects data on its users for the purposes of targeted advertising. I think Windows 10 takes it a step further and, you know, that’s just competition.

Ultimately I neither trust Google or Microsoft with that information. Even if they don’t care to abuse the data themselves, neither of them have the ability to protect that data from governments and hackers that probably do wish to abuse it. I mean it used to be if a hacker wanted a bunch of personal information they’d have to hack a bunch of computers, now they just need to hack one company.

3 Likes

Thanks for sharing @Tryder

Fixed and overhauled the tractor beams. :smile:

The beam is composed out of 32 lines in a single geometry that have vertex colors for color and a glowmap that fades bloom from bright to black. The vertices are then put into their randomised position via vertex shader as suggested by @Apollo. (passed target position + that one weird thing with a passed random vector)) .

The manipulation is done using physics forces and the beams try to keep the targeted object always in the same position relative to the ship. So you can grab something, spin your ship around and let it fly away due to centrifugal force.

The base effect:

It expands when you hook up larger objects:

And you can target anything that has a bullet physics control. Like other ships:

Or asteroids.

Or even space stations.

Or you can hurl an asteroid into a space station for all I know :stuck_out_tongue:

And yes, this is what that thread was about…

24 Likes

Really really cool! We can see how much effort you put into this game, awesome :+1:

1 Like

Hellow everyone :smiley: Am having some fun whit the filter, even though I could really use some help on the optimisation x)

Anyway, still working on the big presentation, whit sound, some basic IA and everything! Hope you enjoy x)

20 Likes

I like shields design.

Thanks :smiley: Its actually a free model couple whit the ShaderBlow animated material use directly as the material for the shield part.

That library is just so much fun stuff!

new testing “level”, new GUI aiming system:

 

17 Likes

Next Step: Cloth Physics?

Been there. These fall into the category of “I think that will look cool… but serve no purpose”, and are just cloth physics baked out of Blender with a quick and dirty unshaded satin look material.

3 Likes

@MoffKalast Careful now, you’re starting to make the Space Engineers guys look bad. They might send some of those stupid exploding dogs after you.

1 Like

First ever WIP screenshot posted.

13 Likes

…looks vaguely familiar. :slight_smile:

I look forward to seeing what’s next.

2 Likes