So Im Making a PopUpBook and there is something weird with the hinge. The frontPage is attached to the backPage by a HingeJoint. I would like the frontpage to move and the backpage to be stationary when I enable to motors. So I set the mass of the front page to be 1 and the mass of the back page to 0. But when I do that the two geometries wont render. The two pages appeared for less than a second and disappeared, like a flash. I tried again with different mass and it successfully render. Success mass combination for front and back page are: front page 0 back page 0 and front page 1 back page 1.
Here is my:
package mygame;
import com.jme3.app.SimpleApplication;
import com.jme3.bullet.BulletAppState;
import static com.jme3.bullet.PhysicsSpace.getPhysicsSpace;
import com.jme3.bullet.collision.shapes.GImpactCollisionShape;
import com.jme3.bullet.control.RigidBodyControl;
import com.jme3.bullet.joints.HingeJoint;
import com.jme3.input.ChaseCamera;
import com.jme3.material.Material;
import com.jme3.material.RenderState;
import com.jme3.math.ColorRGBA;
import com.jme3.math.FastMath;
import com.jme3.math.Vector2f;
import com.jme3.math.Vector3f;
import com.jme3.renderer.RenderManager;
import com.jme3.scene.Geometry;
import com.jme3.scene.Mesh;
import com.jme3.scene.Node;
import com.jme3.scene.VertexBuffer;
import com.jme3.util.BufferUtils;
import java.util.ArrayList;
/**
* This is the Main Class of your Game. You should only do initialization here.
Move your Logic into AppStates or Controls
@author normenhansen
*/
public class PopUpBook extends SimpleApplication {
private ChaseCamera chaseCam;
private BulletAppState bulletAppState;
public Node planes;
public Material paper;
public Material markPaper;
public HingeJoint joint;
public ArrayList<Geometry> selected;
public static void main(String[] args) {
PopUpBook app = new PopUpBook();
app.start();
}
@Override
public void simpleInitApp() {
viewPort.setBackgroundColor(ColorRGBA.White);
bulletAppState = new BulletAppState();
stateManager.attach(bulletAppState);
bulletAppState.setDebugEnabled(false);
planes = new Node("plane");
rootNode.attachChild(planes);
selected = new ArrayList<>();
initMaterial();
initBook();
}
@Override
public void simpleUpdate(float tpf) {
//TODO: add update code
}
@Override
public void simpleRender(RenderManager rm) {
//TODO: add render code
}
private void initMaterial(){
paper = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
paper.setTexture("ColorMap",
assetManager.loadTexture("Textures/paper.jpg"));
paper.getAdditionalRenderState().setFaceCullMode(RenderState.FaceCullMode.Off);
markPaper = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
markPaper.setTexture("ColorMap",
assetManager.loadTexture("Textures/selected.jpg"));
markPaper.getAdditionalRenderState().setFaceCullMode(RenderState.FaceCullMode.Off);
}
private void initBook(){
Vector3f [] vertices = new Vector3f[4];
vertices[0] = new Vector3f(-4,0,0);
vertices[1] = new Vector3f(-4,0,5);
vertices[2] = new Vector3f(4,0,5);
vertices[3] = new Vector3f(4,0,0);
Mesh f = makeMesh(vertices);
Geometry front = new Geometry("Box", f);
Vector3f [] vertices1 = new Vector3f[4];
vertices1[3] = new Vector3f(-4,0,0);
vertices1[2] = new Vector3f(-4,0,-5);
vertices1[1] = new Vector3f(4,0,-5);
vertices1[0] = new Vector3f(4,0,0);
Mesh b = makeMesh(vertices1);
Geometry back = new Geometry("Box", b);
front.setMaterial(paper);
back.setMaterial(paper);
Node frontPage = new Node("PhysicsNode");
//problem right here!!!!!!!!!!!!!
frontPage.addControl(new RigidBodyControl(new GImpactCollisionShape(front.getMesh()),1f));
frontPage.getControl(RigidBodyControl.class).setPhysicsLocation(new Vector3f(0f,0f,0f));
Node backPage = new Node("PhysicsNode");
//problem right here!!!!!!!!!!!!!
backPage.addControl(new RigidBodyControl(new GImpactCollisionShape(back.getMesh()),0f));
backPage.getControl(RigidBodyControl.class).setPhysicsLocation(new Vector3f(0f,0f,0f));
frontPage.attachChild(front);
backPage.attachChild(back);
rootNode.attachChild(frontPage);
rootNode.attachChild(backPage);
getPhysicsSpace().setGravity(Vector3f.ZERO);
getPhysicsSpace().add(frontPage);
getPhysicsSpace().add(backPage);
System.out.println(this.planes.getChildren());
joint = new HingeJoint(frontPage.getControl(RigidBodyControl.class), backPage.getControl(RigidBodyControl.class), Vector3f.ZERO, new Vector3f(0f,0f,0f),Vector3f.UNIT_X , Vector3f.UNIT_X);
getPhysicsSpace().add(joint);
joint.setLimit(-1*FastMath.PI, 0);
flyCam.setEnabled(false);
chaseCam = new ChaseCamera(cam, frontPage, inputManager);
chaseCam.setInvertVerticalAxis(true);
chaseCam.setMaxVerticalRotation(FastMath.PI/2);
}
//basically just a method to create mesh from vertices
private Mesh makeMesh(Vector3f[] vertices){
Mesh mesh = new Mesh();
Vector3f[] verList = vertices.clone();
float averX = 0f;
float averY = 0f;
float averZ = 0f;
for(Vector3f vec : vertices){
averX += vec.x;
averY += vec.y;
averZ += vec.z;
}
averX = averX/vertices.length;
averY = averY/vertices.length;
averZ = averZ/vertices.length;
int count = 0;
Vector3f centerPoint = new Vector3f(averX,averY,averZ);
int current=0;
int[] triangles = new int[3*(vertices.length-2)];
while(count<triangles.length){
//System.out.println();
//System.out.println("current: " + current + " ("+ Arrays.toString(verList) +")");
int prevInt = (current-1+vertices.length)%vertices.length;
while(verList[prevInt] ==null){
prevInt = (prevInt-1+vertices.length)%vertices.length;
}
int nextInt = (current+1)%vertices.length;
while(verList[nextInt] ==null){
nextInt = (nextInt+1)%vertices.length;
}
boolean prevLarge = verList[current].distance(centerPoint) < verList[prevInt].distance(centerPoint);
boolean nextLarge = verList[current].distance(centerPoint) < verList[nextInt].distance(centerPoint);
if(prevLarge && nextLarge ){
}else{
triangles[count+1]=current;
boolean skip= true;
for(int x = 2; x < verList.length-1 && skip;x++){
if(verList[(current+x)%verList.length] != null && (current+x!=prevInt && current+x != nextInt)){
float prevBigger = verList[current].distance(verList[prevInt]) - verList[current].distance(verList[(current+x)%verList.length]);
float nextBigger = verList[current].distance(verList[nextInt]) - verList[current].distance(verList[(current+x)%verList.length]);
if(prevBigger > 0 || nextBigger > 0){
skip = false;
}
}
}
if(skip){
triangles[count+2]=nextInt;
triangles[count]=prevInt;
verList[current]= null;
count += 3;}
}
current=(current+1)%vertices.length;
while(verList[current] ==null && count < triangles.length){
current = (current+1)%vertices.length;
}
}
Vector2f[] texCoord = new Vector2f[4];
texCoord[0] = new Vector2f(0,0);
texCoord[1] = new Vector2f(1,0);
texCoord[2] = new Vector2f(0,1);
texCoord[3] = new Vector2f(1,1);
mesh.setBuffer(VertexBuffer.Type.Position, 3, BufferUtils.createFloatBuffer(vertices));
mesh.setBuffer(VertexBuffer.Type.TexCoord, 2, BufferUtils.createFloatBuffer(texCoord));
mesh.setBuffer(VertexBuffer.Type.Index, 3, BufferUtils.createIntBuffer(triangles));
mesh.updateBound();
return mesh;
}
}
The problem should be in initBook(). Thanks you very much for you help