I use this code to generate the grid
package scenario.Grid;
import com.jme3.material.Material;
import com.jme3.material.RenderState;
import com.jme3.math.ColorRGBA;
import com.jme3.math.FastMath;
import com.jme3.math.Quaternion;
import com.jme3.math.Vector3f;
import com.jme3.scene.Geometry;
import com.jme3.scene.Mesh;
import com.jme3.scene.VertexBuffer;
import com.jme3.scene.shape.Quad;
import com.jme3.util.BufferUtils;
import static scenario.scenarioState.mapGrid3D;
/**
*使用Mesh生成网格
* @author IcyBoxs
*/
public class meshGrid {
public Geometry GameMap(float XLength,float YHighly,float ZWidth,float cellsize) {
int Length = (int)XLength/(int)cellsize;
int Highly = (int)YHighly/(int)cellsize;
int Width = (int)ZWidth/(int)cellsize;
float spacing = cellsize;
// float XLength=XLength;//长度X
// float XHighly;//高度Y
// float ZWidth;//宽度Z
//
// float cellsize;//单元格长度
// Define vertices for the grid
//定义网格顶点
float[] vertices = new float[Length * Width * 3];
for (int x = 0; x < Length; x++) {
for (int z = 0; z < Width; z++) {
vertices[(x * Width + z) * 3] = x * spacing;
vertices[(x * Width + z) * 3 + 1] = YHighly;
vertices[(x * Width + z) * 3 + 2] = z * spacing;
}
}
// Define indices to create triangles
int[] indices = new int[(Length - 1) * (Width - 1) * 6];
int idx = 0;
for (int x = 0; x < Length - 1; x++) {
for (int z = 0; z < Width - 1; z++) {
int topLeft = x * Width + z;
int topRight = topLeft + 1;
int bottomLeft = (x + 1) * Width + z;
int bottomRight = bottomLeft + 1;
// First triangle 第一个三角形
indices[idx++] = topLeft;
indices[idx++] = bottomLeft;
indices[idx++] = topRight;
// Second triangle 第二个三角形
indices[idx++] = topRight;
indices[idx++] = bottomLeft;
indices[idx++] = bottomRight;
}
}
// Create a Mesh
Mesh mesh = new Mesh();
mesh.setBuffer(VertexBuffer.Type.Position, 3, BufferUtils.createFloatBuffer(vertices));
mesh.setBuffer(VertexBuffer.Type.Index, 3, BufferUtils.createIntBuffer(indices));
mesh.updateBound();
// Create a Geometry to display the mesh
Geometry gridGeometry = new Geometry("Grid", mesh);
return gridGeometry;
}
}
At first my intention was just to put this mesh into the physical world in order to simulate parts of the map (like the floor we step on)
CollisionShape sceneShape = CollisionShapeFactory.createMeshShape(gridGeometry);
RigidBodyControl landscape = new RigidBodyControl(sceneShape, 0);
map.addControl(landscape);
Like this I converted it into a rigid body.
And I have a lot of tanks. I put tanks in collisions.
BoxCollisionShape capsuleShape = new BoxCollisionShape(radius, height, radius);
player = new CharacterControl(capsuleShape,stepHeight);
player.setPhysicsLocation(new Vector3f(0, 10f, 0));
MinieBulletAppState.bulletAppState.getPhysicsSpace().add(player);
At this point the question arises!
The graphics card becomes very laggy when the tank’s collision body touches a rigid body.
I don’t really understand what’s happening to cause the graphics card to lag so much, but I did a test and it doesn’t happen if I use an oversized mesh made from blender as a rigid body.
If I use the Geometry generated by the mesh code above as a rigid body I get severe lag on the graphics card.
If anyone knows what’s going on please let me know thank you very much!
//If you have any doubts about my questions, please point them out.
This is a test code just copy this code into your ide and run it!
package com.mygame;
import com.jme3.app.DetailedProfilerState;
import com.jme3.app.SimpleApplication;
import com.jme3.bullet.BulletAppState;
import com.jme3.bullet.collision.shapes.BoxCollisionShape;
import com.jme3.bullet.collision.shapes.CollisionShape;
import com.jme3.bullet.control.CharacterControl;
import com.jme3.bullet.control.RigidBodyControl;
import com.jme3.bullet.util.CollisionShapeFactory;
import com.jme3.light.DirectionalLight;
import com.jme3.material.Material;
import com.jme3.material.RenderState;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Vector3f;
import com.jme3.scene.Geometry;
import com.jme3.scene.Mesh;
import com.jme3.scene.Node;
import com.jme3.scene.VertexBuffer;
import com.jme3.scene.shape.Box;
import com.jme3.system.AppSettings;
import com.jme3.util.BufferUtils;
/**
*
* @author icyboxs
*/
public class SimpleTestGridApp extends SimpleApplication {
public static BulletAppState bulletAppState;
private CharacterControl player;
private Node block = new Node("block");
public static void main(String[] args) {
SimpleTestGridApp app = new SimpleTestGridApp();
AppSettings setting = new AppSettings(true);
setting.setWindowSize(1920, 1080);
app.setSettings(setting);
app.start();
}
@Override
public void simpleInitApp() {
DetailedProfilerState detailedProfilerState = new DetailedProfilerState();
getStateManager().attach(detailedProfilerState);
bulletAppState = new BulletAppState();
bulletAppState.setThreadingType(BulletAppState.ThreadingType.PARALLEL);
getStateManager().attach(bulletAppState);//添加物理世界
bulletAppState.setDebugEnabled(true);
Geometry gridGeometry = GameMap(1280, 0, 1280, 5);
Material material = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
material.setColor("Color", ColorRGBA.Red);
material.getAdditionalRenderState().setWireframe(true);
material.getAdditionalRenderState().setFaceCullMode(RenderState.FaceCullMode.Off);
gridGeometry.setMaterial(material);
for(int i=1;i<=20;i++){
for(int j=1;j<=20;j++){
addT100(new Vector3f(30*j,300,30*i));
}
}
CollisionShape sceneShape = CollisionShapeFactory.createMeshShape(gridGeometry.clone());
RigidBodyControl landscape = new RigidBodyControl(sceneShape, 0);
gridGeometry.addControl(landscape);
bulletAppState.getPhysicsSpace().add(landscape);
bulletAppState.startPhysics();
rootNode.attachChild(gridGeometry);
// #4 创建一束定向光,并让它斜向下照射,好使我们能够看清那个方块。
DirectionalLight sun = new DirectionalLight();
sun.setDirection(new Vector3f(-1, -2, -3));
// #5 将方块和光源都添加到场景图中
rootNode.attachChild(block);
rootNode.addLight(sun);
}
public void addT100( Vector3f v3f){
// #1 创建一个方块形状的网格
Mesh box = new Box(2f, 2f, 2f);
// #2 加载一个感光材质
Material mat = new Material(assetManager, "Common/MatDefs/Light/Lighting.j3md");
// #3 创建一个几何体,应用刚才和网格和材质。
Geometry geom = new Geometry("Box");
geom.setMesh(box);
geom.setMaterial(mat);
geom.setLocalTranslation(v3f);
float radius = 5.5f;// 胶囊半径0.3米
float height = 5.5f;// 胶囊身高1.8米
float stepHeight = 0.5f;// 角色步高0.5米
BoxCollisionShape capsuleShape = new BoxCollisionShape(radius, height, radius);
player = new CharacterControl(capsuleShape,stepHeight);
player.setJumpSpeed(10f);// 起跳速度
player.setFallSpeed(20f);// 坠落速度
player.setGravity(9.81f * 3);// 重力加速度
player.setPhysicsLocation(v3f);
bulletAppState.getPhysicsSpace().add(player);
geom.addControl(player);
block.attachChild(geom);
}
public Geometry GameMap(float XLength,float YHighly,float ZWidth,float cellsize) {
int Length = (int)XLength/(int)cellsize;
int Highly = (int)YHighly/(int)cellsize;
int Width = (int)ZWidth/(int)cellsize;
float spacing = cellsize;
// float XLength=XLength;//长度X
// float XHighly;//高度Y
// float ZWidth;//宽度Z
//
// float cellsize;//单元格长度
// Define vertices for the grid
//定义网格顶点
float[] vertices = new float[Length * Width * 3];
for (int x = 0; x < Length; x++) {
for (int z = 0; z < Width; z++) {
vertices[(x * Width + z) * 3] = x * spacing;
vertices[(x * Width + z) * 3 + 1] = YHighly;
vertices[(x * Width + z) * 3 + 2] = z * spacing;
}
}
// Define indices to create triangles
int[] indices = new int[(Length - 1) * (Width - 1) * 6];
int idx = 0;
for (int x = 0; x < Length - 1; x++) {
for (int z = 0; z < Width - 1; z++) {
int topLeft = x * Width + z;
int topRight = topLeft + 1;
int bottomLeft = (x + 1) * Width + z;
int bottomRight = bottomLeft + 1;
// First triangle 第一个三角形
indices[idx++] = topLeft;
indices[idx++] = bottomLeft;
indices[idx++] = topRight;
// Second triangle 第二个三角形
indices[idx++] = topRight;
indices[idx++] = bottomLeft;
indices[idx++] = bottomRight;
}
}
// Create a Mesh
Mesh mesh = new Mesh();
mesh.setBuffer(VertexBuffer.Type.Position, 3, BufferUtils.createFloatBuffer(vertices));
mesh.setBuffer(VertexBuffer.Type.Index, 3, BufferUtils.createIntBuffer(indices));
mesh.updateBound();
// Create a Geometry to display the mesh
Geometry gridGeometry = new Geometry("Grid", mesh);
return gridGeometry;
}
}