EzDevInfo.com

jmonkeyengine

A complete 3D game development suite written purely in Java. jMonkeyEngine - 3D Game Development for Java developersjMonkeyEngine | 3D Game Development for Java developers 3d game development for java developers

jMonkey optimization similar to Java3D's

Edit: For having real-time drawing, started using lwjgl which is base of jmonkeyengine and jocl in an "interoperability" between opengl and opencl, now can calculate and draw 100k particles real-time. Maybe mantle version of jmonkey engine can cure this drawcall overhead problem.

For several days, I have been learning jMonkey engine(ver:3.0) in Eclipse(java 64 bit) and trying how to optimize a scene with using GeometryBatchFactory.optimize(rootNode); command.

Without optimization(with capability of changing spheres positions):

enter image description here

Okay, only 1-fps is originated from both pci-express bandwidth+jvm overhead.

With optimization(without capability to change positions of spheres):

enter image description here

Now it is 29 fps even with increased triangle number.

Java3D had a setCapability() method which makes a scene object be able to be read/written even in an optimized form. jMonkey engine 3.0 must be capable of this subject but I couldn't find any trace of it(searched tutorials and examples, failed).

Question: How can I set read/write position/rotation/scale capabilities of optimized nodes of a scene in jMonkey 3.0? If you cannot give an answer to first question, can you tell me why triangle numbers increase when I use optimization command? Do I have to create a new method to access the graphics card and change the variables myself(jogl maybe?)?

Scene information: 16k particles(spheres of 16x16 res) + 1 point light(and its 4096 resolutioned shadow).

I'm sure we can send several thousands of float numbers in a millisecond through pci-express with ease.

  • Additional info: I'm using Aparapi-kernels to update particle positions which takes 10 milliseconds(16k * 16k interactions to calculate forces).(does not change anything in optimized mode :( ) Can aparapi access those optimized data?

For the case of batchNode.batch(); optimization, here is 1 fps again with lessened object-numbers:

enter image description here

Object number is now only several hundreds but fps is still at 1!

Sending just sphere positions to gpu and letting it calculate the vertex positions could be better than calculating vertexes on cpu plus sending huge data to gpu.

No-one here to help? Already tried batchNode but did not help enough.

I dont want to change 3d api because jMonkey people already reinvented the wheel and I'm happy with current situation. Just trying to squeeze a little more performance(canceling shadows gives %100 speed but quality is important too!).

This java program will become an asteroid-impact scene simulator(there will be choice of asteroid size,mass,speed,angle) with marching-cubes algorithm with LOD(will be millions of particles).

Marching-cubes algorithm would decrease the triangle numbers greatly. If you couldnt give any answer the question, any marching-cubes(or any O(n) convex hull) algorithm for java will be accepted! Data: x,y,z arrays as source and triangle-strip-array as target(iso-surface mesh points)

Thanks.

Here are some samples about the stream(with a much lower resolution):

1)Collapsing of a cube-shaped rock-group by gravitation: enter image description here

2)Exclusion force starts to show itself: enter image description here

3)Exclusion force + gravitation makes the group form a more smooth shape: enter image description here

4)Group forms a sphere(as expected): enter image description here

5)Then, a big stellar body approaches: enter image description here

6)About to touch: enter image description here

7)The moment of impact: enter image description here

With help of Barnes-Hutt algorithm and a truncated potential, particle numbers will be 10x(maybe 100x) more.

Rather than Marching-Cubes algorithm, a ghost cloth which wraps the nbody can give a low-resolutioned hull(more easier than BH but need more computation)

Ghost cloth will be affected by nbody(gravity + exclusion) but nbody will not be affected by cloth which wraps it. Nbody wont be rendered but cloth mesh will be rendered with lower triange count.

enter image description here enter image description here

If MC or above works, this will let the program render a wrapping-cloth for ~200x more particles.


Source: (StackOverflow)

Do you know good JMonkeyEngine tutorials and docs? [closed]

I'm interested in JMonkey for some fun projects, but when I search Google to find tutorials and docs, I can only find either really basic and/or incomplete stuff, like these on http://jmonkeyengine.org/, or really specific ones. Do you know some "from beginner to expert" tutorial for JMonkey?


Source: (StackOverflow)

Advertisements

Relative gravity

I've started using jMonkey engine recently, which is very nice. But I got stuck trying to implement relative gravity.

I want to make planets orbiting around each other (not necessarily in perfectly circular orbit, depends on velocity). So every object should affect other objects.

What I have right now:

turning off global gravity

bulletAppState.getPhysicsSpace().setGravity(Vector3f.ZERO);

initializing spheres and adding to physics space

Sphere sphere = new Sphere(50, 50, 5);
Geometry sun = new Geometry("Sun", sphere);

sun.setMaterial(stone_mat);
rootNode.attachChild(sun);
sun.setLocalTranslation(0, 0, 0);

sunPhysics = new RigidBodyControl((float) (50*Math.pow(10, 5)));
sun.addControl(sunPhysics);
bulletAppState.getPhysicsSpace().add(sunPhysics);

Geometry mercury = new Geometry("Mercury", sphere);

mercury.setMaterial(stone_mat);
rootNode.attachChild(mercury);
mercury.setLocalTranslation(15f, 0, 0);

mercuryPhysics = new RigidBodyControl((float) (5));
mercury.addControl(mercuryPhysics);
bulletAppState.getPhysicsSpace().add(mercuryPhysics);

I noticed that there is method setGravity in RigidBodyControl class, but it just sets the direction. So object goes that way until it disappears.

I am really looking forward for answers.


Source: (StackOverflow)

OpenGL too hard for me, is there any alternative? [closed]

I have read the famous "Learning Modern 3d Graphics Programming" til the hierarchy chapter but it seems way too hard to me, or at least too long to learn (I have to do a project to render a 3d landscape in which the camera can move + lighting effects + objects). I have used the java translation of the gltut and I still need to do my project in java.

So here's the question: Is there any engine, a little more easy to use for the beginners, in which we can easily render scenes but not an engine where a simple makeScene() will do all the job?

I've heard of jmonkeyengine, is that a good alternative?


Source: (StackOverflow)

JME 3 + Swing, multiple canvases

I am playing with JME3 and currently facing the following problem:

When LWJGL canvases are included in multiple tabs of application, none of them or only 1 runs.

Here is an example:

SwingCanvas.java:

package jme3test.helloworld;

import java.awt.Dimension;
import javax.swing.JFrame;

import com.jme3.app.SimpleApplication;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.scene.Geometry;
import com.jme3.scene.shape.Box;
import com.jme3.system.AppSettings;
import com.jme3.system.JmeCanvasContext;

public class SwingCanvas extends SimpleApplication {

    private void SwingCanvasTest() {
        SwingCanvas app = new SwingCanvas();
        app.start();
    }

    @Override
    public void simpleInitApp() {
        // activate windowed input behaviour
        flyCam.setDragToRotate(true);

        Box box = new Box(2, 2, 2);
        Geometry geom = new Geometry("Box", box);
        Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
        mat.setColor("Color", ColorRGBA.Blue);
        geom.setMaterial(mat);

        rootNode.attachChild(geom); // make the cube appear in the scene
    }

    public JmeCanvasContext createJMEcanvas(){
        AppSettings settings = new AppSettings(true);
        settings.setWidth(640);
        settings.setHeight(480);

        this.setSettings(settings);
        this.createCanvas(); // create canvas!

        JmeCanvasContext ctx = (JmeCanvasContext) this.getContext();
        ctx.setSystemListener(this);
        Dimension dim = new Dimension(640, 480);
        ctx.getCanvas().setPreferredSize(dim);

        return ctx;
    }

    public static void main(String[] args) {
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {

                SwingCanvas canvasApplication = new SwingCanvas();

                JFrame window = new JFrame("Swing Application");
                window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

                window.add(canvasApplication.createJMEcanvas().getCanvas());
                window.pack();
                window.setVisible(true);

                canvasApplication.start();              
            }
        });
    }
}

SwingApplicationJME.java:

package jme3test.helloworld;

import java.awt.BorderLayout;

import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JSplitPane;
import javax.swing.JTabbedPane;
import javax.swing.SwingUtilities;

import com.jme3.system.JmeCanvasContext;

public class SwingApplicationJME {

    public SwingApplicationJME(){
        JFrame frame = new JFrame("JME Swing Application");
        frame.setSize(800, 600);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(getLayout());
        frame.setVisible(true);
    }

    private JComponent getLayout(){
        JTabbedPane tabbedPane = new JTabbedPane();

        SwingCanvas canvas1 = new SwingCanvas();
        SwingCanvas canvas2 = new SwingCanvas();
        SwingCanvas canvas3 = new SwingCanvas();

        JmeCanvasContext ctx1 = canvas1.createJMEcanvas();
        JmeCanvasContext ctx2 = canvas2.createJMEcanvas();
        JmeCanvasContext ctx3 = canvas3.createJMEcanvas();

        JPanel JME_panel_1 = new JPanel(new BorderLayout());
        JME_panel_1.add(new JButton("WEST"), BorderLayout.WEST);
        JME_panel_1.add(new JButton("NORTH"), BorderLayout.NORTH);
        JME_panel_1.add(new JButton("EAST"), BorderLayout.EAST);
        JME_panel_1.add(new JButton("SOUTH"), BorderLayout.SOUTH);
        JME_panel_1.add(ctx1.getCanvas(), BorderLayout.CENTER);

        JPanel JME_panel_2 = new JPanel();
        JSplitPane splitPaneVertical = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
        splitPaneVertical.add(new JButton("Vertical Button"), JSplitPane.LEFT);
        splitPaneVertical.add(ctx2.getCanvas(), JSplitPane.RIGHT);
        JME_panel_2.add(splitPaneVertical);

        JPanel JME_panel_3 = new JPanel();
        JSplitPane splitPaneHorizontal = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
        splitPaneHorizontal.add(new JButton("Horizontal Button"), JSplitPane.TOP);
        splitPaneHorizontal.add(ctx3.getCanvas(), JSplitPane.BOTTOM);
        JME_panel_3.add(splitPaneHorizontal);

        tabbedPane.add(JME_panel_1, "JME border panel");
        tabbedPane.add(JME_panel_2, "JME vetical split panel");
        tabbedPane.add(JME_panel_3, "JME horizontal split panel");

        return tabbedPane;
    }

    public static void main(String [] s){
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                SwingApplicationJME app = new SwingApplicationJME();
            }
        });
    }
}

Any ideas please =)


Source: (StackOverflow)

3D plot in java. Java3D or Jmonkey [closed]

I wanna plot a 3D points cloud ( say 100000 points) in Java, being able to drag and rotate it and select one of the plotted 3D points and get x,y,z of it by clicking on it. I am concerned about the continuation of support for java3D and at the same time I see that java3D is still a bigger community and a lot more active than JMonkey3 which is the stable version of jme3. I wanna deploy it as an applet too.

What technology should I choose?


Source: (StackOverflow)

Why is my character either hovering or falling through the floor?

I'm making a simple 3D scene with a character and a floor but the character is hovering, or falling through the scene if I put the y coordinate to a negative.

private void createCharacters() {
    CapsuleCollisionShape capsule = new CapsuleCollisionShape(3f, 4f);
    character = new CharacterControl(capsule, 0.01f);
    model = (Node) assetManager.loadModel("Models/Ninja/Ninja.mesh.xml");
    float scale = 0.25f;
    model.scale(0.05f, 0.05f, 0.05f);
    model.addControl(character);
    character.setPhysicsLocation(new Vector3f(0, -0.15f, 0));
    model.setShadowMode(ShadowMode.CastAndReceive);
    character.setViewDirection(new Vector3f(1, 0, 0));
    rootNode.attachChild(model);
    getPhysicsSpace().add(character);

}

The above code makes the character fall through the scene. Changing it just a little bit to this makes the character hover:

character.setPhysicsLocation(new Vector3f(0, -0.09f, 0));

enter image description here

If you want to inspect all of the code it's here

package adventure;

import java.applet.Applet;
import com.jme3.math.Quaternion;
import com.jme3.math.FastMath;
import java.applet.AudioClip;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Image;
import java.awt.TextArea;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import com.jme3.material.RenderState.FaceCullMode;
import javax.swing.JFrame;
import javax.swing.JPanel;
import com.jme3.renderer.queue.RenderQueue.ShadowMode;
import com.jme3.animation.AnimChannel;
import com.jme3.animation.AnimControl;
import com.jme3.animation.AnimEventListener;
import com.jme3.animation.LoopMode;
import com.jme3.app.SimpleApplication;
import com.jme3.asset.BlenderKey;
import com.jme3.asset.TextureKey;
import com.jme3.asset.plugins.ZipLocator;
import com.jme3.bullet.BulletAppState;
import com.jme3.bullet.PhysicsSpace;
import com.jme3.bullet.collision.PhysicsCollisionEvent;
import com.jme3.bullet.collision.PhysicsCollisionListener;
import com.jme3.bullet.collision.shapes.CapsuleCollisionShape;
import com.jme3.bullet.collision.shapes.CollisionShape;
import com.jme3.bullet.collision.shapes.SphereCollisionShape;
import com.jme3.bullet.control.CharacterControl;
import com.jme3.bullet.control.RigidBodyControl;
import com.jme3.bullet.util.CollisionShapeFactory;
import com.jme3.effect.ParticleEmitter;
import com.jme3.effect.ParticleMesh.Type;
import com.jme3.effect.shapes.EmitterSphereShape;
import com.jme3.input.ChaseCamera;
import com.jme3.input.KeyInput;
import com.jme3.input.controls.ActionListener;
import com.jme3.input.controls.KeyTrigger;
import com.jme3.light.DirectionalLight;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Vector2f;
import com.jme3.math.Vector3f;
import com.jme3.post.FilterPostProcessor;
import com.jme3.post.filters.BloomFilter;
import com.jme3.renderer.Camera;
import com.jme3.renderer.queue.RenderQueue.ShadowMode;
import com.jme3.scene.Geometry;
import com.jme3.scene.Node;
import com.jme3.scene.Spatial;
import com.jme3.scene.shape.Box;
import com.jme3.scene.shape.Sphere;
import com.jme3.scene.shape.Sphere.TextureMode;
import com.jme3.system.AppSettings;
import com.jme3.system.JmeCanvasContext;
import com.jme3.terrain.geomipmap.TerrainLodControl;
import com.jme3.terrain.geomipmap.TerrainQuad;
import com.jme3.terrain.heightmap.AbstractHeightMap;
import com.jme3.terrain.heightmap.ImageBasedHeightMap;
import com.jme3.texture.Texture;
import com.jme3.texture.Texture.WrapMode;
import com.jme3.util.SkyFactory;

public class MountainWorld extends SimpleApplication implements ActionListener,
        PhysicsCollisionListener, AnimEventListener, Playable {






      /** Prepare Materials */
      Material wall_mat;
      Material stone_mat;
      Material floor_mat;

      /** Prepare geometries and physical nodes for bricks and cannon balls. */
      private RigidBodyControl    brick_phy;
      private static final Box    box;
      private RigidBodyControl    ball_phy;
      private static final Sphere sphere;
      private RigidBodyControl    floor_phy;
      private static final Box    floor;

      /** dimensions used for bricks and wall */
      private static final float brickLength = 0.48f;
      private static final float brickWidth  = 0.24f;
      private static final float brickHeight = 0.12f;

      static {
        /** Initialize the cannon ball geometry */
        sphere = new Sphere(32, 32, 0.4f, true, false);
        sphere.setTextureMode(TextureMode.Projected);
        /** Initialize the brick geometry */
        box = new Box(Vector3f.ZERO, brickLength, brickHeight, brickWidth);
        box.scaleTextureCoordinates(new Vector2f(1f, .5f));
        /** Initialize the floor geometry */
        floor = new Box(Vector3f.ZERO, 10f, 0.1f, 5f);
        floor.scaleTextureCoordinates(new Vector2f(3, 6));
      }







    private static World world;
    private static Person person;
    private static Player dplayer;
    private static TextArea textarea;
    private BulletAppState bulletAppState;
    private AnimChannel channel;
    private AnimControl control;
    // character
    CharacterControl character;
    Node model;
    // temp vectors
    Vector3f walkDirection = new Vector3f();
    // terrain
    TerrainQuad terrain;
    RigidBodyControl terrainPhysicsNode;
    // Materials
    Material matRock;
    Material matBullet;
    // animation
    AnimChannel animationChannel;
    AnimChannel shootingChannel;
    AnimControl animationControl;
    float airTime = 0;
    // camera
    boolean left = false, right = false, up = false, down = false;
    ChaseCamera chaseCam;
    // bullet
    Sphere bullet;
    SphereCollisionShape bulletCollisionShape;
    // explosion
    ParticleEmitter effect;
    // brick wall
    Box brick;
    float bLength = 0.8f;
    float bWidth = 0.4f;
    float bHeight = 0.4f;
    FilterPostProcessor fpp;
    private Spatial sceneModel;

    private RigidBodyControl landscape;
    public static void main(String[] args) {
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                AppSettings settings = new AppSettings(true);
                settings.setWidth(850);
                settings.setHeight(440);

                MountainWorld canvasApplication = new MountainWorld();
                canvasApplication.setSettings(settings);
                canvasApplication.createCanvas(); // create canvas!
                JmeCanvasContext ctx = (JmeCanvasContext) canvasApplication
                        .getContext();
                ctx.setSystemListener(canvasApplication);
                Dimension dim = new Dimension(640, 480);
                ctx.getCanvas().setPreferredSize(dim);

                JFrame window = new JFrame("Mountain World");
                window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

                JPanel panel = new JPanel(new BorderLayout()); // a panel
                world = new DungeonWorld(canvasApplication);
                person = new Person(world, "You", null);
                dplayer = new Player(world, person);
                Commands commands = new Commands(person);
                textarea = new TextArea("", 10, 60,
                        TextArea.SCROLLBARS_VERTICAL_ONLY);
                textarea.append("You are in a mountain. The trolls live here.\n");
                textarea.setEditable(false);
                panel.add("West", ctx.getCanvas());
                panel.add("East", commands);
                panel.add("South", textarea);
                window.add(panel);
                window.pack();
                window.setVisible(true);
                canvasApplication.startCanvas();

            }
        });
    }

    @Override
    public void simpleInitApp() {
        bulletAppState = new BulletAppState();
        bulletAppState.setThreadingType(BulletAppState.ThreadingType.PARALLEL);
        stateManager.attach(bulletAppState);
        setupKeys();
        //prepareBullet();
        //prepareEffect();
        createLight();
        //createSky();
        initMaterials();
        initFloor();
        //createTerrain();
        //createWall();
        createCharacters();
        setupChaseCamera();
        setupAnimationController();
        setupFilter();
    }
     /** Make a solid floor and add it to the scene. */
      public void initFloor() {
        Geometry floor_geo = new Geometry("Floor", floor);
        floor_geo.setMaterial(floor_mat);
        floor_geo.setLocalTranslation(0, -0.1f, 0);
        this.rootNode.attachChild(floor_geo);
        /* Make the floor physical with mass 0.0f! */
        floor_phy = new RigidBodyControl(0.0f);
        floor_geo.addControl(floor_phy);
        bulletAppState.getPhysicsSpace().add(floor_phy);
      }

      /** Initialize the materials used in this scene. */
      public void initMaterials() {
        wall_mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
        TextureKey key = new TextureKey("Textures/Terrain/BrickWall/BrickWall.jpg");
        key.setGenerateMips(true);
        Texture tex = assetManager.loadTexture(key);
        wall_mat.setTexture("ColorMap", tex);

        stone_mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
        TextureKey key2 = new TextureKey("Textures/Terrain/Rock/Rock.PNG");
        key2.setGenerateMips(true);
        Texture tex2 = assetManager.loadTexture(key2);
        stone_mat.setTexture("ColorMap", tex2);

        floor_mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
        TextureKey key3 = new TextureKey("Textures/Terrain/Pond/Pond.jpg");
        key3.setGenerateMips(true);
        Texture tex3 = assetManager.loadTexture(key3);
        tex3.setWrap(WrapMode.Repeat);
        floor_mat.setTexture("ColorMap", tex3);
      }


    private void setupFilter() {
        FilterPostProcessor fpp = new FilterPostProcessor(assetManager);
        BloomFilter bloom = new BloomFilter(BloomFilter.GlowMode.Objects);
        fpp.addFilter(bloom);
        viewPort.addProcessor(fpp);
    }

    private PhysicsSpace getPhysicsSpace() {
        return bulletAppState.getPhysicsSpace();
    }

    private void setupKeys() {
        inputManager.addMapping("wireframe", new KeyTrigger(KeyInput.KEY_T));
        inputManager.addListener(this, "wireframe");
        inputManager.addMapping("CharLeft", new KeyTrigger(KeyInput.KEY_A));
        inputManager.addMapping("CharRight", new KeyTrigger(KeyInput.KEY_D));
        inputManager.addMapping("CharUp", new KeyTrigger(KeyInput.KEY_W));
        inputManager.addMapping("CharDown", new KeyTrigger(KeyInput.KEY_S));
        inputManager.addMapping("CharSpace",
                new KeyTrigger(KeyInput.KEY_RETURN));
        inputManager
                .addMapping("CharShoot", new KeyTrigger(KeyInput.KEY_SPACE));
        inputManager.addListener(this, "CharLeft");
        inputManager.addListener(this, "CharRight");
        inputManager.addListener(this, "CharUp");
        inputManager.addListener(this, "CharDown");
        inputManager.addListener(this, "CharSpace");
        inputManager.addListener(this, "CharShoot");
    }

    private void createWall() {
        float xOff = -144;
        float zOff = -40;
        float startpt = bLength / 4 - xOff;
        float height = 6.1f;
        brick = new Box(Vector3f.ZERO, bLength, bHeight, bWidth);
        brick.scaleTextureCoordinates(new Vector2f(1f, .5f));
        for (int j = 0; j < 15; j++) {
            for (int i = 0; i < 4; i++) {
                Vector3f vt = new Vector3f(i * bLength * 2 + startpt, bHeight
                        + height, zOff);
                addBrick(vt);
            }
            startpt = -startpt;
            height += 1.01f * bHeight;
        }
    }

    private void addBrick(Vector3f ori) {
        Geometry reBoxg = new Geometry("brick", brick);
        reBoxg.setMaterial(matBullet);
        reBoxg.setLocalTranslation(ori);
        reBoxg.addControl(new RigidBodyControl(1.5f));
        reBoxg.setShadowMode(ShadowMode.CastAndReceive);
        this.rootNode.attachChild(reBoxg);
        this.getPhysicsSpace().add(reBoxg);
    }

    private void prepareBullet() {
        bullet = new Sphere(32, 32, 0.4f, true, false);
        bullet.setTextureMode(TextureMode.Projected);
        bulletCollisionShape = new SphereCollisionShape(0.4f);
        matBullet = new Material(getAssetManager(),
                "Common/MatDefs/Misc/Unshaded.j3md");
        matBullet.setColor("Color", ColorRGBA.Green);
        // matBullet.setColor("m_GlowColor", ColorRGBA.Green);
        getPhysicsSpace().addCollisionListener(this);
    }

    private void prepareEffect() {
        int COUNT_FACTOR = 1;
        float COUNT_FACTOR_F = 1f;
        effect = new ParticleEmitter("Flame", Type.Triangle, 32 * COUNT_FACTOR);
        effect.setSelectRandomImage(true);
        effect.setStartColor(new ColorRGBA(1f, 0.4f, 0.05f,
                (float) (1f / COUNT_FACTOR_F)));
        effect.setEndColor(new ColorRGBA(.4f, .22f, .12f, 0f));
        effect.setStartSize(1.3f);
        effect.setEndSize(2f);
        effect.setShape(new EmitterSphereShape(Vector3f.ZERO, 1f));
        effect.setParticlesPerSec(0);
        effect.setGravity(0, -5, 0);
        effect.setLowLife(.4f);
        effect.setHighLife(.5f);
        effect.setInitialVelocity(new Vector3f(0, 7, 0));
        effect.setVelocityVariation(1f);
        effect.setImagesX(2);
        effect.setImagesY(2);
        Material mat = new Material(assetManager,
                "Common/MatDefs/Misc/Particle.j3md");
        mat.setTexture("Texture",
                assetManager.loadTexture("Effects/Explosion/flame.png"));
        effect.setMaterial(mat);
        // effect.setLocalScale(100);
        rootNode.attachChild(effect);
    }

    private void createLight() {
        Vector3f direction = new Vector3f(-0.1f, -0.7f, -1).normalizeLocal();
        DirectionalLight dl = new DirectionalLight();
        dl.setDirection(direction);
        dl.setColor(new ColorRGBA(1f, 1f, 1f, 1.0f));
        rootNode.addLight(dl);
    }

    private void createSky() {
        rootNode.attachChild(SkyFactory.createSky(assetManager,
                "Textures/Sky/Bright/BrightSky.dds", false));
    }

    private void createTerrain2() {
        matRock = new Material(assetManager,
                "Common/MatDefs/Terrain/TerrainLighting.j3md");
        matRock.setBoolean("useTriPlanarMapping", false);
        matRock.setBoolean("WardIso", true);
        matRock.setTexture("AlphaMap",
                assetManager.loadTexture("Textures/Terrain/splat/alphamap.png"));
        Texture heightMapImage = assetManager
                .loadTexture("Textures/Terrain/splat/mountains512.png");
        Texture grass = assetManager
                .loadTexture("Textures/Terrain/splat/grass.jpg");
        grass.setWrap(WrapMode.Repeat);
        matRock.setTexture("DiffuseMap", grass);
        matRock.setFloat("DiffuseMap_0_scale", 64);
        Texture dirt = assetManager
                .loadTexture("Textures/Terrain/splat/dirt.jpg");
        dirt.setWrap(WrapMode.Repeat);
        matRock.setTexture("DiffuseMap_1", dirt);
        matRock.setFloat("DiffuseMap_1_scale", 16);
        Texture rock = assetManager
                .loadTexture("Textures/Terrain/splat/road.jpg");
        rock.setWrap(WrapMode.Repeat);
        matRock.setTexture("DiffuseMap_2", rock);
        matRock.setFloat("DiffuseMap_2_scale", 128);
        Texture normalMap0 = assetManager
                .loadTexture("Textures/Terrain/splat/grass_normal.jpg");
        normalMap0.setWrap(WrapMode.Repeat);
        Texture normalMap1 = assetManager
                .loadTexture("Textures/Terrain/splat/dirt_normal.png");
        normalMap1.setWrap(WrapMode.Repeat);
        Texture normalMap2 = assetManager
                .loadTexture("Textures/Terrain/splat/road_normal.png");
        normalMap2.setWrap(WrapMode.Repeat);
        matRock.setTexture("NormalMap", normalMap0);
        matRock.setTexture("NormalMap_1", normalMap2);
        matRock.setTexture("NormalMap_2", normalMap2);

        AbstractHeightMap heightmap = null;
        try {
            heightmap = new ImageBasedHeightMap(heightMapImage.getImage(),
                    0.25f);
            heightmap.load();

        } catch (Exception e) {
            e.printStackTrace();
        }

        terrain = new TerrainQuad("terrain", 65, 513, heightmap.getHeightMap());
        List<Camera> cameras = new ArrayList<Camera>();
        cameras.add(getCamera());
        TerrainLodControl control = new TerrainLodControl(terrain, cameras);
        terrain.addControl(control);
        terrain.setMaterial(matRock);
        terrain.setLocalScale(new Vector3f(2, 2, 2));

        terrainPhysicsNode = new RigidBodyControl(
                CollisionShapeFactory.createMeshShape(terrain), 0);
        terrain.addControl(terrainPhysicsNode);
        rootNode.attachChild(terrain);
        getPhysicsSpace().add(terrainPhysicsNode);
    }

    private void createTerrain() {


         assetManager.registerLocator("town.zip", ZipLocator.class);
         sceneModel = assetManager.loadModel("main.scene");
        //sceneModel = assetManager.loadModel("Scenes/ManyLights/Main.scene");
        sceneModel.setLocalScale(2f);
        //initFloor();
        // We set up collision detection for the scene by creating a
        // compound collision shape and a static RigidBodyControl with mass
        // zero.
        CollisionShape sceneShape = CollisionShapeFactory
                .createMeshShape((Node) sceneModel);
        landscape = new RigidBodyControl(sceneShape, 0);
        sceneModel.addControl(landscape);
        List<Camera> cameras = new ArrayList<Camera>();
        cameras.add(getCamera());
        rootNode.attachChild(sceneModel);
    }

    private void createCharacters() {
        CapsuleCollisionShape capsule = new CapsuleCollisionShape(3f, 4f);
        character = new CharacterControl(capsule, 0.01f);
        model = (Node) assetManager.loadModel("Models/Ninja/Ninja.mesh.xml");
        float scale = 0.25f;
        model.scale(0.05f, 0.05f, 0.05f);
        model.addControl(character);
        character.setPhysicsLocation(new Vector3f(0, -0.09f, 0));
        model.setShadowMode(ShadowMode.CastAndReceive);
        character.setViewDirection(new Vector3f(1, 0, 0));
        rootNode.attachChild(model);
        getPhysicsSpace().add(character);

        //BlenderKey blenderKey = new BlenderKey("Models/Oto/Oto.mesh.xml");

        //Spatial man = (Spatial) assetManager.loadModel(blenderKey);
        //man.setLocalTranslation(new Vector3f(-140, 12.5f, -10));

        // man.setShadowMode(ShadowMode.CastAndReceive);
        //rootNode.attachChild(man);

    }

    private void setupChaseCamera() {
        flyCam.setEnabled(false);
        chaseCam = new ChaseCamera(cam, model, inputManager);
    }

    private void setupAnimationController() {
        animationControl = model.getControl(AnimControl.class);
        animationControl.addListener(this);
        animationChannel = animationControl.createChannel();
        // shootingChannel = animationControl.createChannel();
        // shootingChannel.addBone(animationControl.getSkeleton().getBone(
        // "uparm.right"));
        // shootingChannel.addBone(animationControl.getSkeleton().getBone(
        // "arm.right"));
        // shootingChannel.addBone(animationControl.getSkeleton().getBone(
        // "hand.right"));
    }

    @Override
    public void simpleUpdate(float tpf) {
        Vector3f camDir = cam.getDirection().clone().multLocal(0.1f);
        Vector3f camLeft = cam.getLeft().clone().multLocal(0.1f);
        camDir.y = 0;
        camLeft.y = 0;
        walkDirection.set(0, 0, 0);
        if (left) {
            walkDirection.addLocal(camLeft);
        }
        if (right) {
            walkDirection.addLocal(camLeft.negate());
        }
        if (up) {
            walkDirection.addLocal(camDir);
        }
        if (down) {
            walkDirection.addLocal(camDir.negate());
        }
        if (!character.onGround()) {
            airTime = airTime + tpf;
        } else {
            airTime = 0;
        }
        if (walkDirection.length() == 0) {
            if (!"Idle1".equals(animationChannel.getAnimationName())) {
                animationChannel.setAnim("Idle1", 1f);
            }
        } else {
            character.setViewDirection(walkDirection);
            if (airTime > .3f) {
                if (!"stand".equals(animationChannel.getAnimationName())) {
                    animationChannel.setAnim("stand");
                }
            } else if (!"Walk".equals(animationChannel.getAnimationName())) {
                animationChannel.setAnim("Walk", 0.7f);
            }
        }
        character.setWalkDirection(walkDirection);
    }

    public void onAction(String binding, boolean value, float tpf) {
        if (binding.equals("CharLeft")) {
            if (value) {
                left = true;
            } else {
                left = false;
            }
        } else if (binding.equals("CharRight")) {
            if (value) {
                right = true;
            } else {
                right = false;
            }
        } else if (binding.equals("CharUp")) {
            if (value) {
                up = true;
            } else {
                up = false;
            }
        } else if (binding.equals("CharDown")) {
            if (value) {
                down = true;
            } else {
                down = false;
            }
        } else if (binding.equals("CharSpace")) {
            character.jump();
        } else if (binding.equals("CharShoot") && !value) {
            bulletControl();
        }
    }

    private void bulletControl() {
        shootingChannel.setAnim("Dodge", 0.1f);
        shootingChannel.setLoopMode(LoopMode.DontLoop);
        Geometry bulletg = new Geometry("bullet", bullet);
        bulletg.setMaterial(matBullet);
        bulletg.setShadowMode(ShadowMode.CastAndReceive);
        bulletg.setLocalTranslation(character.getPhysicsLocation().add(
                cam.getDirection().mult(5)));
        RigidBodyControl bulletControl = new BombControl(bulletCollisionShape,
                1);
        bulletControl.setCcdMotionThreshold(0.1f);
        bulletControl.setLinearVelocity(cam.getDirection().mult(80));
        bulletg.addControl(bulletControl);
        rootNode.attachChild(bulletg);
        getPhysicsSpace().add(bulletControl);
    }

    public void collision(PhysicsCollisionEvent event) {
        if (event.getObjectA() instanceof BombControl) {
            final Spatial node = event.getNodeA();
            effect.killAllParticles();
            effect.setLocalTranslation(node.getLocalTranslation());
            effect.emitAllParticles();
        } else if (event.getObjectB() instanceof BombControl) {
            final Spatial node = event.getNodeB();
            effect.killAllParticles();
            effect.setLocalTranslation(node.getLocalTranslation());
            effect.emitAllParticles();
        }
    }

    public void onAnimCycleDone(AnimControl control, AnimChannel channel,
            String animName) {
        if (channel == shootingChannel) {
            channel.setAnim("stand");
        }
    }

    public void onAnimChange(AnimControl control, AnimChannel channel,
            String animName) {
    }

    // Load an image from the net, making sure it has already been
    // loaded when the method returns
    public Image loadPicture(String imageName) {
        return null;
    }

    // Load and play a sound from /usr/local/hacks/sounds/

    public void playSound(String name) {
        URL u = null;

        try {
            u = new URL("file:" + "/usr/local/hacks/sounds/" + name + ".au");
        } catch (MalformedURLException e) {
        }

        AudioClip a = Applet.newAudioClip(u);
        a.play();
    }
}

Source: (StackOverflow)

How can I draw a straight line in the JMonkey Engine library

I'm trying to draw straight lines between 3D vertices that I specify using the JMonkey Engine 3D graphics library. JMonkey is of course optimised for importing models but I understand it can be used to create custom shapes "internally" as well.

So for example if I was to try to plot between:
(2,0,0)
(-1,0,1)
(0,1,1)
(1,1,1)
(1,4,0)

Then I would get:

JMonkey straight lines


Source: (StackOverflow)

Smooth rotation with quaternions

Quaternion can describe not only rotation, but also an orientation, i.e. rotation from initial (zero) position.

I was wishing to model smooth rotation from one orientation to another. I calculated start orientation startOrientation and end orientation endOrientation and was wishing to describe intermediate orientations as startOrientation*(1-argument) + endOrientation*argument while argument changes from 0 to 1.

The code for monkey engine update function is follows:

@Override
    public void simpleUpdate(float tpf) {

        if( endOrientation != null ) {

            if( !started ) {
                started = true;
            }
            else {

                fraction += tpf * speed;
                argument = (float) ((1 - Math.cos(fraction * Math.PI)) / 2);

                orientation = startOrientation.mult(1-argument).add(endOrientation.mult(argument));
                //orientation = startOrientation.mult(1-fraction).add(endOrientation.mult(fraction));
                log.debug("tpf = {}, fraction = {}, argument = {}", tpf, fraction, argument);
                //log.debug("orientation = {}", orientation);

                rootNode.setLocalRotation(orientation);

                if( fraction >= 1 ) {

                    rootNode.setLocalRotation(endOrientation);
                    log.debug("Stopped rotating");

                    startOrientation = endOrientation = null;
                    fraction = 0;
                    started = false;
                }
            }
        }


    }

The cosine formula was expected to model smooth accelerating at the beginning and decelerating at the end.

The code works but not as expected: the smooth rotation starts and finishes long before fraction and argument values reach 1 and I don't understand, why.

Why the orientation value reaches endOrientation so fast?


Source: (StackOverflow)

jmonkeyengine movement too fast for collision detection

I am making a Java game using JMonkeyEngine and I have followed the tutorial on their site to shoot balls (bullets) at a wall. I get how everything works, but when I increase the velocity of the bullet, it passes straight through the wall.

Now I know the reason why this is happening (because the bullet moves too fast per frame for collision to register). I also know how to solve for this and I have found the following method on their website (JMonkeyEngine).

setCcdMotionThreshold(0f)

But can anyone tell me how this is implemented or where I can find a sample of someone using this?


Source: (StackOverflow)

jMonkeyEngine OBJ file does not appear as expected

My Artist created a 3d shoe model as FBX in 3d studio Max . which looks as the following image.

3d Shoe model snapshot of FBX file

i use jMonkeyEngine in my Program, and it does not support FBX file so i export FBX to wavefront OBJ file , the 3d studio max also gives me the corresponding mtl file as well.

so when i load the exported obj model into my program which uses jMonkeyEngine as a library,it does not look as real shoe , not it has any texture on it.

3d shoe Model snapshot of OBJ file

the program also shows one warning

WARNING: OBJ mesh style_7-geom-0 doesnt contain normals! It might not display correctly

my simpleInitApp method

Spatial myModel = assetManager.loadModel("/Textures/Shoes/style_7.obj");
    myModel.scale(0.09f);
    rootNode.attachChild(myModel);

both the OBJ file and the material file are in the same directory. so i think as per the doc jMonkeyEngine directly load the material from the same directory where the OBJ resides.

if you want i can upload here OBJ file and the material file plus all of the needed images here.

My absolute goal is to display the same Model in JmonkeyEngine as shown in screenshot1.

what i am missing ? what did i do wrong ?

Update on 16-JULY- 2013

OBJ Model Material File Resources

Thanks


Source: (StackOverflow)

jMonkeyEngine: importing .x models

I found this importer for .x files in the jMonkeyEngine SDK plugins: http://jmonkeyengine.org/groups/contribution-depot-jme3/forum/topic/directx-to-j3o-converter/?topic_page=1&num=15 , and I downloaded/installed it successfully via the Tools -> Plugins menu.

But I'm not sure how to use it. I tried adding a model to my assets folder, then right-clicking it in the SDK and choosing "Convert to j3o Binary", but this accomplished nothing: no dialogs popped up, and nothing seemed to change at all. My code still generates a runtime warning stating that it doesn't know how to load a .x file.

Screenshot

P.S. I posted this question as a reply on the linked thread as well. So far, no responses, so that's why I'm posting here, but just a heads-up in case someone replies there in the near future.

Update: A user replied to the thread, suggesting I check to see if any errors are being thrown (a little red error icon in the bottom-right corner of the screen). Sure enough, there was, and the error message was the converter complaining about not being able to find the dwarf.jpg texture. So I moved the texture into the Models folder next to the dwarf1.x model.

However, the conversion process is still behaving the same way, except that the error icon doesn't come up. In other words, nothing appears to be happening now, and no error messages are being thrown. I don't see any .j3mo file having been created anywhere, and my code is still causing a runtime exception that complains about not having a loader for .x files. (Note: I saw the filename typo in my screenshot, "dwarf.x" instead of "dwarf1.x", and have since corrected it, so that is not related to the problem at all)


Source: (StackOverflow)

jme3 - UV map misplaced on model exported from Blender

I created a simple model of a barrel (.zip) in Blender 2.69. Then I created a UV map in Blender and made a UV mapped texture out of it (its in the archive, too). Then I imported my texture in Blender, now the mapping matches:

The mapping

In Blender the model looks fine so far:

Model in Blender

By using the Ogre exporter plugin that I installed via the jmonkeyengine SDK, I exported the model. The result of this is my OgreXML format file of the barrel (I did not export material).

Now, I tried to add the barrel to my world like this:

this.barrel = this.assetManager.loadModel("models/barrel/Barrel.mesh.xml");

Material barrelMat = new Material(this.assetManager,
        "Common/MatDefs/Light/Lighting.j3md");
barrelMat.setTexture("DiffuseMap",
        this.assetManager.loadTexture("models/barrel/Barrel.jpg"));
barrelMat.setBoolean("UseMaterialColors", true);
barrelMat.setColor("Diffuse", ColorRGBA.White);
barrelMat.setColor("Specular", new ColorRGBA(0.3f, 0.1f, 0, 1));
barrelMat.setFloat("Shininess", 4f);
this.barrel.setMaterial(barrelMat);

this.rootNode.attachChild(this.barrel);

The result is this:

The failed barrel image

Is there something else I have to consider when setting the texture for my UV mapped model?


Source: (StackOverflow)

jMonkeyEngine enabling relative gravity via mass

I'm not sure if I'm wording this correctly, but I want to set up a space-like physics system in jme3. I have the BulletAppState setup and several RigidBodyControl enabled spheres.

    // Setting up BulletAppState
    physics = new BulletAppState();     
    getStateManager().attach(physics);
    physics.getPhysicsSpace().setGravity(Vector3f.ZERO);

    // In each sphere Geometry object I call:
    public void setPhysics(BulletAppState state, float mass) {
        rigidBodyControl = new RigidBodyControl(mass);
        addControl(rigidBodyControl);
        rigidBodyControl.setKinematic(true);
        state.getPhysicsSpace().add(this);
    }

I'd like to have these objects attract each other (like planets) based on their mass. Is this already implemented in jme's jBullet library?


Source: (StackOverflow)

jmonkey rotation and translation

I am having an issue in JME (JMonkey) with rotating then translating two boxes. I have searched the forums and found some similar issues with other languages but I do not understand the answers and that may be because I do not know the other languages. I have two boxes with .lookat( [the other box] ), a rotate, and then a local translation. In my mind the local translation should move the box in the direction it is facing, but it does not it seems to be moving along the world axes. One thing of note; I do not know anything about using matrix math in 3d, some of the answers I found used matrix math to solve the problem. I would like to understand this so that I can avoid this problem in the future. I have reduced my code as small as possible so it does not have any unnessicary parts.

package jme3test.helloworld;
import com.jme3.app.SimpleApplication;
import com.jme3.font.BitmapText;
import com.jme3.material.Material;
import com.jme3.math.Vector3f;
import com.jme3.scene.Geometry;
import com.jme3.scene.shape.Box;
import com.jme3.math.ColorRGBA;
import com.jme3.renderer.RenderManager;
import com.jme3.renderer.ViewPort;
import com.jme3.scene.Node;
import com.jme3.scene.Spatial;
import com.jme3.scene.control.AbstractControl;
import java.util.ResourceBundle.Control;


public class SSF2 extends SimpleApplication {
public Geometry blue = null;
public Geometry red = null;

public static void main(String[] args){
    final SSF2 app = new SSF2();
    app.start();
}

@Override
public void simpleInitApp() {
    // create a blue box at coordinates (1,-1,1)
    Box box1 = new Box( Vector3f.ZERO, 1f,2f,.5f);
    blue =  new Geometry("Box", box1);
    Material mat1 = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
    mat1.setColor("Color", ColorRGBA.Blue);
    blue.setMaterial(mat1);
    blue.move(-5,0,-3);

    // create a red box straight above the blue one at (1,3,1)
    Box box2 = new Box( Vector3f.ZERO, 1f,2f,.5f);
    red = new Geometry("Box", box2);
    Material mat2 = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
    mat2.setColor("Color", ColorRGBA.Red);
    red.setMaterial(mat2);
    red.move(5,0,-3);

    rootNode.attachChild(blue);
    rootNode.attachChild(red);

    blue.lookAt(red.getWorldTranslation(), new Vector3f(0,1,0) );
    red.lookAt(blue.getWorldTranslation(), new Vector3f(0,1,0) );
}

@Override
public void simpleUpdate(float tpf) {
    blue.setLocalTranslation(new Vector3f( (blue.getLocalTranslation().getX() + .02f), (blue.getLocalTranslation().getY())  , (blue.getLocalTranslation().getZ() )));
    red.setLocalTranslation(new Vector3f( (red.getLocalTranslation().getX() + .02f), (red.getLocalTranslation().getY())  , (red.getLocalTranslation().getZ() )));
}
}

Source: (StackOverflow)