Edit: Resolved. It appears to be a problem in the cubes plugin with chunks that are not the very first chunk (corner at (0, 0, 0))
Edit 2: Even more resolved: the developer of the plugin showed me a better way to handle the bug in the plugin
Edit 3: I now have a question about multithreading this
Edit 4: I’m making a new topic for that question
Well, I have absolutely no idea why, but when I use the cubes plugin to make a minecraft-like engine (Which will be a component of my first game), set a block, and jump on top, I almost always pass through the top. This tends to happen with blocks that are two above the starting surface of the flat world.
here is my code:
package mygame;
import com.jme3.app.SimpleApplication;
import com.cubes.*;
import com.cubes.test.*;
import com.cubes.test.blocks.*;
import com.jme3.bullet.control.*;
import com.jme3.bullet.*;
import com.jme3.bullet.collision.*;
import com.jme3.bullet.collision.shapes.*;
import com.jme3.bullet.util.*;
import com.jme3.collision.CollisionResults;
import com.jme3.font.BitmapText;
import com.jme3.input.KeyInput;
import com.jme3.input.MouseInput;
import com.jme3.input.controls.*;
import com.jme3.light.AmbientLight;
import com.jme3.light.DirectionalLight;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Ray;
import com.jme3.math.Vector2f;
import com.jme3.math.Vector3f;
import com.jme3.renderer.queue.RenderQueue;
import com.jme3.renderer.queue.RenderQueue.ShadowMode;
import com.jme3.scene.*;
import com.jme3.scene.mesh.*;
import com.jme3.scene.shape.*;
public class Main extends SimpleApplication implements ActionListener
{
CubesSettings cubesSettings;
Node blocks;
BlockTerrainControl blockTerrain;
BulletAppState bulletAppState;
CharacterControl player;
CapsuleCollisionShape capsuleShape;
Vector3f walkDirection = new Vector3f();
boolean left = false, right = false, up = false, down = false;
Vector3f camDir = new Vector3f();
Vector3f camLeft = new Vector3f();
public static void main(String[] args)
{
Main app = new Main();
app.start();
}
@Override
public void simpleInitApp()
{
bulletAppState = new BulletAppState();
bulletAppState.setThreadingType(BulletAppState.ThreadingType.SEQUENTIAL);
stateManager.attach(bulletAppState);
bulletAppState.getPhysicsSpace().setWorldMin(new Vector3f(0, 0, 0));
bulletAppState.getPhysicsSpace().setWorldMax(new Vector3f(400, 400, 400));
bulletAppState.getPhysicsSpace().setMaxSubSteps(4);
bulletAppState.getPhysicsSpace().enableDebug(assetManager);
setUpKeys();
//setUpLight();
setUpBlocks();
initCrossHairs();
capsuleShape = new CapsuleCollisionShape(1.5f, 5f, 1);
player = new CharacterControl(capsuleShape, 0.05f);
player.setJumpSpeed(17);
player.setFallSpeed(32);
player.setGravity(32);
player.setPhysicsLocation(new Vector3f(200, 50, 200));
bulletAppState.getPhysicsSpace().add(player);
}
private void setUpBlocks()
{
blocks = new Node();
CubesTestAssets.registerBlocks();
CubesTestAssets.initializeEnvironment(this);
cubesSettings = new CubesSettings(this);
cubesSettings.setBlockMaterial(CubesTestAssets.getSettings(this).getBlockMaterial());
cubesSettings.setBlockSize(4);
blockTerrain = new BlockTerrainControl(cubesSettings, new Vector3Int(7, 1, 7));
for(int x = 0; x < 100; x++)
{
for(int z = 0; z < 100; z++)
{
blockTerrain.setBlock(x, 0, z, Block_Stone.class);
for(int y = 1; y < 30; y++)
{
if (y <= 5)
{
blockTerrain.setBlock(x, y, z, Block_Grass.class);
}
else
{
blockTerrain.setBlock(x, y, 0, Block_Stone.class);
blockTerrain.setBlock(x, y, 100, Block_Stone.class);
blockTerrain.setBlock(1, y, z, Block_Stone.class);
blockTerrain.setBlock(99, y, z, Block_Stone.class);
}
}
}
}
blockTerrain.addChunkListener(new BlockChunkListener()
{
@Override
public void onSpatialUpdated(BlockChunkControl blockChunk)
{
Geometry optimizedGeometry = blockChunk.getOptimizedGeometry_Opaque();
RigidBodyControl rigidBodyControl = optimizedGeometry.getControl(RigidBodyControl.class);
if(rigidBodyControl == null)
{
rigidBodyControl = new RigidBodyControl(0);
optimizedGeometry.addControl(rigidBodyControl);
bulletAppState.getPhysicsSpace().add(rigidBodyControl);
}
rigidBodyControl.setCollisionShape(new MeshCollisionShape(optimizedGeometry.getMesh()));
}
});
blocks.addControl(blockTerrain);
blocks.setShadowMode(ShadowMode.CastAndReceive);
rootNode.attachChild(blocks);
}
//private void setUpLight()
//{
// AmbientLight al = new AmbientLight();
// al.setColor(ColorRGBA.White.mult(1.3f));
// rootNode.addLight(al);
//
// DirectionalLight dl = new DirectionalLight();
// dl.setColor(ColorRGBA.White);
// dl.setDirection(new Vector3f(2.8f, -2.8f, -2.8f).normalizeLocal());
// rootNode.addLight(dl);
//}
private CollisionResults getRayCastingResults(Node node)
{
Vector3f origin = cam.getWorldCoordinates(new Vector2f((settings.getWidth() / 2), (settings.getHeight() / 2)), 0.0f);
Vector3f direction = cam.getWorldCoordinates(new Vector2f((settings.getWidth() / 2), (settings.getHeight() / 2)), 0.3f);
direction.subtractLocal(origin).normalizeLocal();
Ray ray = new Ray(origin, direction);
CollisionResults results = new CollisionResults();
node.collideWith(ray, results);
return results;
}
private Vector3Int getCurrentPointedBlockLocation(boolean getNeighborLocation)
{
CollisionResults results = getRayCastingResults(blocks);
if (results.size() > 0)
{
Vector3f collisionContactPoint = results.getClosestCollision().getContactPoint();
return BlockNavigator.getPointedBlockLocation(blockTerrain, collisionContactPoint, getNeighborLocation);
}
return null;
}
private void setUpKeys()
{
inputManager.addMapping("Left", new KeyTrigger(KeyInput.KEY_A));
inputManager.addMapping("Right", new KeyTrigger(KeyInput.KEY_D));
inputManager.addMapping("Up", new KeyTrigger(KeyInput.KEY_W));
inputManager.addMapping("Down", new KeyTrigger(KeyInput.KEY_S));
inputManager.addMapping("Jump", new KeyTrigger(KeyInput.KEY_SPACE));
inputManager.addMapping("Add", new MouseButtonTrigger(MouseInput.BUTTON_RIGHT));
inputManager.addMapping("Destroy", new MouseButtonTrigger(MouseInput.BUTTON_LEFT));
inputManager.addListener(this, "Left");
inputManager.addListener(this, "Right");
inputManager.addListener(this, "Up");
inputManager.addListener(this, "Down");
inputManager.addListener(this, "Jump");
inputManager.addListener(this, "Add");
inputManager.addListener(this, "Destroy");
}
public void onAction(String binding, boolean value, float tpf)
{
if (binding.equals("Left"))
{
if (value)
{
left = true;
}
else
{
left = false;
}
}
else if (binding.equals("Right"))
{
if (value)
{
right = true;
}
else
{
right = false;
}
}
else if (binding.equals("Up"))
{
if (value)
{
up = true;
}
else
{
up = false;
}
}
else if (binding.equals("Down"))
{
if (value)
{
down = true;
}
else
{
down = false;
}
}
else if ((binding.equals("Jump")) && !value)
{
player.jump();
}
if (((binding.equals("Add")) && !value))
{
Vector3Int blockLocation = getCurrentPointedBlockLocation(true);
if (blockLocation != null)
{
if(!blockLocation.equals(new Vector3Int((int)(player.getPhysicsLocation().getX() / 4), blockLocation.getY(), (int)(player.getPhysicsLocation().getZ() / 4))))
{
blockTerrain.setBlock(blockLocation, Block_Grass.class);
System.out.println("physicsLocation: " + player.getPhysicsLocation().getX() + ", " + player.getPhysicsLocation().getY() + ", " + player.getPhysicsLocation().getZ());
System.out.println("blockLocation: " + blockLocation.getX() + ", " + blockLocation.getY() + ", " + blockLocation.getZ());
}
}
}
else if ((binding.equals("Destroy")) && !value)
{
Vector3Int blockLocation = getCurrentPointedBlockLocation(false);
if ((blockLocation != null) && blockTerrain.getBlock(blockLocation).equals(new Block_Grass().getType()))
{
blockTerrain.removeBlock(blockLocation);
}
}
}
protected void initCrossHairs()
{
guiNode.detachAllChildren();
guiFont = assetManager.loadFont("Interface/Fonts/Default.fnt");
BitmapText ch = new BitmapText(guiFont, false);
ch.setSize(guiFont.getCharSet().getRenderedSize() * 2);
ch.setText("+");
ch.setLocalTranslation(settings.getWidth() / 2 - guiFont.getCharSet().getRenderedSize() / 3 * 2, settings.getHeight() / 2 + ch.getLineHeight() / 2, 0);
guiNode.attachChild(ch);
}
@Override
public void simpleUpdate(float tpf)
{
camDir.set(new Vector3f(cam.getDirection().multLocal(0.2f).getX(), 0, cam.getDirection().multLocal(0.2f).getZ()));
camLeft.set(cam.getLeft()).multLocal(0.15f);
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 (!right && !left && !up && !down)
{
player.setWalkDirection(Vector3f.ZERO);
}
player.setWalkDirection(walkDirection);
cam.setLocation(player.getPhysicsLocation());
}
}
I tend to not comment at all in my code, it’s true. I have absolutely no idea even where to start looking for the problem. Any help would be appreciated, thanks in advance.