(June 2020) Monthly WIP Screenshot Thread

Almost an entire week without screenshots! I’m missing it already.
I guess I’ll start by showing what I’m working on.

This is my level editor and now I can add lights:
Imgur

3D view:
Imgur

Baked lights can generate a lightmap, this is after I loaded it in my game:
Imgur

Still a lot of tweaks to do, but happy with the results so far.

Some details.
The editor is inspired by the build engine: draw some sectors in 2D mode and switch to 3D mode to change heights and choose the texture of the surfaces.
The geometry is generated and exported as .j3o to be loaded by any jme3 app.
Lightmap rendering is accomplished with Sunflow, an old java software render I found googling.
I also made so non-baked lights can be added as normal jme lights to the root node of the level, or exported as an special dsl I use for my game.
Other features include generating the navmesh and defining entities.

15 Likes

I want to teach my young students (ages 10-12) how to program a classic fighting game. So I started creating a sample game. Animations where downloaded from mixamo and blended in Blender then the programming was done with SceneMax3D running JME3 as the rendering engine.
So far ~150 lines of code!

11 Likes

I’ve been toying around with vehicles again to scratch an itch. I’ve started to implement a non-raycast vehicle, meaning the wheels have a weight and collide instead of using rays to simulate collision.

Basically I add a Point2Point joint for each wheel from the chassis to the top of the wheel arch, and then add another joint from there to the center of the wheel. So we have a joint from the vehicle center of mass to each wheel arch, and then a joint from there to the middle of the wheel.

From there I limit the rotation of the joints and wheels - and there we are - a rough skeleton of something to play with.

One of the issues I had with the vehicles tech demo I made was that the Bullet vehicle implements a linear wheel slip algorithm, and I wanted to use the Pacejka formula, so I kinda had to make my own vehicle instead.

12 Likes

When your side projects have side projects.

…cool stuff, though.

4 Likes

@jayfella I’m very glad you’re working on vehicles again. You might be interested in these links:

2 Likes

Much appreciated. They are actually really useful. :heart:

2 Likes

Ive been down this road (hehe), the best resource for me was this (warning lots of math):
http://autoxer.skiblack.com/phys_racing/contents.htm

Message me if you need some help with it.

1 Like

Thanks man. I think I need to release the plugin system before I jump down this rabbit hole :stuck_out_tongue:

1 Like

SARS-Cov-2 spike protein visualized with JME3.
I used CDK to import amino acid sequence and visualized them in JME. Maybe JME could be used for chemical and pharmaceutical purposes in future such as molecular dynamics representation and protein docking to suggest new drugs since java has a better performance than other programming languages which is common for reasearches and JME is also easier to learn and use with its high level API.

9 Likes

If you batch these objects you will have a much better performance. Still probably not good enough for such huge “point clouds”, but at least acceptable, I guess.

See BatchNode

1 Like

I made an app like this once but for a different kind of network/point cloud. Still, we supported millions of objects and this was back in 2004 or so. With spheres like this, too. I provide that as background to my experience on how to make this fly.

Connectors should definitely be batches. For the spheres, on modern hardware I’d be tempted to try instancing. Back in 2004, we heavily used LODs, imposters, and batching for the nodes. They were spheres up close in a batched section of the network. From a distance, they were just a stand-in image of a sphere tinted.

Today I might do similar, batched sections of the tree that were either sphere instances or point sprite clouds. So when close, that subgraph is a bunch of instanced fully meshed spheres (still one draw call). When at a reasonable distance, it’s just one draw call of a point sprite.

My guess is that memory would be your only limitation with a scheme like that… depending on batch size.

1 Like

Thanks guys. I have reduced the vertices to the half and got 6 FPS instead of 1-3 FPS.I wanted to use instancing before making the video but objects just disappeared. Finally, I found that using the InstanceNode() constructor which doesn’t have parameters is actually the problem. It seams that this constructor is for deserialization only. I am not sure why that warning in the javadoc wasn’t there :joy:
Do not use this constructor. Serialization purposes only.

public InstancedNode() {
        super();
        // NOTE: since we are deserializing,
        // the control is going to be added automatically here.
    }

    public InstancedNode(String name) {
        super(name);
        control = new InstancedNodeControl(this);
        addControl(control);
    }

After instancing I got 9 objects in the status panel instead of 47000 and 12 FPS instead of nearly 6. The vertices number remained as it was.
Batching was a long process (actually I didn’t wait more than one minute) and sometimes gives an out of memory exception. Anyway, I think using a 2D image instead of a sphere will be a good trick.

1 Like

It should be ‘protected’ anyway. I think some time back we fixed it so serialization could use protected methods and we hid some of the no-arg constructors this way. InstancedNode must be one we missed.

2 Likes

Or they are running an old version. Whenever I read JME3 I think of 3.0 for some reason.
We also improved instancing performance recently for some case, not sure if it would’ve applied.

And well, batching would probably the easiest/best for non moving molecules (I think that’d be called swinging?), but if that takes a long time, that’s undesireable as well

1 Like

The thing is that those are nicely faceted spheres… that would be a pretty giant batch.

Instancing is at least somewhere between batching and separate nodes with at least the sphere part only there one time in the buffer.

…but even better to draw no spheres at all. :slight_smile:

Actually yes, I was working on another project that uses the old animation system and when I knew about the new animation system I afraid to update JME and rewrite the code :joy:. I am not sure if you kept the old system or not.

We kept the old system. Though marked as “deprecated”, I doubt it’ll disappear any time soon.

Edit: I’ll protect the constructor of InstancedNode and add some javadoc.

1 Like

I’ve been working on the menus and HUD interface for my project lately. Most recently I improved the targeting system and added frames that show the selected target’s face.

I also recently added a chat console and a /command system, which makes it much easier for testing new features in a multiplayer environment without having to add any extra networking code every time. I previously used a debug GUI, but it was tedious to debug new things on the server, and was also becoming difficult to keep organized as the GUI grew - so making a command system seemed like a worthwhile investment of time.

21 Likes

Nothing super-amazing to look at, but nevertheless useful: JME embedded into JavaFX as a library. The frame rate is definitely not on-par with the regular AWT window. It’s primarily designed for applications that use JME as a 3D environment to visualize data (scientific, industrial, etc) or even game editors. Everything pretty much “just works” (sound, input, etc)…

package com.jayfella.jfx.embedded.test;

import com.jayfella.jfx.embedded.SimpleJfxApplication;
import com.jme3.app.FlyCamAppState;
import com.jme3.app.StatsAppState;
import com.jme3.audio.AudioListenerState;
import com.jme3.system.AppSettings;
import com.jme3.util.LWJGLBufferAllocator;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
import org.lwjgl.system.Configuration;

import java.util.concurrent.atomic.AtomicReference;

public class TestJmeEmbedded extends Application {

    public static void main(String... args) {

        // some general settings for JFX for maximum compatibility

        Configuration.GLFW_CHECK_THREAD0.set(false); // need to disable to work on macos
        Configuration.MEMORY_ALLOCATOR.set("jemalloc"); // use jemalloc
        System.setProperty("prism.lcdtext", "false"); // JavaFx

        System.setProperty(LWJGLBufferAllocator.PROPERTY_CONCURRENT_BUFFER_ALLOCATOR, "true");

        launch(args);
    }

    @Override
    public void start(Stage primaryStage) throws Exception {

        // We need to start JME on a new thread, not on the JFX thread.
        // We could do this a million ways, but let's just be as safe as possible.
        AtomicReference<SimpleJfxApplication> jfxApp = new AtomicReference<>();

        new Thread(new ThreadGroup("LWJGL"), () -> {

            // create a new instance of our game.
            SimpleJfxApplication myJmeGame = new MyJmeGame();

            // or add some appstates..
            // SimpleJfxApplication myJmeGame = new MyJmeGame(new StatsAppState(), new AudioListenerState());

            // set our appSettings here
            AppSettings appSettings = myJmeGame.getSettings();
            appSettings.setUseJoysticks(true);
            appSettings.setGammaCorrection(true);
            appSettings.setSamples(16);


            jfxApp.set(myJmeGame);

            // we have a specific "start" method because due to LWJGL3 behavior this method will never return.
            // If we called this method in the constructor, it would never get constructed, so we have seperated
            // the blocking line of code in a method that gets called after construction.
            jfxApp.get().start();

        }, "LWJGL Render").start();

        // wait for the engine to initialize...
        // You can show some kind of indeterminate progress bar in a splash screen while you wait if you like...
        while (jfxApp.get() == null || !jfxApp.get().isInitialized()) {
            Thread.sleep(10);
        }

        // The application is never going to change from hereon in, so we can just reference the actual value.
        // Just remember that any calls to JME need to be enqueued from app.enqueue(Runnable) if you are not on the JME
        // thread (e.g. you're on the JavaFX thread). Any calls to JavaFx need to be done on the JavaFX thread, or via
        // Plaform.runLater(Runnable).
        SimpleJfxApplication app = jfxApp.get();

        primaryStage.setTitle("Test JME Embedded in JavaFx");

        StackPane root = new StackPane();

        // add the ImageView that Jme renders to...
        root.getChildren().add(app.getImageView());

        primaryStage.setScene(new Scene(root, 800, 600));
        primaryStage.show();

    }

}

And for our actual game class, instead of extending SimpleApplication we extend SimpleJfxApplication. Everything else is standard jme/jfx workflow.

package com.jayfella.jfx.embedded.test;

import com.jayfella.jfx.embedded.SimpleJfxApplication;

public class MyJmeGame extends SimpleJfxApplication {

    @Override
    public void initApp() {
        flyCam.setDragToRotate(true);
    }

}

9 Likes

Leap

Out Now

Imgur

What’s in this game:

  • 8 areas to traverse.
  • jump and run (press shift).

I publish a FULL game every 6 months.

5 Likes