use of com.jme3.math.Plane in project jmonkeyengine by jMonkeyEngine.
the class BIHTree method createNode.
// private BIHNode createNode2(int l, int r, BoundingBox nodeBbox, int depth){
// if ((r - l) < maxTrisPerNode || depth > 100)
// return createLeaf(l, r);
//
// BoundingBox currentBox = createBox(l, r);
// int axis = depth % 3;
// float split = currentBox.getCenter().get(axis);
//
// TriangleAxisComparator comparator = comparators[axis];
// Arrays.sort(tris, l, r, comparator);
// int splitIndex = -1;
//
// float leftPlane, rightPlane = Float.POSITIVE_INFINITY;
// leftPlane = tris[l].getExtreme(axis, false);
// for (int i = l; i <= r; i++){
// BIHTriangle tri = tris[i];
// if (splitIndex == -1){
// float v = tri.getCenter().get(axis);
// if (v > split){
// if (i == 0){
// // no left plane
// splitIndex = -2;
// }else{
// splitIndex = i;
// // first triangle assigned to right
// rightPlane = tri.getExtreme(axis, true);
// }
// }else{
// // triangle assigned to left
// float ex = tri.getExtreme(axis, false);
// if (ex > leftPlane)
// leftPlane = ex;
// }
// }else{
// float ex = tri.getExtreme(axis, true);
// if (ex < rightPlane)
// rightPlane = ex;
// }
// }
//
// if (splitIndex < 0){
// splitIndex = (r - l) / 2;
//
// leftPlane = Float.NEGATIVE_INFINITY;
// rightPlane = Float.POSITIVE_INFINITY;
//
// for (int i = l; i < splitIndex; i++){
// float ex = tris[i].getExtreme(axis, false);
// if (ex > leftPlane){
// leftPlane = ex;
// }
// }
// for (int i = splitIndex; i <= r; i++){
// float ex = tris[i].getExtreme(axis, true);
// if (ex < rightPlane){
// rightPlane = ex;
// }
// }
// }
//
// BIHNode node = new BIHNode(axis);
// node.leftPlane = leftPlane;
// node.rightPlane = rightPlane;
//
// node.leftIndex = l;
// node.rightIndex = r;
//
// BoundingBox leftBbox = new BoundingBox(currentBox);
// setMinMax(leftBbox, false, axis, split);
// node.left = createNode2(l, splitIndex-1, leftBbox, depth+1);
//
// BoundingBox rightBbox = new BoundingBox(currentBox);
// setMinMax(rightBbox, true, axis, split);
// node.right = createNode2(splitIndex, r, rightBbox, depth+1);
//
// return node;
// }
private BIHNode createNode(int l, int r, BoundingBox nodeBbox, int depth) {
if ((r - l) < maxTrisPerNode || depth > MAX_TREE_DEPTH) {
return new BIHNode(l, r);
}
BoundingBox currentBox = createBox(l, r);
Vector3f exteriorExt = nodeBbox.getExtent(null);
Vector3f interiorExt = currentBox.getExtent(null);
exteriorExt.subtractLocal(interiorExt);
int axis = 0;
if (exteriorExt.x > exteriorExt.y) {
if (exteriorExt.x > exteriorExt.z) {
axis = 0;
} else {
axis = 2;
}
} else {
if (exteriorExt.y > exteriorExt.z) {
axis = 1;
} else {
axis = 2;
}
}
if (exteriorExt.equals(Vector3f.ZERO)) {
axis = 0;
}
// Arrays.sort(tris, l, r, comparators[axis]);
float split = currentBox.getCenter().get(axis);
int pivot = sortTriangles(l, r, split, axis);
if (pivot == l || pivot == r) {
pivot = (r + l) / 2;
}
//If one of the partitions is empty, continue with recursion: same level but different bbox
if (pivot < l) {
//Only right
BoundingBox rbbox = new BoundingBox(currentBox);
setMinMax(rbbox, true, axis, split);
return createNode(l, r, rbbox, depth + 1);
} else if (pivot > r) {
//Only left
BoundingBox lbbox = new BoundingBox(currentBox);
setMinMax(lbbox, false, axis, split);
return createNode(l, r, lbbox, depth + 1);
} else {
//Build the node
BIHNode node = new BIHNode(axis);
//Left child
BoundingBox lbbox = new BoundingBox(currentBox);
setMinMax(lbbox, false, axis, split);
//The left node right border is the plane most right
node.setLeftPlane(getMinMax(createBox(l, max(l, pivot - 1)), false, axis));
//Recursive call
node.setLeftChild(createNode(l, max(l, pivot - 1), lbbox, depth + 1));
//Right Child
BoundingBox rbbox = new BoundingBox(currentBox);
setMinMax(rbbox, true, axis, split);
//The right node left border is the plane most left
node.setRightPlane(getMinMax(createBox(pivot, r), true, axis));
//Recursive call
node.setRightChild(createNode(pivot, r, rbbox, depth + 1));
return node;
}
}
use of com.jme3.math.Plane in project jmonkeyengine by jMonkeyEngine.
the class BillboardControl method rotateCameraAligned.
/**
* Aligns this Billboard so that it points to the camera position.
*
* @param camera
* Camera
*/
private void rotateCameraAligned(Camera camera) {
look.set(camera.getLocation()).subtractLocal(spatial.getWorldTranslation());
// coopt left for our own purposes.
Vector3f xzp = left;
// The xzp vector is the projection of the look vector on the xz plane
xzp.set(look.x, 0, look.z);
// check for undefined rotation...
if (xzp.equals(Vector3f.ZERO)) {
return;
}
look.normalizeLocal();
xzp.normalizeLocal();
float cosp = look.dot(xzp);
// compute the local orientation matrix for the billboard
orient.set(0, 0, xzp.z);
orient.set(0, 1, xzp.x * -look.y);
orient.set(0, 2, xzp.x * cosp);
orient.set(1, 0, 0);
orient.set(1, 1, cosp);
orient.set(1, 2, look.y);
orient.set(2, 0, -xzp.x);
orient.set(2, 1, xzp.z * -look.y);
orient.set(2, 2, xzp.z * cosp);
// The billboard must be oriented to face the camera before it is
// transformed into the world.
spatial.setLocalRotation(orient);
fixRefreshFlags();
}
use of com.jme3.math.Plane in project jmonkeyengine by jMonkeyEngine.
the class Dome method updateGeometry.
/**
* Rebuilds the dome with a new set of parameters.
*
* @param center the new center of the dome.
* @param planes the number of planes along the Z-axis.
* @param radialSamples the new number of radial samples of the dome.
* @param radius the new radius of the dome.
* @param insideView should the dome be set up to be viewed from the inside looking out.
*/
public void updateGeometry(Vector3f center, int planes, int radialSamples, float radius, boolean insideView) {
this.insideView = insideView;
this.center = center != null ? center : new Vector3f(0, 0, 0);
this.planes = planes;
this.radialSamples = radialSamples;
this.radius = radius;
int vertCount = ((planes - 1) * (radialSamples + 1)) + 1;
// Allocate vertices, allocating one extra in each radial to get the
// correct texture coordinates
// setVertexCount();
// setVertexBuffer(createVector3Buffer(getVertexCount()));
// allocate normals
// setNormalBuffer(createVector3Buffer(getVertexCount()));
// allocate texture coordinates
// getTextureCoords().set(0, new TexCoords(createVector2Buffer(getVertexCount())));
FloatBuffer vb = BufferUtils.createVector3Buffer(vertCount);
FloatBuffer nb = BufferUtils.createVector3Buffer(vertCount);
FloatBuffer tb = BufferUtils.createVector2Buffer(vertCount);
setBuffer(Type.Position, 3, vb);
setBuffer(Type.Normal, 3, nb);
setBuffer(Type.TexCoord, 2, tb);
// generate geometry
float fInvRS = 1.0f / radialSamples;
float fYFactor = 1.0f / (planes - 1);
// Generate points on the unit circle to be used in computing the mesh
// points on a dome slice.
float[] afSin = new float[(radialSamples)];
float[] afCos = new float[(radialSamples)];
for (int iR = 0; iR < radialSamples; iR++) {
float fAngle = FastMath.TWO_PI * fInvRS * iR;
afCos[iR] = FastMath.cos(fAngle);
afSin[iR] = FastMath.sin(fAngle);
}
TempVars vars = TempVars.get();
Vector3f tempVc = vars.vect3;
Vector3f tempVb = vars.vect2;
Vector3f tempVa = vars.vect1;
// generate the dome itself
int i = 0;
for (int iY = 0; iY < (planes - 1); iY++, i++) {
// in (0,1)
float fYFraction = fYFactor * iY;
float fY = radius * fYFraction;
// compute center of slice
Vector3f kSliceCenter = tempVb.set(center);
kSliceCenter.y += fY;
// compute radius of slice
float fSliceRadius = FastMath.sqrt(FastMath.abs(radius * radius - fY * fY));
// compute slice vertices
Vector3f kNormal;
int iSave = i;
for (int iR = 0; iR < radialSamples; iR++, i++) {
// in [0,1)
float fRadialFraction = iR * fInvRS;
Vector3f kRadial = tempVc.set(afCos[iR], 0, afSin[iR]);
kRadial.mult(fSliceRadius, tempVa);
vb.put(kSliceCenter.x + tempVa.x).put(kSliceCenter.y + tempVa.y).put(kSliceCenter.z + tempVa.z);
BufferUtils.populateFromBuffer(tempVa, vb, i);
kNormal = tempVa.subtractLocal(center);
kNormal.normalizeLocal();
if (!insideView) {
nb.put(kNormal.x).put(kNormal.y).put(kNormal.z);
} else {
nb.put(-kNormal.x).put(-kNormal.y).put(-kNormal.z);
}
tb.put(fRadialFraction).put(fYFraction);
}
BufferUtils.copyInternalVector3(vb, iSave, i);
BufferUtils.copyInternalVector3(nb, iSave, i);
tb.put(1.0f).put(fYFraction);
}
vars.release();
// pole
vb.put(this.center.x).put(this.center.y + radius).put(this.center.z);
nb.put(0).put(insideView ? -1 : 1).put(0);
tb.put(0.5f).put(1.0f);
// allocate connectivity
int triCount = (planes - 2) * radialSamples * 2 + radialSamples;
ShortBuffer ib = BufferUtils.createShortBuffer(3 * triCount);
setBuffer(Type.Index, 3, ib);
// generate connectivity
int index = 0;
// Generate only for middle planes
for (int plane = 1; plane < (planes - 1); plane++) {
int bottomPlaneStart = ((plane - 1) * (radialSamples + 1));
int topPlaneStart = (plane * (radialSamples + 1));
for (int sample = 0; sample < radialSamples; sample++, index += 6) {
if (insideView) {
ib.put((short) (bottomPlaneStart + sample));
ib.put((short) (bottomPlaneStart + sample + 1));
ib.put((short) (topPlaneStart + sample));
ib.put((short) (bottomPlaneStart + sample + 1));
ib.put((short) (topPlaneStart + sample + 1));
ib.put((short) (topPlaneStart + sample));
} else {
ib.put((short) (bottomPlaneStart + sample));
ib.put((short) (topPlaneStart + sample));
ib.put((short) (bottomPlaneStart + sample + 1));
ib.put((short) (bottomPlaneStart + sample + 1));
ib.put((short) (topPlaneStart + sample));
ib.put((short) (topPlaneStart + sample + 1));
}
}
}
// pole triangles
int bottomPlaneStart = (planes - 2) * (radialSamples + 1);
for (int samples = 0; samples < radialSamples; samples++, index += 3) {
if (insideView) {
ib.put((short) (bottomPlaneStart + samples));
ib.put((short) (bottomPlaneStart + samples + 1));
ib.put((short) (vertCount - 1));
} else {
ib.put((short) (bottomPlaneStart + samples));
ib.put((short) (vertCount - 1));
ib.put((short) (bottomPlaneStart + samples + 1));
}
}
updateBound();
}
use of com.jme3.math.Plane in project jmonkeyengine by jMonkeyEngine.
the class PhysicsTestHelper method createPhysicsTestWorld.
/**
* creates a simple physics test world with a floor, an obstacle and some test boxes
* @param rootNode
* @param assetManager
* @param space
*/
public static void createPhysicsTestWorld(Node rootNode, AssetManager assetManager, PhysicsSpace space) {
AmbientLight light = new AmbientLight();
light.setColor(ColorRGBA.LightGray);
rootNode.addLight(light);
Material material = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
material.setTexture("ColorMap", assetManager.loadTexture("Interface/Logo/Monkey.jpg"));
Box floorBox = new Box(140, 0.25f, 140);
Geometry floorGeometry = new Geometry("Floor", floorBox);
floorGeometry.setMaterial(material);
floorGeometry.setLocalTranslation(0, -5, 0);
// Plane plane = new Plane();
// plane.setOriginNormal(new Vector3f(0, 0.25f, 0), Vector3f.UNIT_Y);
// floorGeometry.addControl(new RigidBodyControl(new PlaneCollisionShape(plane), 0));
floorGeometry.addControl(new RigidBodyControl(0));
rootNode.attachChild(floorGeometry);
space.add(floorGeometry);
//movable boxes
for (int i = 0; i < 12; i++) {
Box box = new Box(0.25f, 0.25f, 0.25f);
Geometry boxGeometry = new Geometry("Box", box);
boxGeometry.setMaterial(material);
boxGeometry.setLocalTranslation(i, 5, -3);
//RigidBodyControl automatically uses box collision shapes when attached to single geometry with box mesh
boxGeometry.addControl(new RigidBodyControl(2));
rootNode.attachChild(boxGeometry);
space.add(boxGeometry);
}
//immovable sphere with mesh collision shape
Sphere sphere = new Sphere(8, 8, 1);
Geometry sphereGeometry = new Geometry("Sphere", sphere);
sphereGeometry.setMaterial(material);
sphereGeometry.setLocalTranslation(4, -4, 2);
sphereGeometry.addControl(new RigidBodyControl(new MeshCollisionShape(sphere), 0));
rootNode.attachChild(sphereGeometry);
space.add(sphereGeometry);
}
use of com.jme3.math.Plane in project jmonkeyengine by jMonkeyEngine.
the class TestKinematicAddToPhysicsSpaceIssue method simpleInitApp.
@Override
public void simpleInitApp() {
bulletAppState = new BulletAppState();
stateManager.attach(bulletAppState);
bulletAppState.setDebugEnabled(true);
// Add a physics sphere to the world
Node physicsSphere = PhysicsTestHelper.createPhysicsTestNode(assetManager, new SphereCollisionShape(1), 1);
physicsSphere.getControl(RigidBodyControl.class).setPhysicsLocation(new Vector3f(3, 6, 0));
rootNode.attachChild(physicsSphere);
//Setting the rigidBody to kinematic before adding it to the physic space
physicsSphere.getControl(RigidBodyControl.class).setKinematic(true);
//adding it to the physic space
getPhysicsSpace().add(physicsSphere);
//Making it not kinematic again, it should fall under gravity, it doesn't
physicsSphere.getControl(RigidBodyControl.class).setKinematic(false);
// Add a physics sphere to the world using the collision shape from sphere one
Node physicsSphere2 = PhysicsTestHelper.createPhysicsTestNode(assetManager, new SphereCollisionShape(1), 1);
physicsSphere2.getControl(RigidBodyControl.class).setPhysicsLocation(new Vector3f(5, 6, 0));
rootNode.attachChild(physicsSphere2);
//Adding the rigid body to physic space
getPhysicsSpace().add(physicsSphere2);
//making it kinematic
physicsSphere2.getControl(RigidBodyControl.class).setKinematic(false);
//Making it not kinematic again, it works properly, the rigidbody is affected by grvity.
physicsSphere2.getControl(RigidBodyControl.class).setKinematic(false);
// an obstacle mesh, does not move (mass=0)
Node node2 = PhysicsTestHelper.createPhysicsTestNode(assetManager, new MeshCollisionShape(new Sphere(16, 16, 1.2f)), 0);
node2.getControl(RigidBodyControl.class).setPhysicsLocation(new Vector3f(2.5f, -4, 0f));
rootNode.attachChild(node2);
getPhysicsSpace().add(node2);
// the floor mesh, does not move (mass=0)
Node node3 = PhysicsTestHelper.createPhysicsTestNode(assetManager, new PlaneCollisionShape(new Plane(new Vector3f(0, 1, 0), 0)), 0);
node3.getControl(RigidBodyControl.class).setPhysicsLocation(new Vector3f(0f, -6, 0f));
rootNode.attachChild(node3);
getPhysicsSpace().add(node3);
}
Aggregations