0

My 3rd person floats in the air and the camera should zoom out: enter image description here

This is the program

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.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.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.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 {
    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;

    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();
        createTerrain();
        createWall();
        createCharacters();



        setupChaseCamera();
        setupAnimationController();
        setupFilter();
    }

    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 createTerrain() {
        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 createCharacters() {
        CapsuleCollisionShape capsule = new CapsuleCollisionShape(3f, 4f);
        character = new CharacterControl(capsule, 0.01f);
        model = (Node) assetManager.loadModel("Models/Ninja/Ninja.mesh.xml");
        model.setLocalScale(0.15f);
        //ninja.setViewDirection( new Vector3f( 1, 0, 1 ) );
         //model.rotate(0.0f, -3.0f, 0.0f);

        model.addControl(character);
        character.setPhysicsLocation(new Vector3f(-140f, 9.9f, -9f));
        character.setViewDirection(new Vector3f(1, 0, 0));
        rootNode.attachChild(model);
        getPhysicsSpace().add(character);

        //BlenderKey blenderKey = new BlenderKey(
            //  "objects/creatures/alien/alien.mesh.xml");

        //Node alien = (Node) assetManager.loadModel(blenderKey);
        //alien.setLocalTranslation(new Vector3f(-145, 21, -10));

        //rootNode.attachChild(alien);



        BlenderKey blenderKey2 = new BlenderKey(
                "objects/creatures/minotaur/minotaur.mesh.xml");

        Spatial man = (Spatial) assetManager.loadModel(blenderKey2);
        man.setLocalTranslation(new Vector3f(-140, 15, -10));

        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();
    }
}

I want the green person to stay on the ground but I can't seem to change the physicslocation to appropriate. Do you have any idea? I took this program and just switched the character from oto to ninja: http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/bullet/TestWalkingChar.java

Do you have any idea how I can make the camera zoom out so that the whole green person is displayed and change the location of the green person so that he is on the ground?

I've noticed that I can change the location of the main char with this

character.setPhysicsLocation(new Vector3f(-140f, 9.9f, -9f));

but when I put in lower y coordinates the main char drops through the ground and then floats way up in the sky like he ended up on the top of everything when he went through the ground. I could run the example with Oto perfectly, it's changing the main char to ninja that doesn't work for me.

Update

When using setlocaltranslationinstead of setphysicallocationmy main char gets located in the air:

enter image description here

Update 2

After scaling the main char: model.scale(0.25f); as suggested in the answer, the rendering is much better: enter image description here

enter image description here

Update 2

After some more manipulation, it looks more like the way I want: enter image description here

private void createCharacters() {
    CapsuleCollisionShape capsule = new CapsuleCollisionShape(3f, 4f);
    character = new CharacterControl(capsule, 0.01f);
    model = (Node) assetManager.loadModel("Models/Ninja/Ninja.mesh.xml");
    model.setLocalScale(0.15f);
    // ninja.setViewDirection( new Vector3f( 1, 0, 1 ) );
    // model.rotate(0.0f, -3.0f, 0.0f);
    float scale = 0.25f;
    model.scale(scale, scale, scale);
    model.addControl(character);
    character.setPhysicsLocation(new Vector3f(-141f, 10.5f, -9f));
    model.setShadowMode(ShadowMode.CastAndReceive);
    // model.setLocalTranslation(0, 50, 0);

    character.setViewDirection(new Vector3f(1, 0, 0));
    rootNode.attachChild(model);
    getPhysicsSpace().add(character);

    // BlenderKey blenderKey = new BlenderKey(
    // "objects/creatures/alien/alien.mesh.xml");

    // Node alien = (Node) assetManager.loadModel(blenderKey);
    // alien.setLocalTranslation(new Vector3f(-145, 21, -10));

    // rootNode.attachChild(alien);

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

    Spatial man = (Spatial) assetManager.loadModel(blenderKey2);
    man.setLocalTranslation(new Vector3f(-140, 10, -10));

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

}
Niklas Rosencrantz
  • 25,640
  • 75
  • 229
  • 424
  • 4
    seriously consider shrinking this down to the smallest possible subset. also - not a good it for SA imo... 'i grabbed some code - and it doesn't work...' isnt really appropriate. – Randy Aug 03 '12 at 13:35
  • @Randy I'm switching the main character of a scene. That is not just grabbing code that is real programming question about Ogre modelling and 3D views. The downvotes here have no reason but lack of interest in solving the problem. I've been working on this for several days and carefully testing different coordinates and even had to rotate the new char. So I'm doing the right thing - learning by doing and learning by changing code. Don't you agree when you examine my question more closely that I've actually programmed this switch of characters and even added a second char which wasn't there. – Niklas Rosencrantz Aug 03 '12 at 14:00
  • This is definetly not an SSCE. Of course *nobody* will install all the dependencies and try out a convoluted mess of code. – Durandal Aug 03 '12 at 14:07
  • 1
    I personally think it's an interesting question. But you might get better responses (or answer the question yourself) if you tried to pull out any extraneous code not related to the problem (for example, using just one texture for the ground, one character, pulling out all the bullet and wall and collision stuff). – Nick Rippe Aug 03 '12 at 14:17
  • You're right, I can repackage the question with just the 3rd person walking with a chasingcamera as a minimal component. I think it's about learning how to handle the chasingcamera and the physicallocation and whether I must adjust the model in blender and how to align different models when having more than one character in the scene. The smallest possible subset will be without the Swing GUI and just the scene and only one person, the green person. And solving just one of the 2 problems I'm asking about here (positioning the main character and landing the main character on the ground). – Niklas Rosencrantz Aug 03 '12 at 14:28
  • 1
    I have no particular interest in installing the dependencies etc., but after reading the code, the question, and the comments: +1, becuase it's a perfectly legitimate subject. – pafau k. Aug 03 '12 at 14:48
  • Question is updated with what happens if I use `model.setLocalTranslation` instead of `character.setPhysicalLocation` and I will look more into the docs to know which to use. I'm trying to solve the one problem first how to locate the main char so that he is on the ground and that would mean adjusting the y coordinate but after floating close above the ground, he just falls through the ground when I lower the y coordinate and falls through the scene which starts again from the top so the main char is now floating in the air on the top of the scene. I'll try to compact this to a smaller example – Niklas Rosencrantz Aug 03 '12 at 15:55
  • @Durandal I don't expect you to try the code but you might notice in the code what I'm trying to do particularly in the method `createCharacters` which is not conulted since it does what it's named to do which is high cohesion. If you want to structure the code more like an MVC I already asked that question to 0 answers: http://stackoverflow.com/questions/11572734/how-to-make-this-3d-scene-an-mvc i.e. how to make more classes so that the structure becomes more like an MVC project (model, view, controller). – Niklas Rosencrantz Aug 03 '12 at 15:59

1 Answers1

2

I suspect there are 3 things that could make your character appear to be hovering:

  1. Your character is hovering. In this case you'd want to use character.setLocalTranslation(0, -20, 0) to adjust where your character is located (may have to adjust the -20 to some other negative number)
  2. Your character's scale is too big compared to the ground's scale (it sounds like this is a problem you want to fix anyways). To fix this, you'd want to use character.scale(.25) (where the .25 can be adjusted to whatever number works for you
  3. You don't have shadows on the ground. This really links your character to the ground and gives the feeling that they're connected in some way. For this, you'll probably want to use object.setShadowMode(RenderQueue.ShadowMode.Receive) for all your terrain objects, and character.setShadowMode(RenderQueue.ShadowMode.CastAndReceive) on your character object.

The JMonkeyEngine javadoc's are pretty good - If you haven't already I would suggest looking there to help figure out what you're capable of doing with your engine. http://jmonkeyengine.org/javadoc/index.html

Nick Rippe
  • 6,465
  • 14
  • 30
  • Thanks for a very good answer which I accept but since so little time has gone I will wait for some more hours or a day until I click accept this answer so that the question will be seen more. I highly appreciate the suggestion of shadows and the pointer to the javadoc. I now will look into the difference between `setLocalTranslation` and `setPhysicalTranslation` and maybe I can just zoom out the camera to get the look more like it should. – Niklas Rosencrantz Aug 03 '12 at 14:31
  • My Java compiler accepts this: `model.setShadowMode(ShadowMode.CastAndReceive);` – Niklas Rosencrantz Aug 03 '12 at 16:04