Implemented a new TempVars system, temp vars can now be requested without conflict.
git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@7692 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
This commit is contained in:
parent
dfeff3c6af
commit
413f2b1e48
@ -165,7 +165,7 @@ public class KinematicRagdollControl implements PhysicsControl, PhysicsCollision
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
TempVars vars = TempVars.get();
|
TempVars vars = TempVars.get();
|
||||||
assert vars.lock();
|
|
||||||
Quaternion tmpRot1 = vars.quat1;
|
Quaternion tmpRot1 = vars.quat1;
|
||||||
Quaternion tmpRot2 = vars.quat2;
|
Quaternion tmpRot2 = vars.quat2;
|
||||||
|
|
||||||
@ -264,7 +264,7 @@ public class KinematicRagdollControl implements PhysicsControl, PhysicsCollision
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
assert vars.unlock();
|
vars.release();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -682,7 +682,6 @@ public class KinematicRagdollControl implements PhysicsControl, PhysicsCollision
|
|||||||
|
|
||||||
baseRigidBody.setKinematic(mode == Mode.Kinetmatic);
|
baseRigidBody.setKinematic(mode == Mode.Kinetmatic);
|
||||||
TempVars vars = TempVars.get();
|
TempVars vars = TempVars.get();
|
||||||
assert vars.lock();
|
|
||||||
for (PhysicsBoneLink link : boneLinks.values()) {
|
for (PhysicsBoneLink link : boneLinks.values()) {
|
||||||
link.rigidBody.setKinematic(mode == Mode.Kinetmatic);
|
link.rigidBody.setKinematic(mode == Mode.Kinetmatic);
|
||||||
if (mode == Mode.Ragdoll) {
|
if (mode == Mode.Ragdoll) {
|
||||||
@ -693,7 +692,7 @@ public class KinematicRagdollControl implements PhysicsControl, PhysicsCollision
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
assert vars.unlock();
|
vars.release();
|
||||||
|
|
||||||
for (Bone bone : skeleton.getRoots()) {
|
for (Bone bone : skeleton.getRoots()) {
|
||||||
RagdollUtils.setUserControl(bone, mode == Mode.Ragdoll);
|
RagdollUtils.setUserControl(bone, mode == Mode.Ragdoll);
|
||||||
@ -718,7 +717,6 @@ public class KinematicRagdollControl implements PhysicsControl, PhysicsCollision
|
|||||||
|
|
||||||
|
|
||||||
TempVars vars = TempVars.get();
|
TempVars vars = TempVars.get();
|
||||||
assert vars.lock();
|
|
||||||
for (PhysicsBoneLink link : boneLinks.values()) {
|
for (PhysicsBoneLink link : boneLinks.values()) {
|
||||||
|
|
||||||
Vector3f p = link.rigidBody.getMotionState().getWorldLocation();
|
Vector3f p = link.rigidBody.getMotionState().getWorldLocation();
|
||||||
@ -737,7 +735,7 @@ public class KinematicRagdollControl implements PhysicsControl, PhysicsCollision
|
|||||||
link.startBlendingRot.set(q2);
|
link.startBlendingRot.set(q2);
|
||||||
link.rigidBody.setKinematic(true);
|
link.rigidBody.setKinematic(true);
|
||||||
}
|
}
|
||||||
assert vars.unlock();
|
vars.release();
|
||||||
|
|
||||||
for (Bone bone : skeleton.getRoots()) {
|
for (Bone bone : skeleton.getRoots()) {
|
||||||
RagdollUtils.setUserControl(bone, false);
|
RagdollUtils.setUserControl(bone, false);
|
||||||
|
@ -80,14 +80,13 @@ public class DebugShapeFactory {
|
|||||||
|
|
||||||
// apply rotation
|
// apply rotation
|
||||||
TempVars vars = TempVars.get();
|
TempVars vars = TempVars.get();
|
||||||
assert vars.lock();
|
|
||||||
Matrix3f tempRot = vars.tempMat3;
|
Matrix3f tempRot = vars.tempMat3;
|
||||||
|
|
||||||
tempRot.set(geometry.getLocalRotation());
|
tempRot.set(geometry.getLocalRotation());
|
||||||
childCollisionShape.rotation.mult(tempRot, tempRot);
|
childCollisionShape.rotation.mult(tempRot, tempRot);
|
||||||
geometry.setLocalRotation(tempRot);
|
geometry.setLocalRotation(tempRot);
|
||||||
|
|
||||||
assert vars.unlock();
|
vars.release();
|
||||||
|
|
||||||
node.attachChild(geometry);
|
node.attachChild(geometry);
|
||||||
}
|
}
|
||||||
|
@ -524,7 +524,7 @@ public final class Bone implements Savable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TempVars vars = TempVars.get();
|
TempVars vars = TempVars.get();
|
||||||
assert vars.lock();
|
// assert vars.lock();
|
||||||
|
|
||||||
Vector3f tmpV = vars.vect1;
|
Vector3f tmpV = vars.vect1;
|
||||||
Vector3f tmpV2 = vars.vect2;
|
Vector3f tmpV2 = vars.vect2;
|
||||||
@ -545,7 +545,7 @@ public final class Bone implements Savable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
assert vars.unlock();
|
vars.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -54,7 +54,6 @@ public final class Skeleton implements Savable {
|
|||||||
|
|
||||||
private Bone[] rootBones;
|
private Bone[] rootBones;
|
||||||
private Bone[] boneList;
|
private Bone[] boneList;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Contains the skinning matrices, multiplying it by a vertex effected by a bone
|
* Contains the skinning matrices, multiplying it by a vertex effected by a bone
|
||||||
* will cause it to go to the animated position.
|
* will cause it to go to the animated position.
|
||||||
@ -251,11 +250,10 @@ public final class Skeleton implements Savable {
|
|||||||
*/
|
*/
|
||||||
public Matrix4f[] computeSkinningMatrices() {
|
public Matrix4f[] computeSkinningMatrices() {
|
||||||
TempVars vars = TempVars.get();
|
TempVars vars = TempVars.get();
|
||||||
assert vars.lock();
|
|
||||||
for (int i = 0; i < boneList.length; i++) {
|
for (int i = 0; i < boneList.length; i++) {
|
||||||
boneList[i].getOffsetTransform(skinningMatrixes[i], vars.quat1, vars.vect1, vars.vect2, vars.tempMat3);
|
boneList[i].getOffsetTransform(skinningMatrixes[i], vars.quat1, vars.vect1, vars.vect2, vars.tempMat3);
|
||||||
}
|
}
|
||||||
assert vars.unlock();
|
vars.release();
|
||||||
return skinningMatrixes;
|
return skinningMatrixes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -227,7 +227,7 @@ public class SkeletonControl extends AbstractControl implements Savable, Cloneab
|
|||||||
int idxWeights = 0;
|
int idxWeights = 0;
|
||||||
|
|
||||||
TempVars vars = TempVars.get();
|
TempVars vars = TempVars.get();
|
||||||
assert vars.lock();
|
|
||||||
|
|
||||||
float[] posBuf = vars.skinPositions;
|
float[] posBuf = vars.skinPositions;
|
||||||
float[] normBuf = vars.skinNormals;
|
float[] normBuf = vars.skinNormals;
|
||||||
@ -284,7 +284,7 @@ public class SkeletonControl extends AbstractControl implements Savable, Cloneab
|
|||||||
fnb.put(normBuf, 0, bufLength);
|
fnb.put(normBuf, 0, bufLength);
|
||||||
}
|
}
|
||||||
|
|
||||||
assert vars.unlock();
|
vars.release();
|
||||||
|
|
||||||
vb.updateData(fvb);
|
vb.updateData(fvb);
|
||||||
nb.updateData(fnb);
|
nb.updateData(fnb);
|
||||||
|
@ -29,7 +29,6 @@
|
|||||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.jme3.bounding;
|
package com.jme3.bounding;
|
||||||
|
|
||||||
import com.jme3.collision.Collidable;
|
import com.jme3.collision.Collidable;
|
||||||
@ -90,14 +89,14 @@ public class BoundingBox extends BoundingVolume {
|
|||||||
this.zExtent = z;
|
this.zExtent = z;
|
||||||
}
|
}
|
||||||
|
|
||||||
public BoundingBox(BoundingBox source){
|
public BoundingBox(BoundingBox source) {
|
||||||
this.center.set(source.center);
|
this.center.set(source.center);
|
||||||
this.xExtent = source.xExtent;
|
this.xExtent = source.xExtent;
|
||||||
this.yExtent = source.yExtent;
|
this.yExtent = source.yExtent;
|
||||||
this.zExtent = source.zExtent;
|
this.zExtent = source.zExtent;
|
||||||
}
|
}
|
||||||
|
|
||||||
public BoundingBox(Vector3f min, Vector3f max){
|
public BoundingBox(Vector3f min, Vector3f max) {
|
||||||
setMinMax(min, max);
|
setMinMax(min, max);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -130,7 +129,7 @@ public class BoundingBox extends BoundingVolume {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TempVars vars = TempVars.get();
|
TempVars vars = TempVars.get();
|
||||||
assert vars.lock();
|
|
||||||
Vector3f min = vars.vect1.set(new Vector3f(Float.POSITIVE_INFINITY, Float.POSITIVE_INFINITY, Float.POSITIVE_INFINITY));
|
Vector3f min = vars.vect1.set(new Vector3f(Float.POSITIVE_INFINITY, Float.POSITIVE_INFINITY, Float.POSITIVE_INFINITY));
|
||||||
Vector3f max = vars.vect2.set(new Vector3f(Float.NEGATIVE_INFINITY, Float.NEGATIVE_INFINITY, Float.NEGATIVE_INFINITY));
|
Vector3f max = vars.vect2.set(new Vector3f(Float.NEGATIVE_INFINITY, Float.NEGATIVE_INFINITY, Float.NEGATIVE_INFINITY));
|
||||||
|
|
||||||
@ -151,27 +150,27 @@ public class BoundingBox extends BoundingVolume {
|
|||||||
yExtent = max.y - center.y;
|
yExtent = max.y - center.y;
|
||||||
zExtent = max.z - center.z;
|
zExtent = max.z - center.z;
|
||||||
|
|
||||||
assert vars.unlock();
|
vars.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void computeFromTris(int[] indices, Mesh mesh, int start, int end) {
|
public void computeFromTris(int[] indices, Mesh mesh, int start, int end) {
|
||||||
if (end - start <= 0) {
|
if (end - start <= 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
TempVars vars = TempVars.get();
|
TempVars vars = TempVars.get();
|
||||||
assert vars.lock();
|
|
||||||
Vector3f vect1 = vars.vect1;
|
Vector3f vect1 = vars.vect1;
|
||||||
Vector3f vect2 = vars.vect2;
|
Vector3f vect2 = vars.vect2;
|
||||||
Triangle triangle = vars.triangle;
|
Triangle triangle = vars.triangle;
|
||||||
|
|
||||||
Vector3f min = vect1.set(Float.POSITIVE_INFINITY, Float.POSITIVE_INFINITY, Float.POSITIVE_INFINITY);
|
Vector3f min = vect1.set(Float.POSITIVE_INFINITY, Float.POSITIVE_INFINITY, Float.POSITIVE_INFINITY);
|
||||||
Vector3f max = vect2.set(Float.NEGATIVE_INFINITY, Float.NEGATIVE_INFINITY, Float.NEGATIVE_INFINITY);
|
Vector3f max = vect2.set(Float.NEGATIVE_INFINITY, Float.NEGATIVE_INFINITY, Float.NEGATIVE_INFINITY);
|
||||||
Vector3f point;
|
Vector3f point;
|
||||||
|
|
||||||
for (int i = start; i < end; i++) {
|
for (int i = start; i < end; i++) {
|
||||||
mesh.getTriangle(indices[i], triangle);
|
mesh.getTriangle(indices[i], triangle);
|
||||||
point = triangle.get(0);
|
point = triangle.get(0);
|
||||||
checkMinMax(min, max, point);
|
checkMinMax(min, max, point);
|
||||||
point = triangle.get(1);
|
point = triangle.get(1);
|
||||||
checkMinMax(min, max, point);
|
checkMinMax(min, max, point);
|
||||||
@ -186,22 +185,28 @@ public class BoundingBox extends BoundingVolume {
|
|||||||
yExtent = max.y - center.y;
|
yExtent = max.y - center.y;
|
||||||
zExtent = max.z - center.z;
|
zExtent = max.z - center.z;
|
||||||
|
|
||||||
assert vars.unlock();
|
vars.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final void checkMinMax(Vector3f min, Vector3f max, Vector3f point) {
|
public static final void checkMinMax(Vector3f min, Vector3f max, Vector3f point) {
|
||||||
if (point.x < min.x)
|
if (point.x < min.x) {
|
||||||
min.x = point.x;
|
min.x = point.x;
|
||||||
if (point.x > max.x)
|
}
|
||||||
|
if (point.x > max.x) {
|
||||||
max.x = point.x;
|
max.x = point.x;
|
||||||
if (point.y < min.y)
|
}
|
||||||
|
if (point.y < min.y) {
|
||||||
min.y = point.y;
|
min.y = point.y;
|
||||||
if (point.y > max.y)
|
}
|
||||||
|
if (point.y > max.y) {
|
||||||
max.y = point.y;
|
max.y = point.y;
|
||||||
if (point.z < min.z)
|
}
|
||||||
|
if (point.z < min.z) {
|
||||||
min.z = point.z;
|
min.z = point.z;
|
||||||
if (point.z > max.z)
|
}
|
||||||
|
if (point.z > max.z) {
|
||||||
max.z = point.z;
|
max.z = point.z;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -213,15 +218,18 @@ public class BoundingBox extends BoundingVolume {
|
|||||||
* the list of points.
|
* the list of points.
|
||||||
*/
|
*/
|
||||||
public void containAABB(FloatBuffer points) {
|
public void containAABB(FloatBuffer points) {
|
||||||
if (points == null)
|
if (points == null) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
points.rewind();
|
points.rewind();
|
||||||
if (points.remaining() <= 2) // we need at least a 3 float vector
|
if (points.remaining() <= 2) // we need at least a 3 float vector
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
TempVars vars = TempVars.get();
|
TempVars vars = TempVars.get();
|
||||||
assert vars.lock();
|
|
||||||
BufferUtils.populateFromBuffer(vars.vect1, points, 0);
|
BufferUtils.populateFromBuffer(vars.vect1, points, 0);
|
||||||
float minX = vars.vect1.x, minY = vars.vect1.y, minZ = vars.vect1.z;
|
float minX = vars.vect1.x, minY = vars.vect1.y, minZ = vars.vect1.z;
|
||||||
float maxX = vars.vect1.x, maxY = vars.vect1.y, maxZ = vars.vect1.z;
|
float maxX = vars.vect1.x, maxY = vars.vect1.y, maxZ = vars.vect1.z;
|
||||||
@ -229,23 +237,26 @@ public class BoundingBox extends BoundingVolume {
|
|||||||
for (int i = 1, len = points.remaining() / 3; i < len; i++) {
|
for (int i = 1, len = points.remaining() / 3; i < len; i++) {
|
||||||
BufferUtils.populateFromBuffer(vars.vect1, points, i);
|
BufferUtils.populateFromBuffer(vars.vect1, points, i);
|
||||||
|
|
||||||
if (vars.vect1.x < minX)
|
if (vars.vect1.x < minX) {
|
||||||
minX = vars.vect1.x;
|
minX = vars.vect1.x;
|
||||||
else if (vars.vect1.x > maxX)
|
} else if (vars.vect1.x > maxX) {
|
||||||
maxX = vars.vect1.x;
|
maxX = vars.vect1.x;
|
||||||
|
}
|
||||||
|
|
||||||
if (vars.vect1.y < minY)
|
if (vars.vect1.y < minY) {
|
||||||
minY = vars.vect1.y;
|
minY = vars.vect1.y;
|
||||||
else if (vars.vect1.y > maxY)
|
} else if (vars.vect1.y > maxY) {
|
||||||
maxY = vars.vect1.y;
|
maxY = vars.vect1.y;
|
||||||
|
}
|
||||||
|
|
||||||
if (vars.vect1.z < minZ)
|
if (vars.vect1.z < minZ) {
|
||||||
minZ = vars.vect1.z;
|
minZ = vars.vect1.z;
|
||||||
else if (vars.vect1.z > maxZ)
|
} else if (vars.vect1.z > maxZ) {
|
||||||
maxZ = vars.vect1.z;
|
maxZ = vars.vect1.z;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
assert vars.unlock();
|
vars.release();
|
||||||
|
|
||||||
center.set(minX + maxX, minY + maxY, minZ + maxZ);
|
center.set(minX + maxX, minY + maxY, minZ + maxZ);
|
||||||
center.multLocal(0.5f);
|
center.multLocal(0.5f);
|
||||||
@ -278,7 +289,7 @@ public class BoundingBox extends BoundingVolume {
|
|||||||
box.center.addLocal(trans.getTranslation());
|
box.center.addLocal(trans.getTranslation());
|
||||||
|
|
||||||
TempVars vars = TempVars.get();
|
TempVars vars = TempVars.get();
|
||||||
assert vars.lock();
|
|
||||||
Matrix3f transMatrix = vars.tempMat3;
|
Matrix3f transMatrix = vars.tempMat3;
|
||||||
transMatrix.set(trans.getRotation());
|
transMatrix.set(trans.getRotation());
|
||||||
// Make the rotation matrix all positive to get the maximum x/y/z extent
|
// Make the rotation matrix all positive to get the maximum x/y/z extent
|
||||||
@ -292,12 +303,12 @@ public class BoundingBox extends BoundingVolume {
|
|||||||
box.yExtent = FastMath.abs(vars.vect2.getY());
|
box.yExtent = FastMath.abs(vars.vect2.getY());
|
||||||
box.zExtent = FastMath.abs(vars.vect2.getZ());
|
box.zExtent = FastMath.abs(vars.vect2.getZ());
|
||||||
|
|
||||||
assert vars.unlock();
|
vars.release();
|
||||||
|
|
||||||
return box;
|
return box;
|
||||||
}
|
}
|
||||||
|
|
||||||
public BoundingVolume transform(Matrix4f trans, BoundingVolume store){
|
public BoundingVolume transform(Matrix4f trans, BoundingVolume store) {
|
||||||
BoundingBox box;
|
BoundingBox box;
|
||||||
if (store == null || store.getType() != Type.AABB) {
|
if (store == null || store.getType() != Type.AABB) {
|
||||||
box = new BoundingBox();
|
box = new BoundingBox();
|
||||||
@ -305,7 +316,7 @@ public class BoundingBox extends BoundingVolume {
|
|||||||
box = (BoundingBox) store;
|
box = (BoundingBox) store;
|
||||||
}
|
}
|
||||||
TempVars vars = TempVars.get();
|
TempVars vars = TempVars.get();
|
||||||
assert vars.lock();
|
|
||||||
|
|
||||||
float w = trans.multProj(center, box.center);
|
float w = trans.multProj(center, box.center);
|
||||||
box.center.divideLocal(w);
|
box.center.divideLocal(w);
|
||||||
@ -324,7 +335,7 @@ public class BoundingBox extends BoundingVolume {
|
|||||||
box.yExtent = FastMath.abs(vars.vect1.getY());
|
box.yExtent = FastMath.abs(vars.vect1.getY());
|
||||||
box.zExtent = FastMath.abs(vars.vect1.getZ());
|
box.zExtent = FastMath.abs(vars.vect1.getZ());
|
||||||
|
|
||||||
assert vars.unlock();
|
vars.release();
|
||||||
|
|
||||||
return box;
|
return box;
|
||||||
}
|
}
|
||||||
@ -371,14 +382,14 @@ public class BoundingBox extends BoundingVolume {
|
|||||||
BoundingBox vBox = (BoundingBox) volume;
|
BoundingBox vBox = (BoundingBox) volume;
|
||||||
return merge(vBox.center, vBox.xExtent, vBox.yExtent,
|
return merge(vBox.center, vBox.xExtent, vBox.yExtent,
|
||||||
vBox.zExtent, new BoundingBox(new Vector3f(0, 0, 0), 0,
|
vBox.zExtent, new BoundingBox(new Vector3f(0, 0, 0), 0,
|
||||||
0, 0));
|
0, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
case Sphere: {
|
case Sphere: {
|
||||||
BoundingSphere vSphere = (BoundingSphere) volume;
|
BoundingSphere vSphere = (BoundingSphere) volume;
|
||||||
return merge(vSphere.center, vSphere.radius, vSphere.radius,
|
return merge(vSphere.center, vSphere.radius, vSphere.radius,
|
||||||
vSphere.radius, new BoundingBox(new Vector3f(0, 0, 0),
|
vSphere.radius, new BoundingBox(new Vector3f(0, 0, 0),
|
||||||
0, 0, 0));
|
0, 0, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
// case OBB: {
|
// case OBB: {
|
||||||
@ -471,7 +482,6 @@ public class BoundingBox extends BoundingVolume {
|
|||||||
// zExtent = max.z - center.z;
|
// zExtent = max.z - center.z;
|
||||||
// return this;
|
// return this;
|
||||||
// }
|
// }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <code>merge</code> combines this bounding box with another box which is
|
* <code>merge</code> combines this bounding box with another box which is
|
||||||
* defined by the center, x, y, z extents.
|
* defined by the center, x, y, z extents.
|
||||||
@ -492,26 +502,32 @@ public class BoundingBox extends BoundingVolume {
|
|||||||
float boxZ, BoundingBox rVal) {
|
float boxZ, BoundingBox rVal) {
|
||||||
|
|
||||||
TempVars vars = TempVars.get();
|
TempVars vars = TempVars.get();
|
||||||
assert vars.lock();
|
|
||||||
vars.vect1.x = center.x - xExtent;
|
vars.vect1.x = center.x - xExtent;
|
||||||
if (vars.vect1.x > boxCenter.x - boxX)
|
if (vars.vect1.x > boxCenter.x - boxX) {
|
||||||
vars.vect1.x = boxCenter.x - boxX;
|
vars.vect1.x = boxCenter.x - boxX;
|
||||||
|
}
|
||||||
vars.vect1.y = center.y - yExtent;
|
vars.vect1.y = center.y - yExtent;
|
||||||
if (vars.vect1.y > boxCenter.y - boxY)
|
if (vars.vect1.y > boxCenter.y - boxY) {
|
||||||
vars.vect1.y = boxCenter.y - boxY;
|
vars.vect1.y = boxCenter.y - boxY;
|
||||||
|
}
|
||||||
vars.vect1.z = center.z - zExtent;
|
vars.vect1.z = center.z - zExtent;
|
||||||
if (vars.vect1.z > boxCenter.z - boxZ)
|
if (vars.vect1.z > boxCenter.z - boxZ) {
|
||||||
vars.vect1.z = boxCenter.z - boxZ;
|
vars.vect1.z = boxCenter.z - boxZ;
|
||||||
|
}
|
||||||
|
|
||||||
vars.vect2.x = center.x + xExtent;
|
vars.vect2.x = center.x + xExtent;
|
||||||
if (vars.vect2.x < boxCenter.x + boxX)
|
if (vars.vect2.x < boxCenter.x + boxX) {
|
||||||
vars.vect2.x = boxCenter.x + boxX;
|
vars.vect2.x = boxCenter.x + boxX;
|
||||||
|
}
|
||||||
vars.vect2.y = center.y + yExtent;
|
vars.vect2.y = center.y + yExtent;
|
||||||
if (vars.vect2.y < boxCenter.y + boxY)
|
if (vars.vect2.y < boxCenter.y + boxY) {
|
||||||
vars.vect2.y = boxCenter.y + boxY;
|
vars.vect2.y = boxCenter.y + boxY;
|
||||||
|
}
|
||||||
vars.vect2.z = center.z + zExtent;
|
vars.vect2.z = center.z + zExtent;
|
||||||
if (vars.vect2.z < boxCenter.z + boxZ)
|
if (vars.vect2.z < boxCenter.z + boxZ) {
|
||||||
vars.vect2.z = boxCenter.z + boxZ;
|
vars.vect2.z = boxCenter.z + boxZ;
|
||||||
|
}
|
||||||
|
|
||||||
center.set(vars.vect2).addLocal(vars.vect1).multLocal(0.5f);
|
center.set(vars.vect2).addLocal(vars.vect1).multLocal(0.5f);
|
||||||
|
|
||||||
@ -519,7 +535,7 @@ public class BoundingBox extends BoundingVolume {
|
|||||||
yExtent = vars.vect2.y - center.y;
|
yExtent = vars.vect2.y - center.y;
|
||||||
zExtent = vars.vect2.z - center.z;
|
zExtent = vars.vect2.z - center.z;
|
||||||
|
|
||||||
assert vars.unlock();
|
vars.release();
|
||||||
|
|
||||||
return rVal;
|
return rVal;
|
||||||
}
|
}
|
||||||
@ -583,10 +599,11 @@ public class BoundingBox extends BoundingVolume {
|
|||||||
if (FastMath.abs(center.x - bs.center.x) < bs.getRadius()
|
if (FastMath.abs(center.x - bs.center.x) < bs.getRadius()
|
||||||
+ xExtent
|
+ xExtent
|
||||||
&& FastMath.abs(center.y - bs.center.y) < bs.getRadius()
|
&& FastMath.abs(center.y - bs.center.y) < bs.getRadius()
|
||||||
+ yExtent
|
+ yExtent
|
||||||
&& FastMath.abs(center.z - bs.center.z) < bs.getRadius()
|
&& FastMath.abs(center.z - bs.center.z) < bs.getRadius()
|
||||||
+ zExtent)
|
+ zExtent) {
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -602,16 +619,17 @@ public class BoundingBox extends BoundingVolume {
|
|||||||
assert Vector3f.isValidVector(center) && Vector3f.isValidVector(bb.center);
|
assert Vector3f.isValidVector(center) && Vector3f.isValidVector(bb.center);
|
||||||
|
|
||||||
if (center.x + xExtent < bb.center.x - bb.xExtent
|
if (center.x + xExtent < bb.center.x - bb.xExtent
|
||||||
|| center.x - xExtent > bb.center.x + bb.xExtent)
|
|| center.x - xExtent > bb.center.x + bb.xExtent) {
|
||||||
return false;
|
return false;
|
||||||
else if (center.y + yExtent < bb.center.y - bb.yExtent
|
} else if (center.y + yExtent < bb.center.y - bb.yExtent
|
||||||
|| center.y - yExtent > bb.center.y + bb.yExtent)
|
|| center.y - yExtent > bb.center.y + bb.yExtent) {
|
||||||
return false;
|
return false;
|
||||||
else if (center.z + zExtent < bb.center.z - bb.zExtent
|
} else if (center.z + zExtent < bb.center.z - bb.zExtent
|
||||||
|| center.z - zExtent > bb.center.z + bb.zExtent)
|
|| center.z - zExtent > bb.center.z + bb.zExtent) {
|
||||||
return false;
|
return false;
|
||||||
else
|
} else {
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -623,7 +641,6 @@ public class BoundingBox extends BoundingVolume {
|
|||||||
// public boolean intersectsOrientedBoundingBox(OrientedBoundingBox obb) {
|
// public boolean intersectsOrientedBoundingBox(OrientedBoundingBox obb) {
|
||||||
// return obb.intersectsBoundingBox(this);
|
// return obb.intersectsBoundingBox(this);
|
||||||
// }
|
// }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* determines if this bounding box intersects with a given ray object. If an
|
* determines if this bounding box intersects with a given ray object. If an
|
||||||
* intersection has occurred, true is returned, otherwise false is returned.
|
* intersection has occurred, true is returned, otherwise false is returned.
|
||||||
@ -636,21 +653,21 @@ public class BoundingBox extends BoundingVolume {
|
|||||||
float rhs;
|
float rhs;
|
||||||
|
|
||||||
TempVars vars = TempVars.get();
|
TempVars vars = TempVars.get();
|
||||||
assert vars.lock();
|
|
||||||
Vector3f diff = ray.origin.subtract(getCenter(vars.vect2), vars.vect1);
|
Vector3f diff = ray.origin.subtract(getCenter(vars.vect2), vars.vect1);
|
||||||
|
|
||||||
final float[] fWdU = vars.fWdU;
|
final float[] fWdU = vars.fWdU;
|
||||||
final float[] fAWdU = vars.fAWdU;
|
final float[] fAWdU = vars.fAWdU;
|
||||||
final float[] fDdU = vars.fDdU;
|
final float[] fDdU = vars.fDdU;
|
||||||
final float[] fADdU = vars.fADdU;
|
final float[] fADdU = vars.fADdU;
|
||||||
final float[] fAWxDdU = vars.fAWxDdU;
|
final float[] fAWxDdU = vars.fAWxDdU;
|
||||||
|
|
||||||
fWdU[0] = ray.getDirection().dot(Vector3f.UNIT_X);
|
fWdU[0] = ray.getDirection().dot(Vector3f.UNIT_X);
|
||||||
fAWdU[0] = FastMath.abs(fWdU[0]);
|
fAWdU[0] = FastMath.abs(fWdU[0]);
|
||||||
fDdU[0] = diff.dot(Vector3f.UNIT_X);
|
fDdU[0] = diff.dot(Vector3f.UNIT_X);
|
||||||
fADdU[0] = FastMath.abs(fDdU[0]);
|
fADdU[0] = FastMath.abs(fDdU[0]);
|
||||||
if (fADdU[0] > xExtent && fDdU[0] * fWdU[0] >= 0.0) {
|
if (fADdU[0] > xExtent && fDdU[0] * fWdU[0] >= 0.0) {
|
||||||
assert vars.unlock();
|
vars.release();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -659,7 +676,7 @@ public class BoundingBox extends BoundingVolume {
|
|||||||
fDdU[1] = diff.dot(Vector3f.UNIT_Y);
|
fDdU[1] = diff.dot(Vector3f.UNIT_Y);
|
||||||
fADdU[1] = FastMath.abs(fDdU[1]);
|
fADdU[1] = FastMath.abs(fDdU[1]);
|
||||||
if (fADdU[1] > yExtent && fDdU[1] * fWdU[1] >= 0.0) {
|
if (fADdU[1] > yExtent && fDdU[1] * fWdU[1] >= 0.0) {
|
||||||
assert vars.unlock();
|
vars.release();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -668,7 +685,7 @@ public class BoundingBox extends BoundingVolume {
|
|||||||
fDdU[2] = diff.dot(Vector3f.UNIT_Z);
|
fDdU[2] = diff.dot(Vector3f.UNIT_Z);
|
||||||
fADdU[2] = FastMath.abs(fDdU[2]);
|
fADdU[2] = FastMath.abs(fDdU[2]);
|
||||||
if (fADdU[2] > zExtent && fDdU[2] * fWdU[2] >= 0.0) {
|
if (fADdU[2] > zExtent && fDdU[2] * fWdU[2] >= 0.0) {
|
||||||
assert vars.unlock();
|
vars.release();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -677,25 +694,25 @@ public class BoundingBox extends BoundingVolume {
|
|||||||
fAWxDdU[0] = FastMath.abs(wCrossD.dot(Vector3f.UNIT_X));
|
fAWxDdU[0] = FastMath.abs(wCrossD.dot(Vector3f.UNIT_X));
|
||||||
rhs = yExtent * fAWdU[2] + zExtent * fAWdU[1];
|
rhs = yExtent * fAWdU[2] + zExtent * fAWdU[1];
|
||||||
if (fAWxDdU[0] > rhs) {
|
if (fAWxDdU[0] > rhs) {
|
||||||
assert vars.unlock();
|
vars.release();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
fAWxDdU[1] = FastMath.abs(wCrossD.dot(Vector3f.UNIT_Y));
|
fAWxDdU[1] = FastMath.abs(wCrossD.dot(Vector3f.UNIT_Y));
|
||||||
rhs = xExtent * fAWdU[2] + zExtent * fAWdU[0];
|
rhs = xExtent * fAWdU[2] + zExtent * fAWdU[0];
|
||||||
if (fAWxDdU[1] > rhs) {
|
if (fAWxDdU[1] > rhs) {
|
||||||
assert vars.unlock();
|
vars.release();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
fAWxDdU[2] = FastMath.abs(wCrossD.dot(Vector3f.UNIT_Z));
|
fAWxDdU[2] = FastMath.abs(wCrossD.dot(Vector3f.UNIT_Z));
|
||||||
rhs = xExtent * fAWdU[1] + yExtent * fAWdU[0];
|
rhs = xExtent * fAWdU[1] + yExtent * fAWdU[0];
|
||||||
if (fAWxDdU[2] > rhs) {
|
if (fAWxDdU[2] > rhs) {
|
||||||
assert vars.unlock();
|
vars.release();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
assert vars.unlock();
|
vars.release();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -704,11 +721,11 @@ public class BoundingBox extends BoundingVolume {
|
|||||||
*/
|
*/
|
||||||
private int collideWithRay(Ray ray, CollisionResults results) {
|
private int collideWithRay(Ray ray, CollisionResults results) {
|
||||||
TempVars vars = TempVars.get();
|
TempVars vars = TempVars.get();
|
||||||
assert vars.lock();
|
|
||||||
Vector3f diff = vars.vect1.set(ray.origin).subtractLocal(center);
|
Vector3f diff = vars.vect1.set(ray.origin).subtractLocal(center);
|
||||||
Vector3f direction = vars.vect2.set(ray.direction);
|
Vector3f direction = vars.vect2.set(ray.direction);
|
||||||
|
|
||||||
float[] t = { 0f, Float.POSITIVE_INFINITY };
|
float[] t = {0f, Float.POSITIVE_INFINITY};
|
||||||
|
|
||||||
float saveT0 = t[0], saveT1 = t[1];
|
float saveT0 = t[0], saveT1 = t[1];
|
||||||
boolean notEntirelyClipped = clip(+direction.x, -diff.x - xExtent, t)
|
boolean notEntirelyClipped = clip(+direction.x, -diff.x - xExtent, t)
|
||||||
@ -717,15 +734,15 @@ public class BoundingBox extends BoundingVolume {
|
|||||||
&& clip(-direction.y, +diff.y - yExtent, t)
|
&& clip(-direction.y, +diff.y - yExtent, t)
|
||||||
&& clip(+direction.z, -diff.z - zExtent, t)
|
&& clip(+direction.z, -diff.z - zExtent, t)
|
||||||
&& clip(-direction.z, +diff.z - zExtent, t);
|
&& clip(-direction.z, +diff.z - zExtent, t);
|
||||||
assert vars.unlock();
|
vars.release();
|
||||||
|
|
||||||
if (notEntirelyClipped && (t[0] != saveT0 || t[1] != saveT1)) {
|
if (notEntirelyClipped && (t[0] != saveT0 || t[1] != saveT1)) {
|
||||||
if (t[1] > t[0]) {
|
if (t[1] > t[0]) {
|
||||||
float[] distances = t;
|
float[] distances = t;
|
||||||
Vector3f[] points = new Vector3f[] {
|
Vector3f[] points = new Vector3f[]{
|
||||||
new Vector3f(ray.direction).multLocal(distances[0]).addLocal(ray.origin),
|
new Vector3f(ray.direction).multLocal(distances[0]).addLocal(ray.origin),
|
||||||
new Vector3f(ray.direction).multLocal(distances[1]).addLocal(ray.origin)
|
new Vector3f(ray.direction).multLocal(distances[1]).addLocal(ray.origin)
|
||||||
};
|
};
|
||||||
|
|
||||||
CollisionResult result = new CollisionResult(points[0], distances[0]);
|
CollisionResult result = new CollisionResult(points[0], distances[0]);
|
||||||
results.addCollision(result);
|
results.addCollision(result);
|
||||||
@ -742,20 +759,20 @@ public class BoundingBox extends BoundingVolume {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int collideWith(Collidable other, CollisionResults results){
|
public int collideWith(Collidable other, CollisionResults results) {
|
||||||
if (other instanceof Ray){
|
if (other instanceof Ray) {
|
||||||
Ray ray = (Ray) other;
|
Ray ray = (Ray) other;
|
||||||
return collideWithRay(ray, results);
|
return collideWithRay(ray, results);
|
||||||
}else if (other instanceof Triangle){
|
} else if (other instanceof Triangle) {
|
||||||
Triangle t = (Triangle) other;
|
Triangle t = (Triangle) other;
|
||||||
if (intersects(t.get1(), t.get2(), t.get3())){
|
if (intersects(t.get1(), t.get2(), t.get3())) {
|
||||||
CollisionResult r = new CollisionResult();
|
CollisionResult r = new CollisionResult();
|
||||||
results.addCollision(r);
|
results.addCollision(r);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}else{
|
} else {
|
||||||
throw new UnsupportedCollisionException("With: "+other.getClass().getSimpleName());
|
throw new UnsupportedCollisionException("With: " + other.getClass().getSimpleName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -768,8 +785,8 @@ public class BoundingBox extends BoundingVolume {
|
|||||||
* @return True if the bounding box intersects the triangle, false
|
* @return True if the bounding box intersects the triangle, false
|
||||||
* otherwise.
|
* otherwise.
|
||||||
*/
|
*/
|
||||||
public boolean intersects(Vector3f v1, Vector3f v2, Vector3f v3){
|
public boolean intersects(Vector3f v1, Vector3f v2, Vector3f v3) {
|
||||||
return Intersection.intersect(this, v1, v2, v3);
|
return Intersection.intersect(this, v1, v2, v3);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -844,16 +861,20 @@ public class BoundingBox extends BoundingVolume {
|
|||||||
// plane. Otherwise 'false' is returned in which case the line segment
|
// plane. Otherwise 'false' is returned in which case the line segment
|
||||||
// is entirely clipped.
|
// is entirely clipped.
|
||||||
if (denom > 0.0f) {
|
if (denom > 0.0f) {
|
||||||
if (numer > denom * t[1])
|
if (numer > denom * t[1]) {
|
||||||
return false;
|
return false;
|
||||||
if (numer > denom * t[0])
|
}
|
||||||
|
if (numer > denom * t[0]) {
|
||||||
t[0] = numer / denom;
|
t[0] = numer / denom;
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
} else if (denom < 0.0f) {
|
} else if (denom < 0.0f) {
|
||||||
if (numer > denom * t[0])
|
if (numer > denom * t[0]) {
|
||||||
return false;
|
return false;
|
||||||
if (numer > denom * t[1])
|
}
|
||||||
|
if (numer > denom * t[1]) {
|
||||||
t[1] = numer / denom;
|
t[1] = numer / denom;
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
return numer <= 0.0;
|
return numer <= 0.0;
|
||||||
@ -875,40 +896,43 @@ public class BoundingBox extends BoundingVolume {
|
|||||||
return store;
|
return store;
|
||||||
}
|
}
|
||||||
|
|
||||||
public float getXExtent(){
|
public float getXExtent() {
|
||||||
return xExtent;
|
return xExtent;
|
||||||
}
|
}
|
||||||
|
|
||||||
public float getYExtent(){
|
public float getYExtent() {
|
||||||
return yExtent;
|
return yExtent;
|
||||||
}
|
}
|
||||||
|
|
||||||
public float getZExtent(){
|
public float getZExtent() {
|
||||||
return zExtent;
|
return zExtent;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setXExtent(float xExtent) {
|
public void setXExtent(float xExtent) {
|
||||||
if (xExtent < 0)
|
if (xExtent < 0) {
|
||||||
throw new IllegalArgumentException();
|
throw new IllegalArgumentException();
|
||||||
|
}
|
||||||
|
|
||||||
this.xExtent = xExtent;
|
this.xExtent = xExtent;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setYExtent(float yExtent) {
|
public void setYExtent(float yExtent) {
|
||||||
if (yExtent < 0)
|
if (yExtent < 0) {
|
||||||
throw new IllegalArgumentException();
|
throw new IllegalArgumentException();
|
||||||
|
}
|
||||||
|
|
||||||
this.yExtent = yExtent;
|
this.yExtent = yExtent;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setZExtent(float zExtent) {
|
public void setZExtent(float zExtent) {
|
||||||
if (zExtent < 0)
|
if (zExtent < 0) {
|
||||||
throw new IllegalArgumentException();
|
throw new IllegalArgumentException();
|
||||||
|
}
|
||||||
|
|
||||||
this.zExtent = zExtent;
|
this.zExtent = zExtent;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Vector3f getMin(Vector3f store){
|
public Vector3f getMin(Vector3f store) {
|
||||||
if (store == null) {
|
if (store == null) {
|
||||||
store = new Vector3f();
|
store = new Vector3f();
|
||||||
}
|
}
|
||||||
@ -916,7 +940,7 @@ public class BoundingBox extends BoundingVolume {
|
|||||||
return store;
|
return store;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Vector3f getMax(Vector3f store){
|
public Vector3f getMax(Vector3f store) {
|
||||||
if (store == null) {
|
if (store == null) {
|
||||||
store = new Vector3f();
|
store = new Vector3f();
|
||||||
}
|
}
|
||||||
@ -924,7 +948,7 @@ public class BoundingBox extends BoundingVolume {
|
|||||||
return store;
|
return store;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setMinMax(Vector3f min, Vector3f max){
|
public void setMinMax(Vector3f min, Vector3f max) {
|
||||||
this.center.set(max).addLocal(min).multLocal(0.5f);
|
this.center.set(max).addLocal(min).multLocal(0.5f);
|
||||||
xExtent = FastMath.abs(max.x - center.x);
|
xExtent = FastMath.abs(max.x - center.x);
|
||||||
yExtent = FastMath.abs(max.y - center.y);
|
yExtent = FastMath.abs(max.y - center.y);
|
||||||
@ -951,7 +975,6 @@ public class BoundingBox extends BoundingVolume {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public float getVolume() {
|
public float getVolume() {
|
||||||
return (8*xExtent*yExtent*zExtent);
|
return (8 * xExtent * yExtent * zExtent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,7 +29,6 @@
|
|||||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.jme3.bounding;
|
package com.jme3.bounding;
|
||||||
|
|
||||||
import com.jme3.collision.Collidable;
|
import com.jme3.collision.Collidable;
|
||||||
@ -69,9 +68,7 @@ public class BoundingSphere extends BoundingVolume {
|
|||||||
|
|
||||||
private static final Logger logger =
|
private static final Logger logger =
|
||||||
Logger.getLogger(BoundingSphere.class.getName());
|
Logger.getLogger(BoundingSphere.class.getName());
|
||||||
|
|
||||||
float radius;
|
float radius;
|
||||||
|
|
||||||
private static final float RADIUS_EPSILON = 1f + 0.00001f;
|
private static final float RADIUS_EPSILON = 1f + 0.00001f;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -95,7 +92,7 @@ public class BoundingSphere extends BoundingVolume {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Type getType() {
|
public Type getType() {
|
||||||
return Type.Sphere;
|
return Type.Sphere;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -146,9 +143,9 @@ public class BoundingSphere extends BoundingVolume {
|
|||||||
|
|
||||||
int count = 0;
|
int count = 0;
|
||||||
for (int i = start; i < end; i++) {
|
for (int i = start; i < end; i++) {
|
||||||
vertList[count++] = tris[i].get(0);
|
vertList[count++] = tris[i].get(0);
|
||||||
vertList[count++] = tris[i].get(1);
|
vertList[count++] = tris[i].get(1);
|
||||||
vertList[count++] = tris[i].get(2);
|
vertList[count++] = tris[i].get(2);
|
||||||
}
|
}
|
||||||
averagePoints(vertList);
|
averagePoints(vertList);
|
||||||
}
|
}
|
||||||
@ -190,8 +187,9 @@ public class BoundingSphere extends BoundingVolume {
|
|||||||
* The points to calculate the minimum bounds from.
|
* The points to calculate the minimum bounds from.
|
||||||
*/
|
*/
|
||||||
public void calcWelzl(FloatBuffer points) {
|
public void calcWelzl(FloatBuffer points) {
|
||||||
if (center == null)
|
if (center == null) {
|
||||||
center = new Vector3f();
|
center = new Vector3f();
|
||||||
|
}
|
||||||
FloatBuffer buf = BufferUtils.createFloatBuffer(points.limit());
|
FloatBuffer buf = BufferUtils.createFloatBuffer(points.limit());
|
||||||
points.rewind();
|
points.rewind();
|
||||||
buf.put(points);
|
buf.put(points);
|
||||||
@ -216,43 +214,43 @@ public class BoundingSphere extends BoundingVolume {
|
|||||||
*/
|
*/
|
||||||
private void recurseMini(FloatBuffer points, int p, int b, int ap) {
|
private void recurseMini(FloatBuffer points, int p, int b, int ap) {
|
||||||
TempVars vars = TempVars.get();
|
TempVars vars = TempVars.get();
|
||||||
assert vars.lock();
|
|
||||||
Vector3f tempA = vars.vect1;
|
Vector3f tempA = vars.vect1;
|
||||||
Vector3f tempB = vars.vect2;
|
Vector3f tempB = vars.vect2;
|
||||||
Vector3f tempC = vars.vect3;
|
Vector3f tempC = vars.vect3;
|
||||||
Vector3f tempD = vars.vect4;
|
Vector3f tempD = vars.vect4;
|
||||||
|
|
||||||
switch (b) {
|
switch (b) {
|
||||||
case 0:
|
case 0:
|
||||||
this.radius = 0;
|
this.radius = 0;
|
||||||
this.center.set(0, 0, 0);
|
this.center.set(0, 0, 0);
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
this.radius = 1f - RADIUS_EPSILON;
|
this.radius = 1f - RADIUS_EPSILON;
|
||||||
BufferUtils.populateFromBuffer(center, points, ap-1);
|
BufferUtils.populateFromBuffer(center, points, ap - 1);
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
BufferUtils.populateFromBuffer(tempA, points, ap-1);
|
BufferUtils.populateFromBuffer(tempA, points, ap - 1);
|
||||||
BufferUtils.populateFromBuffer(tempB, points, ap-2);
|
BufferUtils.populateFromBuffer(tempB, points, ap - 2);
|
||||||
setSphere(tempA, tempB);
|
setSphere(tempA, tempB);
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
BufferUtils.populateFromBuffer(tempA, points, ap-1);
|
BufferUtils.populateFromBuffer(tempA, points, ap - 1);
|
||||||
BufferUtils.populateFromBuffer(tempB, points, ap-2);
|
BufferUtils.populateFromBuffer(tempB, points, ap - 2);
|
||||||
BufferUtils.populateFromBuffer(tempC, points, ap-3);
|
BufferUtils.populateFromBuffer(tempC, points, ap - 3);
|
||||||
setSphere(tempA, tempB, tempC);
|
setSphere(tempA, tempB, tempC);
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
BufferUtils.populateFromBuffer(tempA, points, ap-1);
|
BufferUtils.populateFromBuffer(tempA, points, ap - 1);
|
||||||
BufferUtils.populateFromBuffer(tempB, points, ap-2);
|
BufferUtils.populateFromBuffer(tempB, points, ap - 2);
|
||||||
BufferUtils.populateFromBuffer(tempC, points, ap-3);
|
BufferUtils.populateFromBuffer(tempC, points, ap - 3);
|
||||||
BufferUtils.populateFromBuffer(tempD, points, ap-4);
|
BufferUtils.populateFromBuffer(tempD, points, ap - 4);
|
||||||
setSphere(tempA, tempB, tempC, tempD);
|
setSphere(tempA, tempB, tempC, tempD);
|
||||||
assert vars.unlock();
|
vars.release();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
for (int i = 0; i < p; i++) {
|
for (int i = 0; i < p; i++) {
|
||||||
BufferUtils.populateFromBuffer(tempA, points, i+ap);
|
BufferUtils.populateFromBuffer(tempA, points, i + ap);
|
||||||
if (tempA.distanceSquared(center) - (radius * radius) > RADIUS_EPSILON - 1f) {
|
if (tempA.distanceSquared(center) - (radius * radius) > RADIUS_EPSILON - 1f) {
|
||||||
for (int j = i; j > 0; j--) {
|
for (int j = i; j > 0; j--) {
|
||||||
BufferUtils.populateFromBuffer(tempB, points, j + ap);
|
BufferUtils.populateFromBuffer(tempB, points, j + ap);
|
||||||
@ -260,12 +258,12 @@ public class BoundingSphere extends BoundingVolume {
|
|||||||
BufferUtils.setInBuffer(tempC, points, j + ap);
|
BufferUtils.setInBuffer(tempC, points, j + ap);
|
||||||
BufferUtils.setInBuffer(tempB, points, j - 1 + ap);
|
BufferUtils.setInBuffer(tempB, points, j - 1 + ap);
|
||||||
}
|
}
|
||||||
assert vars.unlock();
|
vars.release();
|
||||||
recurseMini(points, i, b + 1, ap + 1);
|
recurseMini(points, i, b + 1, ap + 1);
|
||||||
assert vars.lock();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
assert vars.unlock();
|
vars.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -327,9 +325,7 @@ public class BoundingSphere extends BoundingVolume {
|
|||||||
radius = 0;
|
radius = 0;
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
Vector3f o = acrossB.cross(a).multLocal(b.lengthSquared())
|
Vector3f o = acrossB.cross(a).multLocal(b.lengthSquared()).addLocal(b.cross(acrossB).multLocal(a.lengthSquared())).divideLocal(Denominator);
|
||||||
.addLocal(b.cross(acrossB).multLocal(a.lengthSquared()))
|
|
||||||
.divideLocal(Denominator);
|
|
||||||
radius = o.length() * RADIUS_EPSILON;
|
radius = o.length() * RADIUS_EPSILON;
|
||||||
O.add(o, center);
|
O.add(o, center);
|
||||||
}
|
}
|
||||||
@ -418,7 +414,7 @@ public class BoundingSphere extends BoundingVolume {
|
|||||||
}
|
}
|
||||||
|
|
||||||
trans.mult(center, sphere.center);
|
trans.mult(center, sphere.center);
|
||||||
Vector3f axes = new Vector3f(1,1,1);
|
Vector3f axes = new Vector3f(1, 1, 1);
|
||||||
trans.mult(axes, axes);
|
trans.mult(axes, axes);
|
||||||
float ax = getMaxAxis(axes);
|
float ax = getMaxAxis(axes);
|
||||||
sphere.radius = FastMath.abs(ax * radius) + RADIUS_EPSILON - 1f;
|
sphere.radius = FastMath.abs(ax * radius) + RADIUS_EPSILON - 1f;
|
||||||
@ -431,13 +427,15 @@ public class BoundingSphere extends BoundingVolume {
|
|||||||
float z = FastMath.abs(scale.z);
|
float z = FastMath.abs(scale.z);
|
||||||
|
|
||||||
if (x >= y) {
|
if (x >= y) {
|
||||||
if (x >= z)
|
if (x >= z) {
|
||||||
return x;
|
return x;
|
||||||
|
}
|
||||||
return z;
|
return z;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (y >= z)
|
if (y >= z) {
|
||||||
return y;
|
return y;
|
||||||
|
}
|
||||||
|
|
||||||
return z;
|
return z;
|
||||||
}
|
}
|
||||||
@ -475,24 +473,24 @@ public class BoundingSphere extends BoundingVolume {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(volume.getType()) {
|
switch (volume.getType()) {
|
||||||
|
|
||||||
case Sphere: {
|
case Sphere: {
|
||||||
BoundingSphere sphere = (BoundingSphere) volume;
|
BoundingSphere sphere = (BoundingSphere) volume;
|
||||||
float temp_radius = sphere.getRadius();
|
float temp_radius = sphere.getRadius();
|
||||||
Vector3f temp_center = sphere.center;
|
Vector3f temp_center = sphere.center;
|
||||||
BoundingSphere rVal = new BoundingSphere();
|
BoundingSphere rVal = new BoundingSphere();
|
||||||
return merge(temp_radius, temp_center, rVal);
|
return merge(temp_radius, temp_center, rVal);
|
||||||
}
|
}
|
||||||
|
|
||||||
case AABB: {
|
case AABB: {
|
||||||
BoundingBox box = (BoundingBox) volume;
|
BoundingBox box = (BoundingBox) volume;
|
||||||
Vector3f radVect = new Vector3f(box.xExtent, box.yExtent,
|
Vector3f radVect = new Vector3f(box.xExtent, box.yExtent,
|
||||||
box.zExtent);
|
box.zExtent);
|
||||||
Vector3f temp_center = box.center;
|
Vector3f temp_center = box.center;
|
||||||
BoundingSphere rVal = new BoundingSphere();
|
BoundingSphere rVal = new BoundingSphere();
|
||||||
return merge(radVect.length(), temp_center, rVal);
|
return merge(radVect.length(), temp_center, rVal);
|
||||||
}
|
}
|
||||||
|
|
||||||
// case OBB: {
|
// case OBB: {
|
||||||
// OrientedBoundingBox box = (OrientedBoundingBox) volume;
|
// OrientedBoundingBox box = (OrientedBoundingBox) volume;
|
||||||
@ -500,8 +498,8 @@ public class BoundingSphere extends BoundingVolume {
|
|||||||
// return rVal.mergeOBB(box);
|
// return rVal.mergeOBB(box);
|
||||||
// }
|
// }
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -522,30 +520,30 @@ public class BoundingSphere extends BoundingVolume {
|
|||||||
|
|
||||||
switch (volume.getType()) {
|
switch (volume.getType()) {
|
||||||
|
|
||||||
case Sphere: {
|
case Sphere: {
|
||||||
BoundingSphere sphere = (BoundingSphere) volume;
|
BoundingSphere sphere = (BoundingSphere) volume;
|
||||||
float temp_radius = sphere.getRadius();
|
float temp_radius = sphere.getRadius();
|
||||||
Vector3f temp_center = sphere.center;
|
Vector3f temp_center = sphere.center;
|
||||||
return merge(temp_radius, temp_center, this);
|
return merge(temp_radius, temp_center, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
case AABB: {
|
case AABB: {
|
||||||
BoundingBox box = (BoundingBox) volume;
|
BoundingBox box = (BoundingBox) volume;
|
||||||
assert TempVars.get().lock();
|
TempVars vars = TempVars.get();
|
||||||
Vector3f radVect = TempVars.get().vect1;
|
Vector3f radVect = vars.vect1;
|
||||||
radVect.set(box.xExtent, box.yExtent, box.zExtent);
|
radVect.set(box.xExtent, box.yExtent, box.zExtent);
|
||||||
Vector3f temp_center = box.center;
|
Vector3f temp_center = box.center;
|
||||||
float len = radVect.length();
|
float len = radVect.length();
|
||||||
assert TempVars.get().unlock();
|
vars.release();
|
||||||
return merge(len, temp_center, this);
|
return merge(len, temp_center, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
// case OBB: {
|
// case OBB: {
|
||||||
// return mergeOBB((OrientedBoundingBox) volume);
|
// return mergeOBB((OrientedBoundingBox) volume);
|
||||||
// }
|
// }
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -585,11 +583,10 @@ public class BoundingSphere extends BoundingVolume {
|
|||||||
//
|
//
|
||||||
// return this;
|
// return this;
|
||||||
// }
|
// }
|
||||||
|
|
||||||
private BoundingVolume merge(float temp_radius, Vector3f temp_center,
|
private BoundingVolume merge(float temp_radius, Vector3f temp_center,
|
||||||
BoundingSphere rVal) {
|
BoundingSphere rVal) {
|
||||||
TempVars vars = TempVars.get();
|
TempVars vars = TempVars.get();
|
||||||
assert vars.lock();
|
|
||||||
Vector3f diff = temp_center.subtract(center, vars.vect1);
|
Vector3f diff = temp_center.subtract(center, vars.vect1);
|
||||||
float lengthSquared = diff.lengthSquared();
|
float lengthSquared = diff.lengthSquared();
|
||||||
float radiusDiff = temp_radius - radius;
|
float radiusDiff = temp_radius - radius;
|
||||||
@ -598,25 +595,25 @@ public class BoundingSphere extends BoundingVolume {
|
|||||||
|
|
||||||
if (fRDiffSqr >= lengthSquared) {
|
if (fRDiffSqr >= lengthSquared) {
|
||||||
if (radiusDiff <= 0.0f) {
|
if (radiusDiff <= 0.0f) {
|
||||||
assert vars.unlock();
|
vars.release();
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector3f rCenter = rVal.center;
|
Vector3f rCenter = rVal.center;
|
||||||
if ( rCenter == null ) {
|
if (rCenter == null) {
|
||||||
rVal.setCenter( rCenter = new Vector3f() );
|
rVal.setCenter(rCenter = new Vector3f());
|
||||||
}
|
}
|
||||||
rCenter.set(temp_center);
|
rCenter.set(temp_center);
|
||||||
rVal.setRadius(temp_radius);
|
rVal.setRadius(temp_radius);
|
||||||
assert vars.unlock();
|
vars.release();
|
||||||
return rVal;
|
return rVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
float length = (float) Math.sqrt(lengthSquared);
|
float length = (float) Math.sqrt(lengthSquared);
|
||||||
|
|
||||||
Vector3f rCenter = rVal.center;
|
Vector3f rCenter = rVal.center;
|
||||||
if ( rCenter == null ) {
|
if (rCenter == null) {
|
||||||
rVal.setCenter( rCenter = new Vector3f() );
|
rVal.setCenter(rCenter = new Vector3f());
|
||||||
}
|
}
|
||||||
if (length > RADIUS_EPSILON) {
|
if (length > RADIUS_EPSILON) {
|
||||||
float coeff = (length + radiusDiff) / (2.0f * length);
|
float coeff = (length + radiusDiff) / (2.0f * length);
|
||||||
@ -626,7 +623,7 @@ public class BoundingSphere extends BoundingVolume {
|
|||||||
}
|
}
|
||||||
|
|
||||||
rVal.setRadius(0.5f * (length + radius + temp_radius));
|
rVal.setRadius(0.5f * (length + radius + temp_radius));
|
||||||
assert vars.unlock();
|
vars.release();
|
||||||
return rVal;
|
return rVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -652,7 +649,7 @@ public class BoundingSphere extends BoundingVolume {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return new BoundingSphere(radius,
|
return new BoundingSphere(radius,
|
||||||
(center != null ? (Vector3f) center.clone() : null));
|
(center != null ? (Vector3f) center.clone() : null));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -685,11 +682,11 @@ public class BoundingSphere extends BoundingVolume {
|
|||||||
assert Vector3f.isValidVector(center) && Vector3f.isValidVector(bs.center);
|
assert Vector3f.isValidVector(center) && Vector3f.isValidVector(bs.center);
|
||||||
|
|
||||||
TempVars vars = TempVars.get();
|
TempVars vars = TempVars.get();
|
||||||
assert vars.lock();
|
|
||||||
Vector3f diff = center.subtract(bs.center, vars.vect1);
|
Vector3f diff = center.subtract(bs.center, vars.vect1);
|
||||||
float rsum = getRadius() + bs.getRadius();
|
float rsum = getRadius() + bs.getRadius();
|
||||||
boolean eq = (diff.dot(diff) <= rsum * rsum);
|
boolean eq = (diff.dot(diff) <= rsum * rsum);
|
||||||
assert vars.unlock();
|
vars.release();
|
||||||
return eq;
|
return eq;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -704,10 +701,11 @@ public class BoundingSphere extends BoundingVolume {
|
|||||||
if (FastMath.abs(bb.center.x - center.x) < getRadius()
|
if (FastMath.abs(bb.center.x - center.x) < getRadius()
|
||||||
+ bb.xExtent
|
+ bb.xExtent
|
||||||
&& FastMath.abs(bb.center.y - center.y) < getRadius()
|
&& FastMath.abs(bb.center.y - center.y) < getRadius()
|
||||||
+ bb.yExtent
|
+ bb.yExtent
|
||||||
&& FastMath.abs(bb.center.z - center.z) < getRadius()
|
&& FastMath.abs(bb.center.z - center.z) < getRadius()
|
||||||
+ bb.zExtent)
|
+ bb.zExtent) {
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -730,9 +728,8 @@ public class BoundingSphere extends BoundingVolume {
|
|||||||
assert Vector3f.isValidVector(center);
|
assert Vector3f.isValidVector(center);
|
||||||
|
|
||||||
TempVars vars = TempVars.get();
|
TempVars vars = TempVars.get();
|
||||||
assert vars.lock();
|
|
||||||
Vector3f diff = vars.vect1.set(ray.getOrigin())
|
Vector3f diff = vars.vect1.set(ray.getOrigin()).subtractLocal(center);
|
||||||
.subtractLocal(center);
|
|
||||||
float radiusSquared = getRadius() * getRadius();
|
float radiusSquared = getRadius() * getRadius();
|
||||||
float a = diff.dot(diff) - radiusSquared;
|
float a = diff.dot(diff) - radiusSquared;
|
||||||
if (a <= 0.0) {
|
if (a <= 0.0) {
|
||||||
@ -742,11 +739,11 @@ public class BoundingSphere extends BoundingVolume {
|
|||||||
|
|
||||||
// outside sphere
|
// outside sphere
|
||||||
float b = ray.getDirection().dot(diff);
|
float b = ray.getDirection().dot(diff);
|
||||||
assert vars.unlock();
|
vars.release();
|
||||||
if (b >= 0.0) {
|
if (b >= 0.0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return b*b >= a;
|
return b * b >= a;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -756,10 +753,10 @@ public class BoundingSphere extends BoundingVolume {
|
|||||||
*/
|
*/
|
||||||
public int collideWithRay(Ray ray, CollisionResults results) {
|
public int collideWithRay(Ray ray, CollisionResults results) {
|
||||||
TempVars vars = TempVars.get();
|
TempVars vars = TempVars.get();
|
||||||
assert vars.lock();
|
|
||||||
Vector3f diff = vars.vect1.set(ray.getOrigin()).subtractLocal(
|
Vector3f diff = vars.vect1.set(ray.getOrigin()).subtractLocal(
|
||||||
center);
|
center);
|
||||||
float a = diff.dot(diff) - (getRadius()*getRadius());
|
float a = diff.dot(diff) - (getRadius() * getRadius());
|
||||||
float a1, discr, root;
|
float a1, discr, root;
|
||||||
if (a <= 0.0) {
|
if (a <= 0.0) {
|
||||||
// inside sphere
|
// inside sphere
|
||||||
@ -776,16 +773,15 @@ public class BoundingSphere extends BoundingVolume {
|
|||||||
}
|
}
|
||||||
|
|
||||||
a1 = ray.direction.dot(diff);
|
a1 = ray.direction.dot(diff);
|
||||||
assert vars.unlock();
|
vars.release();
|
||||||
if (a1 >= 0.0) {
|
if (a1 >= 0.0) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
discr = a1*a1 - a;
|
discr = a1 * a1 - a;
|
||||||
if (discr < 0.0)
|
if (discr < 0.0) {
|
||||||
return 0;
|
return 0;
|
||||||
|
} else if (discr >= FastMath.ZERO_TOLERANCE) {
|
||||||
else if (discr >= FastMath.ZERO_TOLERANCE) {
|
|
||||||
root = FastMath.sqrt(discr);
|
root = FastMath.sqrt(discr);
|
||||||
float dist = -a1 - root;
|
float dist = -a1 - root;
|
||||||
Vector3f point = new Vector3f(ray.direction).multLocal(dist).addLocal(ray.origin);
|
Vector3f point = new Vector3f(ray.direction).multLocal(dist).addLocal(ray.origin);
|
||||||
@ -803,11 +799,11 @@ public class BoundingSphere extends BoundingVolume {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public int collideWith(Collidable other, CollisionResults results){
|
public int collideWith(Collidable other, CollisionResults results) {
|
||||||
if (other instanceof Ray){
|
if (other instanceof Ray) {
|
||||||
Ray ray = (Ray) other;
|
Ray ray = (Ray) other;
|
||||||
return collideWithRay(ray, results);
|
return collideWithRay(ray, results);
|
||||||
}else{
|
} else {
|
||||||
throw new UnsupportedCollisionException();
|
throw new UnsupportedCollisionException();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -29,7 +29,6 @@
|
|||||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.jme3.bounding;
|
package com.jme3.bounding;
|
||||||
|
|
||||||
import com.jme3.util.TempVars;
|
import com.jme3.util.TempVars;
|
||||||
@ -47,16 +46,23 @@ import static java.lang.Math.max;
|
|||||||
*/
|
*/
|
||||||
public class Intersection {
|
public class Intersection {
|
||||||
|
|
||||||
private static final void findMinMax(float x0, float x1, float x2, Vector3f minMax){
|
private static final void findMinMax(float x0, float x1, float x2, Vector3f minMax) {
|
||||||
minMax.set(x0, x0, 0);
|
minMax.set(x0, x0, 0);
|
||||||
if (x1 < minMax.x) minMax.setX(x1);
|
if (x1 < minMax.x) {
|
||||||
if (x1 > minMax.y) minMax.setY(x1);
|
minMax.setX(x1);
|
||||||
if (x2 < minMax.x) minMax.setX(x2);
|
}
|
||||||
if (x2 > minMax.y) minMax.setY(x2);
|
if (x1 > minMax.y) {
|
||||||
|
minMax.setY(x1);
|
||||||
|
}
|
||||||
|
if (x2 < minMax.x) {
|
||||||
|
minMax.setX(x2);
|
||||||
|
}
|
||||||
|
if (x2 > minMax.y) {
|
||||||
|
minMax.setY(x2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// private boolean axisTest(float a, float b, float fa, float fb, Vector3f v0, Vector3f v1, )
|
// private boolean axisTest(float a, float b, float fa, float fb, Vector3f v0, Vector3f v1, )
|
||||||
|
|
||||||
// private boolean axisTestX01(float a, float b, float fa, float fb,
|
// private boolean axisTestX01(float a, float b, float fa, float fb,
|
||||||
// Vector3f center, Vector3f ext,
|
// Vector3f center, Vector3f ext,
|
||||||
// Vector3f v1, Vector3f v2, Vector3f v3){
|
// Vector3f v1, Vector3f v2, Vector3f v3){
|
||||||
@ -73,188 +79,187 @@ public class Intersection {
|
|||||||
// if(min > rad || max < -rad)
|
// if(min > rad || max < -rad)
|
||||||
// return false;
|
// return false;
|
||||||
// }
|
// }
|
||||||
|
public static boolean intersect(BoundingBox bbox, Vector3f v1, Vector3f v2, Vector3f v3) {
|
||||||
public static boolean intersect(BoundingBox bbox, Vector3f v1, Vector3f v2, Vector3f v3){
|
|
||||||
// use separating axis theorem to test overlap between triangle and box
|
// use separating axis theorem to test overlap between triangle and box
|
||||||
// need to test for overlap in these directions:
|
// need to test for overlap in these directions:
|
||||||
// 1) the {x,y,z}-directions (actually, since we use the AABB of the triangle
|
// 1) the {x,y,z}-directions (actually, since we use the AABB of the triangle
|
||||||
// we do not even need to test these)
|
// we do not even need to test these)
|
||||||
// 2) normal of the triangle
|
// 2) normal of the triangle
|
||||||
// 3) crossproduct(edge from tri, {x,y,z}-directin)
|
// 3) crossproduct(edge from tri, {x,y,z}-directin)
|
||||||
// this gives 3x3=9 more tests
|
// this gives 3x3=9 more tests
|
||||||
|
|
||||||
TempVars vars = TempVars.get();
|
TempVars vars = TempVars.get();
|
||||||
assert vars.lock();
|
|
||||||
|
|
||||||
Vector3f tmp0 = vars.vect1,
|
|
||||||
|
Vector3f tmp0 = vars.vect1,
|
||||||
tmp1 = vars.vect2,
|
tmp1 = vars.vect2,
|
||||||
tmp2 = vars.vect3;
|
tmp2 = vars.vect3;
|
||||||
|
|
||||||
Vector3f e0 = vars.vect4,
|
Vector3f e0 = vars.vect4,
|
||||||
e1 = vars.vect5,
|
e1 = vars.vect5,
|
||||||
e2 = vars.vect6;
|
e2 = vars.vect6;
|
||||||
|
|
||||||
Vector3f center = bbox.getCenter();
|
Vector3f center = bbox.getCenter();
|
||||||
Vector3f extent = bbox.getExtent(null);
|
Vector3f extent = bbox.getExtent(null);
|
||||||
|
|
||||||
// float min,max,p0,p1,p2,rad,fex,fey,fez;
|
// float min,max,p0,p1,p2,rad,fex,fey,fez;
|
||||||
// float normal[3]
|
// float normal[3]
|
||||||
|
|
||||||
// This is the fastest branch on Sun
|
// This is the fastest branch on Sun
|
||||||
// move everything so that the boxcenter is in (0,0,0)
|
// move everything so that the boxcenter is in (0,0,0)
|
||||||
v1.subtract(center, tmp0);
|
v1.subtract(center, tmp0);
|
||||||
v2.subtract(center, tmp1);
|
v2.subtract(center, tmp1);
|
||||||
v3.subtract(center, tmp2);
|
v3.subtract(center, tmp2);
|
||||||
|
|
||||||
// compute triangle edges
|
// compute triangle edges
|
||||||
tmp1.subtract(tmp0, e0); // tri edge 0
|
tmp1.subtract(tmp0, e0); // tri edge 0
|
||||||
tmp2.subtract(tmp1, e1); // tri edge 1
|
tmp2.subtract(tmp1, e1); // tri edge 1
|
||||||
tmp0.subtract(tmp2, e2); // tri edge 2
|
tmp0.subtract(tmp2, e2); // tri edge 2
|
||||||
|
|
||||||
// Bullet 3:
|
// Bullet 3:
|
||||||
// test the 9 tests first (this was faster)
|
// test the 9 tests first (this was faster)
|
||||||
float min, max;
|
float min, max;
|
||||||
float p0, p1, p2, rad;
|
float p0, p1, p2, rad;
|
||||||
float fex = FastMath.abs(e0.x);
|
float fex = FastMath.abs(e0.x);
|
||||||
float fey = FastMath.abs(e0.y);
|
float fey = FastMath.abs(e0.y);
|
||||||
float fez = FastMath.abs(e0.z);
|
float fez = FastMath.abs(e0.z);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//AXISTEST_X01(e0[Z], e0[Y], fez, fey);
|
//AXISTEST_X01(e0[Z], e0[Y], fez, fey);
|
||||||
p0 = e0.z * tmp0.y - e0.y * tmp0.z;
|
p0 = e0.z * tmp0.y - e0.y * tmp0.z;
|
||||||
p2 = e0.z * tmp2.y - e0.y * tmp2.z;
|
p2 = e0.z * tmp2.y - e0.y * tmp2.z;
|
||||||
min = min(p0,p2);
|
min = min(p0, p2);
|
||||||
max = max(p0,p2);
|
max = max(p0, p2);
|
||||||
rad = fez * extent.y + fey * extent.z;
|
rad = fez * extent.y + fey * extent.z;
|
||||||
if (min > rad || max < -rad){
|
if (min > rad || max < -rad) {
|
||||||
assert vars.unlock();
|
vars.release();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// AXISTEST_Y02(e0[Z], e0[X], fez, fex);
|
// AXISTEST_Y02(e0[Z], e0[X], fez, fex);
|
||||||
p0 = -e0.z * tmp0.x + e0.x * tmp0.z;
|
p0 = -e0.z * tmp0.x + e0.x * tmp0.z;
|
||||||
p2 = -e0.z * tmp2.x + e0.x * tmp2.z;
|
p2 = -e0.z * tmp2.x + e0.x * tmp2.z;
|
||||||
min = min(p0,p2);
|
min = min(p0, p2);
|
||||||
max = max(p0,p2);
|
max = max(p0, p2);
|
||||||
rad = fez * extent.x + fex * extent.z;
|
rad = fez * extent.x + fex * extent.z;
|
||||||
if (min > rad || max < -rad){
|
if (min > rad || max < -rad) {
|
||||||
assert vars.unlock();
|
vars.release();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// AXISTEST_Z12(e0[Y], e0[X], fey, fex);
|
// AXISTEST_Z12(e0[Y], e0[X], fey, fex);
|
||||||
p1 = e0.y * tmp1.x - e0.x * tmp1.y;
|
p1 = e0.y * tmp1.x - e0.x * tmp1.y;
|
||||||
p2 = e0.y * tmp2.x - e0.x * tmp2.y;
|
p2 = e0.y * tmp2.x - e0.x * tmp2.y;
|
||||||
min = min(p1,p2);
|
min = min(p1, p2);
|
||||||
max = max(p1,p2);
|
max = max(p1, p2);
|
||||||
rad = fey * extent.x + fex * extent.y;
|
rad = fey * extent.x + fex * extent.y;
|
||||||
if (min > rad || max < -rad){
|
if (min > rad || max < -rad) {
|
||||||
assert vars.unlock();
|
vars.release();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
fex = FastMath.abs(e1.x);
|
fex = FastMath.abs(e1.x);
|
||||||
fey = FastMath.abs(e1.y);
|
fey = FastMath.abs(e1.y);
|
||||||
fez = FastMath.abs(e1.z);
|
fez = FastMath.abs(e1.z);
|
||||||
|
|
||||||
// AXISTEST_X01(e1[Z], e1[Y], fez, fey);
|
// AXISTEST_X01(e1[Z], e1[Y], fez, fey);
|
||||||
p0 = e1.z * tmp0.y - e1.y * tmp0.z;
|
p0 = e1.z * tmp0.y - e1.y * tmp0.z;
|
||||||
p2 = e1.z * tmp2.y - e1.y * tmp2.z;
|
p2 = e1.z * tmp2.y - e1.y * tmp2.z;
|
||||||
min = min(p0,p2);
|
min = min(p0, p2);
|
||||||
max = max(p0,p2);
|
max = max(p0, p2);
|
||||||
rad = fez * extent.y + fey * extent.z;
|
rad = fez * extent.y + fey * extent.z;
|
||||||
if (min > rad || max < -rad){
|
if (min > rad || max < -rad) {
|
||||||
assert vars.unlock();
|
vars.release();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// AXISTEST_Y02(e1[Z], e1[X], fez, fex);
|
// AXISTEST_Y02(e1[Z], e1[X], fez, fex);
|
||||||
p0 = -e1.z * tmp0.x + e1.x * tmp0.z;
|
p0 = -e1.z * tmp0.x + e1.x * tmp0.z;
|
||||||
p2 = -e1.z * tmp2.x + e1.x * tmp2.z;
|
p2 = -e1.z * tmp2.x + e1.x * tmp2.z;
|
||||||
min = min(p0,p2);
|
min = min(p0, p2);
|
||||||
max = max(p0,p2);
|
max = max(p0, p2);
|
||||||
rad = fez * extent.x + fex * extent.z;
|
rad = fez * extent.x + fex * extent.z;
|
||||||
if (min > rad || max < -rad){
|
if (min > rad || max < -rad) {
|
||||||
assert vars.unlock();
|
vars.release();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// AXISTEST_Z0(e1[Y], e1[X], fey, fex);
|
// AXISTEST_Z0(e1[Y], e1[X], fey, fex);
|
||||||
p0 = e1.y * tmp0.x - e1.x * tmp0.y;
|
p0 = e1.y * tmp0.x - e1.x * tmp0.y;
|
||||||
p1 = e1.y * tmp1.x - e1.x * tmp1.y;
|
p1 = e1.y * tmp1.x - e1.x * tmp1.y;
|
||||||
min = min(p0,p1);
|
min = min(p0, p1);
|
||||||
max = max(p0,p1);
|
max = max(p0, p1);
|
||||||
rad = fey * extent.x + fex * extent.y;
|
rad = fey * extent.x + fex * extent.y;
|
||||||
if (min > rad || max < -rad){
|
if (min > rad || max < -rad) {
|
||||||
assert vars.unlock();
|
vars.release();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
fex = FastMath.abs(e2.x);
|
fex = FastMath.abs(e2.x);
|
||||||
fey = FastMath.abs(e2.y);
|
fey = FastMath.abs(e2.y);
|
||||||
fez = FastMath.abs(e2.z);
|
fez = FastMath.abs(e2.z);
|
||||||
|
|
||||||
// AXISTEST_X2(e2[Z], e2[Y], fez, fey);
|
// AXISTEST_X2(e2[Z], e2[Y], fez, fey);
|
||||||
p0 = e2.z * tmp0.y - e2.y * tmp0.z;
|
p0 = e2.z * tmp0.y - e2.y * tmp0.z;
|
||||||
p1 = e2.z * tmp1.y - e2.y * tmp1.z;
|
p1 = e2.z * tmp1.y - e2.y * tmp1.z;
|
||||||
min = min(p0,p1);
|
min = min(p0, p1);
|
||||||
max = max(p0,p1);
|
max = max(p0, p1);
|
||||||
rad = fez * extent.y + fey * extent.z;
|
rad = fez * extent.y + fey * extent.z;
|
||||||
if (min > rad || max < -rad){
|
if (min > rad || max < -rad) {
|
||||||
assert vars.unlock();
|
vars.release();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// AXISTEST_Y1(e2[Z], e2[X], fez, fex);
|
// AXISTEST_Y1(e2[Z], e2[X], fez, fex);
|
||||||
p0 = -e2.z * tmp0.x + e2.x * tmp0.z;
|
p0 = -e2.z * tmp0.x + e2.x * tmp0.z;
|
||||||
p1 = -e2.z * tmp1.x + e2.x * tmp1.z;
|
p1 = -e2.z * tmp1.x + e2.x * tmp1.z;
|
||||||
min = min(p0,p1);
|
min = min(p0, p1);
|
||||||
max = max(p0,p1);
|
max = max(p0, p1);
|
||||||
rad = fez * extent.x + fex * extent.y;
|
rad = fez * extent.x + fex * extent.y;
|
||||||
if (min > rad || max < -rad){
|
if (min > rad || max < -rad) {
|
||||||
assert vars.unlock();
|
vars.release();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// AXISTEST_Z12(e2[Y], e2[X], fey, fex);
|
// AXISTEST_Z12(e2[Y], e2[X], fey, fex);
|
||||||
p1 = e2.y * tmp1.x - e2.x * tmp1.y;
|
p1 = e2.y * tmp1.x - e2.x * tmp1.y;
|
||||||
p2 = e2.y * tmp2.x - e2.x * tmp2.y;
|
p2 = e2.y * tmp2.x - e2.x * tmp2.y;
|
||||||
min = min(p1,p2);
|
min = min(p1, p2);
|
||||||
max = max(p1,p2);
|
max = max(p1, p2);
|
||||||
rad = fey * extent.x + fex * extent.y;
|
rad = fey * extent.x + fex * extent.y;
|
||||||
if (min > rad || max < -rad){
|
if (min > rad || max < -rad) {
|
||||||
assert vars.unlock();
|
vars.release();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bullet 1:
|
// Bullet 1:
|
||||||
// first test overlap in the {x,y,z}-directions
|
// first test overlap in the {x,y,z}-directions
|
||||||
// find min, max of the triangle each direction, and test for overlap in
|
// find min, max of the triangle each direction, and test for overlap in
|
||||||
// that direction -- this is equivalent to testing a minimal AABB around
|
// that direction -- this is equivalent to testing a minimal AABB around
|
||||||
// the triangle against the AABB
|
// the triangle against the AABB
|
||||||
|
|
||||||
|
|
||||||
Vector3f minMax = vars.vect7;
|
Vector3f minMax = vars.vect7;
|
||||||
|
|
||||||
// test in X-direction
|
// test in X-direction
|
||||||
findMinMax(tmp0.x, tmp1.x, tmp2.x, minMax);
|
findMinMax(tmp0.x, tmp1.x, tmp2.x, minMax);
|
||||||
if(minMax.x > extent.x || minMax.y < -extent.x){
|
if (minMax.x > extent.x || minMax.y < -extent.x) {
|
||||||
assert vars.unlock();
|
vars.release();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// test in Y-direction
|
// test in Y-direction
|
||||||
findMinMax(tmp0.y, tmp1.y, tmp2.y, minMax);
|
findMinMax(tmp0.y, tmp1.y, tmp2.y, minMax);
|
||||||
if(minMax.x > extent.y || minMax.y < -extent.y){
|
if (minMax.x > extent.y || minMax.y < -extent.y) {
|
||||||
assert vars.unlock();
|
vars.release();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// test in Z-direction
|
// test in Z-direction
|
||||||
findMinMax(tmp0.z, tmp1.z, tmp2.z, minMax);
|
findMinMax(tmp0.z, tmp1.z, tmp2.z, minMax);
|
||||||
if(minMax.x > extent.z || minMax.y < -extent.z){
|
if (minMax.x > extent.z || minMax.y < -extent.z) {
|
||||||
assert vars.unlock();
|
vars.release();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -263,19 +268,18 @@ public class Intersection {
|
|||||||
// // compute plane equation of triangle: normal * x + d = 0
|
// // compute plane equation of triangle: normal * x + d = 0
|
||||||
// Vector3f normal = new Vector3f();
|
// Vector3f normal = new Vector3f();
|
||||||
// e0.cross(e1, normal);
|
// e0.cross(e1, normal);
|
||||||
Plane p = vars.plane;
|
Plane p = vars.plane;
|
||||||
|
|
||||||
p.setPlanePoints(v1,v2,v3);
|
p.setPlanePoints(v1, v2, v3);
|
||||||
if (bbox.whichSide(p) == Plane.Side.Negative){
|
if (bbox.whichSide(p) == Plane.Side.Negative) {
|
||||||
assert vars.unlock();
|
vars.release();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
// if(!planeBoxOverlap(normal,v0,boxhalfsize)) return false;
|
// if(!planeBoxOverlap(normal,v0,boxhalfsize)) return false;
|
||||||
|
|
||||||
assert vars.unlock();
|
vars.release();
|
||||||
|
|
||||||
return true; /* box and triangle overlaps */
|
return true; /* box and triangle overlaps */
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -29,7 +29,6 @@
|
|||||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.jme3.collision.bih;
|
package com.jme3.collision.bih;
|
||||||
|
|
||||||
import com.jme3.bounding.BoundingBox;
|
import com.jme3.bounding.BoundingBox;
|
||||||
@ -62,24 +61,23 @@ import static java.lang.Math.max;
|
|||||||
public final class BIHNode implements Savable {
|
public final class BIHNode implements Savable {
|
||||||
|
|
||||||
private int leftIndex, rightIndex;
|
private int leftIndex, rightIndex;
|
||||||
|
|
||||||
private BIHNode left;
|
private BIHNode left;
|
||||||
private BIHNode right;
|
private BIHNode right;
|
||||||
private float leftPlane;
|
private float leftPlane;
|
||||||
private float rightPlane;
|
private float rightPlane;
|
||||||
private int axis;
|
private int axis;
|
||||||
|
|
||||||
public BIHNode(int l, int r){
|
public BIHNode(int l, int r) {
|
||||||
leftIndex = l;
|
leftIndex = l;
|
||||||
rightIndex = r;
|
rightIndex = r;
|
||||||
axis = 3; // indicates leaf
|
axis = 3; // indicates leaf
|
||||||
}
|
}
|
||||||
|
|
||||||
public BIHNode(int axis){
|
public BIHNode(int axis) {
|
||||||
this.axis = axis;
|
this.axis = axis;
|
||||||
}
|
}
|
||||||
|
|
||||||
public BIHNode(){
|
public BIHNode() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public BIHNode getLeftChild() {
|
public BIHNode getLeftChild() {
|
||||||
@ -116,7 +114,7 @@ public final class BIHNode implements Savable {
|
|||||||
|
|
||||||
public void write(JmeExporter ex) throws IOException {
|
public void write(JmeExporter ex) throws IOException {
|
||||||
OutputCapsule oc = ex.getCapsule(this);
|
OutputCapsule oc = ex.getCapsule(this);
|
||||||
oc.write(leftIndex, "left_index", 0);
|
oc.write(leftIndex, "left_index", 0);
|
||||||
oc.write(rightIndex, "right_index", 0);
|
oc.write(rightIndex, "right_index", 0);
|
||||||
oc.write(leftPlane, "left_plane", 0);
|
oc.write(leftPlane, "left_plane", 0);
|
||||||
oc.write(rightPlane, "right_plane", 0);
|
oc.write(rightPlane, "right_plane", 0);
|
||||||
@ -146,53 +144,55 @@ public final class BIHNode implements Savable {
|
|||||||
this.min = min;
|
this.min = min;
|
||||||
this.max = max;
|
this.max = max;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public final int intersectWhere(Collidable col,
|
public final int intersectWhere(Collidable col,
|
||||||
BoundingBox box,
|
BoundingBox box,
|
||||||
Matrix4f worldMatrix,
|
Matrix4f worldMatrix,
|
||||||
BIHTree tree,
|
BIHTree tree,
|
||||||
CollisionResults results){
|
CollisionResults results) {
|
||||||
|
|
||||||
ArrayList<BIHStackData> stack = TempVars.get().bihStack;
|
TempVars vars = TempVars.get();
|
||||||
|
ArrayList<BIHStackData> stack = vars.bihStack;
|
||||||
stack.clear();
|
stack.clear();
|
||||||
|
|
||||||
float[] minExts = { box.getCenter().x - box.getXExtent(),
|
float[] minExts = {box.getCenter().x - box.getXExtent(),
|
||||||
box.getCenter().y - box.getYExtent(),
|
box.getCenter().y - box.getYExtent(),
|
||||||
box.getCenter().z - box.getZExtent() };
|
box.getCenter().z - box.getZExtent()};
|
||||||
|
|
||||||
float[] maxExts = { box.getCenter().x + box.getXExtent(),
|
float[] maxExts = {box.getCenter().x + box.getXExtent(),
|
||||||
box.getCenter().y + box.getYExtent(),
|
box.getCenter().y + box.getYExtent(),
|
||||||
box.getCenter().z + box.getZExtent() };
|
box.getCenter().z + box.getZExtent()};
|
||||||
|
|
||||||
stack.add(new BIHStackData(this, 0,0));
|
stack.add(new BIHStackData(this, 0, 0));
|
||||||
|
|
||||||
Triangle t = new Triangle();
|
Triangle t = new Triangle();
|
||||||
int cols = 0;
|
int cols = 0;
|
||||||
|
|
||||||
stackloop: while (stack.size() > 0){
|
stackloop:
|
||||||
BIHNode node = stack.remove(stack.size()-1).node;
|
while (stack.size() > 0) {
|
||||||
|
BIHNode node = stack.remove(stack.size() - 1).node;
|
||||||
|
|
||||||
while (node.axis != 3){
|
while (node.axis != 3) {
|
||||||
int a = node.axis;
|
int a = node.axis;
|
||||||
|
|
||||||
float maxExt = maxExts[a];
|
float maxExt = maxExts[a];
|
||||||
float minExt = minExts[a];
|
float minExt = minExts[a];
|
||||||
|
|
||||||
if (node.leftPlane < node.rightPlane){
|
if (node.leftPlane < node.rightPlane) {
|
||||||
// means there's a gap in the middle
|
// means there's a gap in the middle
|
||||||
// if the box is in that gap, we stop there
|
// if the box is in that gap, we stop there
|
||||||
if (minExt > node.leftPlane
|
if (minExt > node.leftPlane
|
||||||
&& maxExt < node.rightPlane)
|
&& maxExt < node.rightPlane) {
|
||||||
continue stackloop;
|
continue stackloop;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (maxExt < node.rightPlane){
|
if (maxExt < node.rightPlane) {
|
||||||
node = node.left;
|
node = node.left;
|
||||||
}else if (minExt > node.leftPlane){
|
} else if (minExt > node.leftPlane) {
|
||||||
node = node.right;
|
node = node.right;
|
||||||
}else{
|
} else {
|
||||||
stack.add(new BIHStackData(node.right, 0, 0));
|
stack.add(new BIHStackData(node.right, 0, 0));
|
||||||
node = node.left;
|
node = node.left;
|
||||||
}
|
}
|
||||||
@ -207,9 +207,9 @@ public final class BIHNode implements Savable {
|
|||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = node.leftIndex; i <= node.rightIndex; i++){
|
for (int i = node.leftIndex; i <= node.rightIndex; i++) {
|
||||||
tree.getTriangle(i, t.get1(), t.get2(), t.get3());
|
tree.getTriangle(i, t.get1(), t.get2(), t.get3());
|
||||||
if (worldMatrix != null){
|
if (worldMatrix != null) {
|
||||||
worldMatrix.mult(t.get1(), t.get1());
|
worldMatrix.mult(t.get1(), t.get1());
|
||||||
worldMatrix.mult(t.get2(), t.get2());
|
worldMatrix.mult(t.get2(), t.get2());
|
||||||
worldMatrix.mult(t.get3(), t.get3());
|
worldMatrix.mult(t.get3(), t.get3());
|
||||||
@ -217,11 +217,11 @@ public final class BIHNode implements Savable {
|
|||||||
|
|
||||||
int added = col.collideWith(t, results);
|
int added = col.collideWith(t, results);
|
||||||
|
|
||||||
if (added > 0){
|
if (added > 0) {
|
||||||
int index = tree.getTriangleIndex(i);
|
int index = tree.getTriangleIndex(i);
|
||||||
int start = results.size() - added;
|
int start = results.size() - added;
|
||||||
|
|
||||||
for (int j = start; j < results.size(); j++){
|
for (int j = start; j < results.size(); j++) {
|
||||||
CollisionResult cr = results.getCollisionDirect(j);
|
CollisionResult cr = results.getCollisionDirect(j);
|
||||||
cr.setTriangleIndex(index);
|
cr.setTriangleIndex(index);
|
||||||
}
|
}
|
||||||
@ -230,76 +230,78 @@ public final class BIHNode implements Savable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
vars.release();
|
||||||
return cols;
|
return cols;
|
||||||
}
|
}
|
||||||
|
|
||||||
public final int intersectBrute(Ray r,
|
public final int intersectBrute(Ray r,
|
||||||
Matrix4f worldMatrix,
|
Matrix4f worldMatrix,
|
||||||
BIHTree tree,
|
BIHTree tree,
|
||||||
float sceneMin,
|
float sceneMin,
|
||||||
float sceneMax,
|
float sceneMax,
|
||||||
CollisionResults results){
|
CollisionResults results) {
|
||||||
float tHit = Float.POSITIVE_INFINITY;
|
float tHit = Float.POSITIVE_INFINITY;
|
||||||
|
|
||||||
Vector3f v1 = new Vector3f(),
|
Vector3f v1 = new Vector3f(),
|
||||||
v2 = new Vector3f(),
|
v2 = new Vector3f(),
|
||||||
v3 = new Vector3f();
|
v3 = new Vector3f();
|
||||||
|
|
||||||
int cols = 0;
|
int cols = 0;
|
||||||
|
|
||||||
ArrayList<BIHStackData> stack = TempVars.get().bihStack;
|
TempVars vars = TempVars.get();
|
||||||
|
ArrayList<BIHStackData> stack = vars.bihStack;
|
||||||
stack.clear();
|
stack.clear();
|
||||||
stack.add(new BIHStackData(this, 0, 0));
|
stack.add(new BIHStackData(this, 0, 0));
|
||||||
stackloop: while (stack.size() > 0){
|
stackloop:
|
||||||
|
while (stack.size() > 0) {
|
||||||
|
|
||||||
BIHStackData data = stack.remove(stack.size()-1);
|
BIHStackData data = stack.remove(stack.size() - 1);
|
||||||
BIHNode node = data.node;
|
BIHNode node = data.node;
|
||||||
|
|
||||||
leafloop: while (node.axis != 3){ // while node is not a leaf
|
leafloop:
|
||||||
|
while (node.axis != 3) { // while node is not a leaf
|
||||||
BIHNode nearNode, farNode;
|
BIHNode nearNode, farNode;
|
||||||
nearNode = node.left;
|
nearNode = node.left;
|
||||||
farNode = node.right;
|
farNode = node.right;
|
||||||
|
|
||||||
stack.add(new BIHStackData(farNode, 0, 0));
|
stack.add(new BIHStackData(farNode, 0, 0));
|
||||||
node = nearNode;
|
node = nearNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
// a leaf
|
// a leaf
|
||||||
for (int i = node.leftIndex; i <= node.rightIndex; i++){
|
for (int i = node.leftIndex; i <= node.rightIndex; i++) {
|
||||||
tree.getTriangle(i, v1,v2,v3);
|
tree.getTriangle(i, v1, v2, v3);
|
||||||
|
|
||||||
if (worldMatrix != null){
|
if (worldMatrix != null) {
|
||||||
worldMatrix.mult(v1, v1);
|
worldMatrix.mult(v1, v1);
|
||||||
worldMatrix.mult(v2, v2);
|
worldMatrix.mult(v2, v2);
|
||||||
worldMatrix.mult(v3, v3);
|
worldMatrix.mult(v3, v3);
|
||||||
}
|
}
|
||||||
|
|
||||||
float t = r.intersects(v1,v2,v3);
|
float t = r.intersects(v1, v2, v3);
|
||||||
if (t < tHit){
|
if (t < tHit) {
|
||||||
tHit = t;
|
tHit = t;
|
||||||
Vector3f contactPoint = new Vector3f(r.direction)
|
Vector3f contactPoint = new Vector3f(r.direction).multLocal(tHit).addLocal(r.origin);
|
||||||
.multLocal(tHit)
|
|
||||||
.addLocal(r.origin);
|
|
||||||
CollisionResult cr = new CollisionResult(contactPoint, tHit);
|
CollisionResult cr = new CollisionResult(contactPoint, tHit);
|
||||||
cr.setTriangleIndex(tree.getTriangleIndex(i));
|
cr.setTriangleIndex(tree.getTriangleIndex(i));
|
||||||
results.addCollision(cr);
|
results.addCollision(cr);
|
||||||
cols ++;
|
cols++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
vars.release();
|
||||||
return cols;
|
return cols;
|
||||||
}
|
}
|
||||||
|
|
||||||
public final int intersectWhere(Ray r,
|
public final int intersectWhere(Ray r,
|
||||||
Matrix4f worldMatrix,
|
Matrix4f worldMatrix,
|
||||||
BIHTree tree,
|
BIHTree tree,
|
||||||
float sceneMin,
|
float sceneMin,
|
||||||
float sceneMax,
|
float sceneMax,
|
||||||
CollisionResults results){
|
CollisionResults results) {
|
||||||
|
|
||||||
ArrayList<BIHStackData> stack = TempVars.get().bihStack;
|
TempVars vars = TempVars.get();
|
||||||
|
ArrayList<BIHStackData> stack = vars.bihStack;
|
||||||
stack.clear();
|
stack.clear();
|
||||||
|
|
||||||
// float tHit = Float.POSITIVE_INFINITY;
|
// float tHit = Float.POSITIVE_INFINITY;
|
||||||
@ -315,33 +317,36 @@ public final class BIHNode implements Savable {
|
|||||||
inv.multNormal(r.getDirection(), r.getDirection());
|
inv.multNormal(r.getDirection(), r.getDirection());
|
||||||
// inv.multNormalAcross(r.getDirection(), r.getDirection());
|
// inv.multNormalAcross(r.getDirection(), r.getDirection());
|
||||||
|
|
||||||
float[] origins = { r.getOrigin().x,
|
float[] origins = {r.getOrigin().x,
|
||||||
r.getOrigin().y,
|
r.getOrigin().y,
|
||||||
r.getOrigin().z };
|
r.getOrigin().z};
|
||||||
|
|
||||||
float[] invDirections = { 1f / r.getDirection().x,
|
float[] invDirections = {1f / r.getDirection().x,
|
||||||
1f / r.getDirection().y,
|
1f / r.getDirection().y,
|
||||||
1f / r.getDirection().z };
|
1f / r.getDirection().z};
|
||||||
|
|
||||||
r.getDirection().normalizeLocal();
|
r.getDirection().normalizeLocal();
|
||||||
|
|
||||||
Vector3f v1 = new Vector3f(),
|
Vector3f v1 = new Vector3f(),
|
||||||
v2 = new Vector3f(),
|
v2 = new Vector3f(),
|
||||||
v3 = new Vector3f();
|
v3 = new Vector3f();
|
||||||
int cols = 0;
|
int cols = 0;
|
||||||
|
|
||||||
stack.add(new BIHStackData(this, sceneMin, sceneMax));
|
stack.add(new BIHStackData(this, sceneMin, sceneMax));
|
||||||
stackloop: while (stack.size() > 0){
|
stackloop:
|
||||||
|
while (stack.size() > 0) {
|
||||||
|
|
||||||
BIHStackData data = stack.remove(stack.size()-1);
|
BIHStackData data = stack.remove(stack.size() - 1);
|
||||||
BIHNode node = data.node;
|
BIHNode node = data.node;
|
||||||
float tMin = data.min,
|
float tMin = data.min,
|
||||||
tMax = data.max;
|
tMax = data.max;
|
||||||
|
|
||||||
if (tMax < tMin)
|
if (tMax < tMin) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
leafloop: while (node.axis != 3){ // while node is not a leaf
|
leafloop:
|
||||||
|
while (node.axis != 3) { // while node is not a leaf
|
||||||
int a = node.axis;
|
int a = node.axis;
|
||||||
|
|
||||||
// find the origin and direction value for the given axis
|
// find the origin and direction value for the given axis
|
||||||
@ -351,12 +356,12 @@ public final class BIHNode implements Savable {
|
|||||||
float tNearSplit, tFarSplit;
|
float tNearSplit, tFarSplit;
|
||||||
BIHNode nearNode, farNode;
|
BIHNode nearNode, farNode;
|
||||||
|
|
||||||
tNearSplit = (node.leftPlane - origin) * invDirection;
|
tNearSplit = (node.leftPlane - origin) * invDirection;
|
||||||
tFarSplit = (node.rightPlane - origin) * invDirection;
|
tFarSplit = (node.rightPlane - origin) * invDirection;
|
||||||
nearNode = node.left;
|
nearNode = node.left;
|
||||||
farNode = node.right;
|
farNode = node.right;
|
||||||
|
|
||||||
if (invDirection < 0){
|
if (invDirection < 0) {
|
||||||
float tmpSplit = tNearSplit;
|
float tmpSplit = tNearSplit;
|
||||||
tNearSplit = tFarSplit;
|
tNearSplit = tFarSplit;
|
||||||
tFarSplit = tmpSplit;
|
tFarSplit = tmpSplit;
|
||||||
@ -366,18 +371,18 @@ public final class BIHNode implements Savable {
|
|||||||
farNode = tmpNode;
|
farNode = tmpNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tMin > tNearSplit && tMax < tFarSplit){
|
if (tMin > tNearSplit && tMax < tFarSplit) {
|
||||||
continue stackloop;
|
continue stackloop;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tMin > tNearSplit){
|
if (tMin > tNearSplit) {
|
||||||
tMin = max(tMin, tFarSplit);
|
tMin = max(tMin, tFarSplit);
|
||||||
node = farNode;
|
node = farNode;
|
||||||
}else if (tMax < tFarSplit){
|
} else if (tMax < tFarSplit) {
|
||||||
tMax = min(tMax, tNearSplit);
|
tMax = min(tMax, tNearSplit);
|
||||||
node = nearNode;
|
node = nearNode;
|
||||||
}else{
|
} else {
|
||||||
stack.add(new BIHStackData(farNode, max(tMin, tFarSplit), tMax));
|
stack.add(new BIHStackData(farNode, max(tMin, tFarSplit), tMax));
|
||||||
tMax = min(tMax, tNearSplit);
|
tMax = min(tMax, tNearSplit);
|
||||||
node = nearNode;
|
node = nearNode;
|
||||||
}
|
}
|
||||||
@ -391,38 +396,35 @@ public final class BIHNode implements Savable {
|
|||||||
// }
|
// }
|
||||||
|
|
||||||
// a leaf
|
// a leaf
|
||||||
for (int i = node.leftIndex; i <= node.rightIndex; i++){
|
for (int i = node.leftIndex; i <= node.rightIndex; i++) {
|
||||||
tree.getTriangle(i, v1,v2,v3);
|
tree.getTriangle(i, v1, v2, v3);
|
||||||
|
|
||||||
float t = r.intersects(v1,v2,v3);
|
float t = r.intersects(v1, v2, v3);
|
||||||
if (!Float.isInfinite(t)){
|
if (!Float.isInfinite(t)) {
|
||||||
if (worldMatrix != null) {
|
if (worldMatrix != null) {
|
||||||
worldMatrix.mult(v1, v1);
|
worldMatrix.mult(v1, v1);
|
||||||
worldMatrix.mult(v2, v2);
|
worldMatrix.mult(v2, v2);
|
||||||
worldMatrix.mult(v3, v3);
|
worldMatrix.mult(v3, v3);
|
||||||
float t_world = new Ray(o,d).intersects(v1,v2,v3);
|
float t_world = new Ray(o, d).intersects(v1, v2, v3);
|
||||||
t = t_world;
|
t = t_world;
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector3f contactNormal = Triangle.computeTriangleNormal(v1, v2, v3, null);
|
Vector3f contactNormal = Triangle.computeTriangleNormal(v1, v2, v3, null);
|
||||||
Vector3f contactPoint = new Vector3f(d)
|
Vector3f contactPoint = new Vector3f(d).multLocal(t).addLocal(o);
|
||||||
.multLocal(t)
|
float worldSpaceDist = o.distance(contactPoint);
|
||||||
.addLocal(o);
|
|
||||||
float worldSpaceDist = o.distance(contactPoint);
|
|
||||||
|
|
||||||
CollisionResult cr = new CollisionResult(contactPoint, worldSpaceDist);
|
CollisionResult cr = new CollisionResult(contactPoint, worldSpaceDist);
|
||||||
cr.setContactNormal(contactNormal);
|
cr.setContactNormal(contactNormal);
|
||||||
cr.setTriangleIndex(tree.getTriangleIndex(i));
|
cr.setTriangleIndex(tree.getTriangleIndex(i));
|
||||||
results.addCollision(cr);
|
results.addCollision(cr);
|
||||||
cols ++;
|
cols++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
vars.release();
|
||||||
r.setOrigin(o);
|
r.setOrigin(o);
|
||||||
r.setDirection(d);
|
r.setDirection(d);
|
||||||
|
|
||||||
return cols;
|
return cols;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -29,7 +29,6 @@
|
|||||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.jme3.collision.bih;
|
package com.jme3.collision.bih;
|
||||||
|
|
||||||
import com.jme3.scene.mesh.VirtualIndexBuffer;
|
import com.jme3.scene.mesh.VirtualIndexBuffer;
|
||||||
@ -62,20 +61,16 @@ import static java.lang.Math.max;
|
|||||||
|
|
||||||
public class BIHTree implements CollisionData {
|
public class BIHTree implements CollisionData {
|
||||||
|
|
||||||
public static final int MAX_TREE_DEPTH = 100;
|
public static final int MAX_TREE_DEPTH = 100;
|
||||||
public static final int MAX_TRIS_PER_NODE = 21;
|
public static final int MAX_TRIS_PER_NODE = 21;
|
||||||
|
|
||||||
private Mesh mesh;
|
private Mesh mesh;
|
||||||
|
|
||||||
private BIHNode root;
|
private BIHNode root;
|
||||||
private int maxTrisPerNode;
|
private int maxTrisPerNode;
|
||||||
private int numTris;
|
private int numTris;
|
||||||
private float[] pointData;
|
private float[] pointData;
|
||||||
private int[] triIndices;
|
private int[] triIndices;
|
||||||
|
|
||||||
private transient CollisionResults boundResults = new CollisionResults();
|
private transient CollisionResults boundResults = new CollisionResults();
|
||||||
private transient float[] bihSwapTmp;
|
private transient float[] bihSwapTmp;
|
||||||
|
|
||||||
private static final TriangleAxisComparator[] comparators = new TriangleAxisComparator[3];
|
private static final TriangleAxisComparator[] comparators = new TriangleAxisComparator[3];
|
||||||
|
|
||||||
static {
|
static {
|
||||||
@ -84,45 +79,47 @@ public class BIHTree implements CollisionData {
|
|||||||
comparators[2] = new TriangleAxisComparator(2);
|
comparators[2] = new TriangleAxisComparator(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initTriList(FloatBuffer vb, IndexBuffer ib){
|
private void initTriList(FloatBuffer vb, IndexBuffer ib) {
|
||||||
pointData = new float[numTris * 3 * 3];
|
pointData = new float[numTris * 3 * 3];
|
||||||
int p = 0;
|
int p = 0;
|
||||||
for (int i = 0; i < numTris*3; i+=3){
|
for (int i = 0; i < numTris * 3; i += 3) {
|
||||||
int vert = ib.get(i)*3;
|
int vert = ib.get(i) * 3;
|
||||||
pointData[p++] = vb.get(vert++);
|
pointData[p++] = vb.get(vert++);
|
||||||
pointData[p++] = vb.get(vert++);
|
pointData[p++] = vb.get(vert++);
|
||||||
pointData[p++] = vb.get(vert);
|
pointData[p++] = vb.get(vert);
|
||||||
|
|
||||||
vert = ib.get(i+1)*3;
|
vert = ib.get(i + 1) * 3;
|
||||||
pointData[p++] = vb.get(vert++);
|
pointData[p++] = vb.get(vert++);
|
||||||
pointData[p++] = vb.get(vert++);
|
pointData[p++] = vb.get(vert++);
|
||||||
pointData[p++] = vb.get(vert);
|
pointData[p++] = vb.get(vert);
|
||||||
|
|
||||||
vert = ib.get(i+2)*3;
|
vert = ib.get(i + 2) * 3;
|
||||||
pointData[p++] = vb.get(vert++);
|
pointData[p++] = vb.get(vert++);
|
||||||
pointData[p++] = vb.get(vert++);
|
pointData[p++] = vb.get(vert++);
|
||||||
pointData[p++] = vb.get(vert);
|
pointData[p++] = vb.get(vert);
|
||||||
}
|
}
|
||||||
|
|
||||||
triIndices = new int[numTris];
|
triIndices = new int[numTris];
|
||||||
for (int i = 0; i < numTris; i++)
|
for (int i = 0; i < numTris; i++) {
|
||||||
triIndices[i] = i;
|
triIndices[i] = i;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public BIHTree(Mesh mesh, int maxTrisPerNode){
|
public BIHTree(Mesh mesh, int maxTrisPerNode) {
|
||||||
this.mesh = mesh;
|
this.mesh = mesh;
|
||||||
this.maxTrisPerNode = maxTrisPerNode;
|
this.maxTrisPerNode = maxTrisPerNode;
|
||||||
|
|
||||||
if (maxTrisPerNode < 1 || mesh == null)
|
if (maxTrisPerNode < 1 || mesh == null) {
|
||||||
throw new IllegalArgumentException();
|
throw new IllegalArgumentException();
|
||||||
|
}
|
||||||
|
|
||||||
bihSwapTmp = new float[9];
|
bihSwapTmp = new float[9];
|
||||||
|
|
||||||
FloatBuffer vb = (FloatBuffer) mesh.getBuffer(Type.Position).getData();
|
FloatBuffer vb = (FloatBuffer) mesh.getBuffer(Type.Position).getData();
|
||||||
IndexBuffer ib = mesh.getIndexBuffer();
|
IndexBuffer ib = mesh.getIndexBuffer();
|
||||||
if (ib == null){
|
if (ib == null) {
|
||||||
ib = new VirtualIndexBuffer(mesh.getVertexCount(), mesh.getMode());
|
ib = new VirtualIndexBuffer(mesh.getVertexCount(), mesh.getMode());
|
||||||
}else if (mesh.getMode() != Mode.Triangles){
|
} else if (mesh.getMode() != Mode.Triangles) {
|
||||||
ib = new WrappedIndexBuffer(mesh);
|
ib = new WrappedIndexBuffer(mesh);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -130,87 +127,89 @@ public class BIHTree implements CollisionData {
|
|||||||
initTriList(vb, ib);
|
initTriList(vb, ib);
|
||||||
}
|
}
|
||||||
|
|
||||||
public BIHTree(Mesh mesh){
|
public BIHTree(Mesh mesh) {
|
||||||
this(mesh, MAX_TRIS_PER_NODE);
|
this(mesh, MAX_TRIS_PER_NODE);
|
||||||
}
|
}
|
||||||
|
|
||||||
public BIHTree(){
|
public BIHTree() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void construct(){
|
public void construct() {
|
||||||
BoundingBox sceneBbox = createBox(0, numTris-1);
|
BoundingBox sceneBbox = createBox(0, numTris - 1);
|
||||||
root = createNode(0, numTris-1, sceneBbox, 0);
|
root = createNode(0, numTris - 1, sceneBbox, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
private BoundingBox createBox(int l, int r) {
|
private BoundingBox createBox(int l, int r) {
|
||||||
TempVars vars = TempVars.get();
|
TempVars vars = TempVars.get();
|
||||||
assert vars.lock();
|
|
||||||
Vector3f min = vars.vect1.set(new Vector3f(Float.POSITIVE_INFINITY, Float.POSITIVE_INFINITY, Float.POSITIVE_INFINITY));
|
Vector3f min = vars.vect1.set(new Vector3f(Float.POSITIVE_INFINITY, Float.POSITIVE_INFINITY, Float.POSITIVE_INFINITY));
|
||||||
Vector3f max = vars.vect2.set(new Vector3f(Float.NEGATIVE_INFINITY, Float.NEGATIVE_INFINITY, Float.NEGATIVE_INFINITY));
|
Vector3f max = vars.vect2.set(new Vector3f(Float.NEGATIVE_INFINITY, Float.NEGATIVE_INFINITY, Float.NEGATIVE_INFINITY));
|
||||||
|
|
||||||
Vector3f v1 = vars.vect3,
|
Vector3f v1 = vars.vect3,
|
||||||
v2 = vars.vect4,
|
v2 = vars.vect4,
|
||||||
v3 = vars.vect5;
|
v3 = vars.vect5;
|
||||||
|
|
||||||
for (int i = l; i <= r; i++) {
|
for (int i = l; i <= r; i++) {
|
||||||
getTriangle(i, v1,v2,v3);
|
getTriangle(i, v1, v2, v3);
|
||||||
BoundingBox.checkMinMax(min, max, v1);
|
BoundingBox.checkMinMax(min, max, v1);
|
||||||
BoundingBox.checkMinMax(min, max, v2);
|
BoundingBox.checkMinMax(min, max, v2);
|
||||||
BoundingBox.checkMinMax(min, max, v3);
|
BoundingBox.checkMinMax(min, max, v3);
|
||||||
}
|
}
|
||||||
|
|
||||||
BoundingBox bbox = new BoundingBox(min,max);
|
BoundingBox bbox = new BoundingBox(min, max);
|
||||||
assert vars.unlock();
|
vars.release();
|
||||||
return bbox;
|
return bbox;
|
||||||
}
|
}
|
||||||
|
|
||||||
int getTriangleIndex(int triIndex){
|
int getTriangleIndex(int triIndex) {
|
||||||
return triIndices[triIndex];
|
return triIndices[triIndex];
|
||||||
}
|
}
|
||||||
|
|
||||||
private int sortTriangles(int l, int r, float split, int axis){
|
private int sortTriangles(int l, int r, float split, int axis) {
|
||||||
int pivot = l;
|
int pivot = l;
|
||||||
int j = r;
|
int j = r;
|
||||||
|
|
||||||
TempVars vars = TempVars.get();
|
TempVars vars = TempVars.get();
|
||||||
assert vars.lock();
|
|
||||||
Vector3f v1 = vars.vect1,
|
|
||||||
v2 = vars.vect2,
|
|
||||||
v3 = vars.vect3;
|
|
||||||
|
|
||||||
while (pivot <= j){
|
Vector3f v1 = vars.vect1,
|
||||||
|
v2 = vars.vect2,
|
||||||
|
v3 = vars.vect3;
|
||||||
|
|
||||||
|
while (pivot <= j) {
|
||||||
getTriangle(pivot, v1, v2, v3);
|
getTriangle(pivot, v1, v2, v3);
|
||||||
v1.addLocal(v2).addLocal(v3).multLocal(FastMath.ONE_THIRD);
|
v1.addLocal(v2).addLocal(v3).multLocal(FastMath.ONE_THIRD);
|
||||||
if (v1.get(axis) > split){
|
if (v1.get(axis) > split) {
|
||||||
swapTriangles(pivot, j);
|
swapTriangles(pivot, j);
|
||||||
--j;
|
--j;
|
||||||
}else{
|
} else {
|
||||||
++pivot;
|
++pivot;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
assert vars.unlock();
|
vars.release();
|
||||||
pivot = (pivot == l && j < pivot) ? j : pivot;
|
pivot = (pivot == l && j < pivot) ? j : pivot;
|
||||||
return pivot;
|
return pivot;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setMinMax(BoundingBox bbox, boolean doMin, int axis, float value){
|
private void setMinMax(BoundingBox bbox, boolean doMin, int axis, float value) {
|
||||||
Vector3f min = bbox.getMin(null);
|
Vector3f min = bbox.getMin(null);
|
||||||
Vector3f max = bbox.getMax(null);
|
Vector3f max = bbox.getMax(null);
|
||||||
|
|
||||||
if (doMin)
|
if (doMin) {
|
||||||
min.set(axis, value);
|
min.set(axis, value);
|
||||||
else
|
} else {
|
||||||
max.set(axis, value);
|
max.set(axis, value);
|
||||||
|
}
|
||||||
|
|
||||||
bbox.setMinMax(min, max);
|
bbox.setMinMax(min, max);
|
||||||
}
|
}
|
||||||
|
|
||||||
private float getMinMax(BoundingBox bbox, boolean doMin, int axis){
|
private float getMinMax(BoundingBox bbox, boolean doMin, int axis) {
|
||||||
if (doMin)
|
if (doMin) {
|
||||||
return bbox.getMin(null).get(axis);
|
return bbox.getMin(null).get(axis);
|
||||||
else
|
} else {
|
||||||
return bbox.getMax(null).get(axis);
|
return bbox.getMax(null).get(axis);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// private BIHNode createNode2(int l, int r, BoundingBox nodeBbox, int depth){
|
// private BIHNode createNode2(int l, int r, BoundingBox nodeBbox, int depth){
|
||||||
@ -290,9 +289,8 @@ public class BIHTree implements CollisionData {
|
|||||||
//
|
//
|
||||||
// return node;
|
// return node;
|
||||||
// }
|
// }
|
||||||
|
|
||||||
private BIHNode createNode(int l, int r, BoundingBox nodeBbox, int depth) {
|
private BIHNode createNode(int l, int r, BoundingBox nodeBbox, int depth) {
|
||||||
if ((r - l) < maxTrisPerNode || depth > MAX_TREE_DEPTH){
|
if ((r - l) < maxTrisPerNode || depth > MAX_TREE_DEPTH) {
|
||||||
return new BIHNode(l, r);
|
return new BIHNode(l, r);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -303,38 +301,42 @@ public class BIHTree implements CollisionData {
|
|||||||
exteriorExt.subtractLocal(interiorExt);
|
exteriorExt.subtractLocal(interiorExt);
|
||||||
|
|
||||||
int axis = 0;
|
int axis = 0;
|
||||||
if (exteriorExt.x > exteriorExt.y){
|
if (exteriorExt.x > exteriorExt.y) {
|
||||||
if (exteriorExt.x > exteriorExt.z)
|
if (exteriorExt.x > exteriorExt.z) {
|
||||||
axis = 0;
|
axis = 0;
|
||||||
else
|
} else {
|
||||||
axis = 2;
|
axis = 2;
|
||||||
}else{
|
}
|
||||||
if (exteriorExt.y > exteriorExt.z)
|
} else {
|
||||||
|
if (exteriorExt.y > exteriorExt.z) {
|
||||||
axis = 1;
|
axis = 1;
|
||||||
else
|
} else {
|
||||||
axis = 2;
|
axis = 2;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (exteriorExt.equals(Vector3f.ZERO))
|
if (exteriorExt.equals(Vector3f.ZERO)) {
|
||||||
axis = 0;
|
axis = 0;
|
||||||
|
}
|
||||||
|
|
||||||
// Arrays.sort(tris, l, r, comparators[axis]);
|
// Arrays.sort(tris, l, r, comparators[axis]);
|
||||||
float split = currentBox.getCenter().get(axis);
|
float split = currentBox.getCenter().get(axis);
|
||||||
int pivot = sortTriangles(l, r, split, axis);
|
int pivot = sortTriangles(l, r, split, axis);
|
||||||
if (pivot == l || pivot == r)
|
if (pivot == l || pivot == r) {
|
||||||
pivot = (r + l) / 2;
|
pivot = (r + l) / 2;
|
||||||
|
}
|
||||||
|
|
||||||
//If one of the partitions is empty, continue with recursion: same level but different bbox
|
//If one of the partitions is empty, continue with recursion: same level but different bbox
|
||||||
if (pivot < l){
|
if (pivot < l) {
|
||||||
//Only right
|
//Only right
|
||||||
BoundingBox rbbox = new BoundingBox(currentBox);
|
BoundingBox rbbox = new BoundingBox(currentBox);
|
||||||
setMinMax(rbbox, true, axis, split);
|
setMinMax(rbbox, true, axis, split);
|
||||||
return createNode(l, r, rbbox, depth+1);
|
return createNode(l, r, rbbox, depth + 1);
|
||||||
}else if (pivot > r){
|
} else if (pivot > r) {
|
||||||
//Only left
|
//Only left
|
||||||
BoundingBox lbbox = new BoundingBox(currentBox);
|
BoundingBox lbbox = new BoundingBox(currentBox);
|
||||||
setMinMax(lbbox, false, axis, split);
|
setMinMax(lbbox, false, axis, split);
|
||||||
return createNode(l, r, lbbox, depth+1);
|
return createNode(l, r, lbbox, depth + 1);
|
||||||
}else{
|
} else {
|
||||||
//Build the node
|
//Build the node
|
||||||
BIHNode node = new BIHNode(axis);
|
BIHNode node = new BIHNode(axis);
|
||||||
|
|
||||||
@ -343,21 +345,21 @@ public class BIHTree implements CollisionData {
|
|||||||
setMinMax(lbbox, false, axis, split);
|
setMinMax(lbbox, false, axis, split);
|
||||||
|
|
||||||
//The left node right border is the plane most right
|
//The left node right border is the plane most right
|
||||||
node.setLeftPlane( getMinMax(createBox(l, max(l, pivot - 1)), false, axis) );
|
node.setLeftPlane(getMinMax(createBox(l, max(l, pivot - 1)), false, axis));
|
||||||
node.setLeftChild( createNode(l, max(l, pivot - 1), lbbox, depth+1) ); //Recursive call
|
node.setLeftChild(createNode(l, max(l, pivot - 1), lbbox, depth + 1)); //Recursive call
|
||||||
|
|
||||||
//Right Child
|
//Right Child
|
||||||
BoundingBox rbbox = new BoundingBox(currentBox);
|
BoundingBox rbbox = new BoundingBox(currentBox);
|
||||||
setMinMax(rbbox, true, axis, split);
|
setMinMax(rbbox, true, axis, split);
|
||||||
//The right node left border is the plane most left
|
//The right node left border is the plane most left
|
||||||
node.setRightPlane( getMinMax(createBox(pivot, r), true, axis) );
|
node.setRightPlane(getMinMax(createBox(pivot, r), true, axis));
|
||||||
node.setRightChild( createNode(pivot, r, rbbox, depth+1) ); //Recursive call
|
node.setRightChild(createNode(pivot, r, rbbox, depth + 1)); //Recursive call
|
||||||
|
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void getTriangle(int index, Vector3f v1, Vector3f v2, Vector3f v3){
|
public void getTriangle(int index, Vector3f v1, Vector3f v2, Vector3f v3) {
|
||||||
int pointIndex = index * 9;
|
int pointIndex = index * 9;
|
||||||
|
|
||||||
v1.x = pointData[pointIndex++];
|
v1.x = pointData[pointIndex++];
|
||||||
@ -373,7 +375,7 @@ public class BIHTree implements CollisionData {
|
|||||||
v3.z = pointData[pointIndex++];
|
v3.z = pointData[pointIndex++];
|
||||||
}
|
}
|
||||||
|
|
||||||
public void swapTriangles(int index1, int index2){
|
public void swapTriangles(int index1, int index2) {
|
||||||
int p1 = index1 * 9;
|
int p1 = index1 * 9;
|
||||||
int p2 = index2 * 9;
|
int p2 = index2 * 9;
|
||||||
|
|
||||||
@ -393,25 +395,27 @@ public class BIHTree implements CollisionData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private int collideWithRay(Ray r,
|
private int collideWithRay(Ray r,
|
||||||
Matrix4f worldMatrix,
|
Matrix4f worldMatrix,
|
||||||
BoundingVolume worldBound,
|
BoundingVolume worldBound,
|
||||||
CollisionResults results){
|
CollisionResults results) {
|
||||||
|
|
||||||
boundResults.clear();
|
boundResults.clear();
|
||||||
worldBound.collideWith(r, boundResults);
|
worldBound.collideWith(r, boundResults);
|
||||||
if (boundResults.size() > 0){
|
if (boundResults.size() > 0) {
|
||||||
float tMin = boundResults.getClosestCollision().getDistance();
|
float tMin = boundResults.getClosestCollision().getDistance();
|
||||||
float tMax = boundResults.getFarthestCollision().getDistance();
|
float tMax = boundResults.getFarthestCollision().getDistance();
|
||||||
|
|
||||||
if (tMax <= 0)
|
if (tMax <= 0) {
|
||||||
tMax = Float.POSITIVE_INFINITY;
|
tMax = Float.POSITIVE_INFINITY;
|
||||||
else if (tMin == tMax)
|
} else if (tMin == tMax) {
|
||||||
tMin = 0;
|
tMin = 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (tMin <= 0)
|
if (tMin <= 0) {
|
||||||
tMin = 0;
|
tMin = 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (r.getLimit() < Float.POSITIVE_INFINITY){
|
if (r.getLimit() < Float.POSITIVE_INFINITY) {
|
||||||
tMax = Math.min(tMax, r.getLimit());
|
tMax = Math.min(tMax, r.getLimit());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -422,17 +426,17 @@ public class BIHTree implements CollisionData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private int collideWithBoundingVolume(BoundingVolume bv,
|
private int collideWithBoundingVolume(BoundingVolume bv,
|
||||||
Matrix4f worldMatrix,
|
Matrix4f worldMatrix,
|
||||||
CollisionResults results){
|
CollisionResults results) {
|
||||||
BoundingBox bbox;
|
BoundingBox bbox;
|
||||||
if (bv instanceof BoundingSphere){
|
if (bv instanceof BoundingSphere) {
|
||||||
BoundingSphere sphere = (BoundingSphere) bv;
|
BoundingSphere sphere = (BoundingSphere) bv;
|
||||||
bbox = new BoundingBox(bv.getCenter().clone(), sphere.getRadius(),
|
bbox = new BoundingBox(bv.getCenter().clone(), sphere.getRadius(),
|
||||||
sphere.getRadius(),
|
sphere.getRadius(),
|
||||||
sphere.getRadius());
|
sphere.getRadius());
|
||||||
}else if (bv instanceof BoundingBox){
|
} else if (bv instanceof BoundingBox) {
|
||||||
bbox = new BoundingBox( (BoundingBox) bv );
|
bbox = new BoundingBox((BoundingBox) bv);
|
||||||
}else{
|
} else {
|
||||||
throw new UnsupportedCollisionException();
|
throw new UnsupportedCollisionException();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -441,17 +445,17 @@ public class BIHTree implements CollisionData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public int collideWith(Collidable other,
|
public int collideWith(Collidable other,
|
||||||
Matrix4f worldMatrix,
|
Matrix4f worldMatrix,
|
||||||
BoundingVolume worldBound,
|
BoundingVolume worldBound,
|
||||||
CollisionResults results){
|
CollisionResults results) {
|
||||||
|
|
||||||
if (other instanceof Ray){
|
if (other instanceof Ray) {
|
||||||
Ray ray = (Ray) other;
|
Ray ray = (Ray) other;
|
||||||
return collideWithRay(ray, worldMatrix, worldBound, results);
|
return collideWithRay(ray, worldMatrix, worldBound, results);
|
||||||
}else if (other instanceof BoundingVolume){
|
} else if (other instanceof BoundingVolume) {
|
||||||
BoundingVolume bv = (BoundingVolume) other;
|
BoundingVolume bv = (BoundingVolume) other;
|
||||||
return collideWithBoundingVolume(bv, worldMatrix, results);
|
return collideWithBoundingVolume(bv, worldMatrix, results);
|
||||||
}else{
|
} else {
|
||||||
throw new UnsupportedCollisionException();
|
throw new UnsupportedCollisionException();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -473,5 +477,4 @@ public class BIHTree implements CollisionData {
|
|||||||
pointData = ic.readFloatArray("points", null);
|
pointData = ic.readFloatArray("points", null);
|
||||||
triIndices = ic.readIntArray("indices", null);
|
triIndices = ic.readIntArray("indices", null);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -75,7 +75,6 @@ public class ParticleEmitter extends Geometry {
|
|||||||
|
|
||||||
private static final EmitterShape DEFAULT_SHAPE = new EmitterPointShape(Vector3f.ZERO);
|
private static final EmitterShape DEFAULT_SHAPE = new EmitterPointShape(Vector3f.ZERO);
|
||||||
private static final ParticleInfluencer DEFAULT_INFLUENCER = new DefaultParticleInfluencer();
|
private static final ParticleInfluencer DEFAULT_INFLUENCER = new DefaultParticleInfluencer();
|
||||||
|
|
||||||
private ParticleEmitterControl control = new ParticleEmitterControl();
|
private ParticleEmitterControl control = new ParticleEmitterControl();
|
||||||
private EmitterShape shape = DEFAULT_SHAPE;
|
private EmitterShape shape = DEFAULT_SHAPE;
|
||||||
private ParticleMesh particleMesh;
|
private ParticleMesh particleMesh;
|
||||||
@ -110,7 +109,7 @@ public class ParticleEmitter extends Geometry {
|
|||||||
private class ParticleEmitterControl implements Control {
|
private class ParticleEmitterControl implements Control {
|
||||||
|
|
||||||
public Control cloneForSpatial(Spatial spatial) {
|
public Control cloneForSpatial(Spatial spatial) {
|
||||||
return ((ParticleEmitter)spatial).control;
|
return ((ParticleEmitter) spatial).control;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setSpatial(Spatial spatial) {
|
public void setSpatial(Spatial spatial) {
|
||||||
@ -139,7 +138,6 @@ public class ParticleEmitter extends Geometry {
|
|||||||
public void read(JmeImporter im) throws IOException {
|
public void read(JmeImporter im) throws IOException {
|
||||||
// the data is not written here
|
// the data is not written here
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -199,7 +197,6 @@ public class ParticleEmitter extends Geometry {
|
|||||||
this.shape = shape;
|
this.shape = shape;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public EmitterShape getShape() {
|
public EmitterShape getShape() {
|
||||||
return shape;
|
return shape;
|
||||||
}
|
}
|
||||||
@ -838,7 +835,7 @@ public class ParticleEmitter extends Geometry {
|
|||||||
this.getWorldTransform();
|
this.getWorldTransform();
|
||||||
|
|
||||||
TempVars vars = TempVars.get();
|
TempVars vars = TempVars.get();
|
||||||
assert vars.lock();
|
|
||||||
|
|
||||||
BoundingBox bbox = (BoundingBox) this.getMesh().getBound();
|
BoundingBox bbox = (BoundingBox) this.getMesh().getBound();
|
||||||
|
|
||||||
@ -862,7 +859,7 @@ public class ParticleEmitter extends Geometry {
|
|||||||
bbox.setMinMax(min, max);
|
bbox.setMinMax(min, max);
|
||||||
this.setBoundRefresh();
|
this.setBoundRefresh();
|
||||||
|
|
||||||
assert vars.unlock();
|
vars.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -909,7 +906,7 @@ public class ParticleEmitter extends Geometry {
|
|||||||
this.getWorldTransform();
|
this.getWorldTransform();
|
||||||
|
|
||||||
TempVars vars = TempVars.get();
|
TempVars vars = TempVars.get();
|
||||||
assert vars.lock();
|
|
||||||
|
|
||||||
Vector3f min = vars.vect1.set(Vector3f.POSITIVE_INFINITY);
|
Vector3f min = vars.vect1.set(Vector3f.POSITIVE_INFINITY);
|
||||||
Vector3f max = vars.vect2.set(Vector3f.NEGATIVE_INFINITY);
|
Vector3f max = vars.vect2.set(Vector3f.NEGATIVE_INFINITY);
|
||||||
@ -979,7 +976,7 @@ public class ParticleEmitter extends Geometry {
|
|||||||
bbox.setMinMax(min, max);
|
bbox.setMinMax(min, max);
|
||||||
this.setBoundRefresh();
|
this.setBoundRefresh();
|
||||||
|
|
||||||
assert vars.unlock();
|
vars.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1033,14 +1030,15 @@ public class ParticleEmitter extends Geometry {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Matrix3f inverseRotation = Matrix3f.IDENTITY;
|
Matrix3f inverseRotation = Matrix3f.IDENTITY;
|
||||||
|
TempVars vars = null;
|
||||||
if (!worldSpace) {
|
if (!worldSpace) {
|
||||||
TempVars vars = TempVars.get();
|
vars = TempVars.get();
|
||||||
assert vars.lock();
|
|
||||||
inverseRotation = this.getWorldRotation().toRotationMatrix(vars.tempMat3).invertLocal();
|
inverseRotation = this.getWorldRotation().toRotationMatrix(vars.tempMat3).invertLocal();
|
||||||
}
|
}
|
||||||
particleMesh.updateParticleData(particles, cam, inverseRotation);
|
particleMesh.updateParticleData(particles, cam, inverseRotation);
|
||||||
if (!worldSpace) {
|
if (!worldSpace) {
|
||||||
assert TempVars.get().unlock();
|
vars.release();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1123,9 +1121,9 @@ public class ParticleEmitter extends Geometry {
|
|||||||
// compatibility before the control inside particle emitter
|
// compatibility before the control inside particle emitter
|
||||||
// was changed:
|
// was changed:
|
||||||
// find it in the controls and take it out, then add the proper one in
|
// find it in the controls and take it out, then add the proper one in
|
||||||
for (int i = 0; i < controls.size(); i++){
|
for (int i = 0; i < controls.size(); i++) {
|
||||||
Object obj = controls.get(i);
|
Object obj = controls.get(i);
|
||||||
if (obj instanceof ParticleEmitter){
|
if (obj instanceof ParticleEmitter) {
|
||||||
controls.remove(i);
|
controls.remove(i);
|
||||||
// now add the proper one in
|
// now add the proper one in
|
||||||
controls.add(control);
|
controls.add(control);
|
||||||
@ -1134,7 +1132,7 @@ public class ParticleEmitter extends Geometry {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// compatability before gravity was not a vector but a float
|
// compatability before gravity was not a vector but a float
|
||||||
if (gravity == null){
|
if (gravity == null) {
|
||||||
gravity = new Vector3f();
|
gravity = new Vector3f();
|
||||||
gravity.y = ic.readFloat("gravity", 0);
|
gravity.y = ic.readFloat("gravity", 0);
|
||||||
}
|
}
|
||||||
|
@ -29,7 +29,6 @@
|
|||||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.jme3.math;
|
package com.jme3.math;
|
||||||
|
|
||||||
import com.jme3.export.InputCapsule;
|
import com.jme3.export.InputCapsule;
|
||||||
@ -113,7 +112,7 @@ public class Line implements Savable, Cloneable {
|
|||||||
|
|
||||||
public float distanceSquared(Vector3f point) {
|
public float distanceSquared(Vector3f point) {
|
||||||
TempVars vars = TempVars.get();
|
TempVars vars = TempVars.get();
|
||||||
assert vars.lock();
|
|
||||||
Vector3f compVec1 = vars.vect1;
|
Vector3f compVec1 = vars.vect1;
|
||||||
Vector3f compVec2 = vars.vect2;
|
Vector3f compVec2 = vars.vect2;
|
||||||
|
|
||||||
@ -122,71 +121,71 @@ public class Line implements Savable, Cloneable {
|
|||||||
origin.add(direction.mult(lineParameter, compVec2), compVec2);
|
origin.add(direction.mult(lineParameter, compVec2), compVec2);
|
||||||
compVec2.subtract(point, compVec1);
|
compVec2.subtract(point, compVec1);
|
||||||
float len = compVec1.lengthSquared();
|
float len = compVec1.lengthSquared();
|
||||||
assert vars.unlock();
|
vars.release();
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
public float distance(Vector3f point) {
|
public float distance(Vector3f point) {
|
||||||
return FastMath.sqrt(distanceSquared(point));
|
return FastMath.sqrt(distanceSquared(point));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void orthogonalLineFit(FloatBuffer points) {
|
public void orthogonalLineFit(FloatBuffer points) {
|
||||||
if (points == null) {
|
if (points == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
TempVars vars = TempVars.get();
|
TempVars vars = TempVars.get();
|
||||||
assert vars.lock();
|
|
||||||
Vector3f compVec1 = vars.vect1;
|
Vector3f compVec1 = vars.vect1;
|
||||||
Vector3f compVec2 = vars.vect2;
|
Vector3f compVec2 = vars.vect2;
|
||||||
Matrix3f compMat1 = vars.tempMat3;
|
Matrix3f compMat1 = vars.tempMat3;
|
||||||
Eigen3f compEigen1 = vars.eigen;
|
Eigen3f compEigen1 = vars.eigen;
|
||||||
|
|
||||||
points.rewind();
|
points.rewind();
|
||||||
|
|
||||||
// compute average of points
|
// compute average of points
|
||||||
int length = points.remaining() / 3;
|
int length = points.remaining() / 3;
|
||||||
|
|
||||||
BufferUtils.populateFromBuffer(origin, points, 0);
|
BufferUtils.populateFromBuffer(origin, points, 0);
|
||||||
for (int i = 1; i < length; i++) {
|
for (int i = 1; i < length; i++) {
|
||||||
BufferUtils.populateFromBuffer(compVec1, points, i);
|
BufferUtils.populateFromBuffer(compVec1, points, i);
|
||||||
origin.addLocal(compVec1);
|
origin.addLocal(compVec1);
|
||||||
}
|
}
|
||||||
|
|
||||||
origin.multLocal(1f / (float) length);
|
origin.multLocal(1f / (float) length);
|
||||||
|
|
||||||
// compute sums of products
|
// compute sums of products
|
||||||
float sumXX = 0.0f, sumXY = 0.0f, sumXZ = 0.0f;
|
float sumXX = 0.0f, sumXY = 0.0f, sumXZ = 0.0f;
|
||||||
float sumYY = 0.0f, sumYZ = 0.0f, sumZZ = 0.0f;
|
float sumYY = 0.0f, sumYZ = 0.0f, sumZZ = 0.0f;
|
||||||
|
|
||||||
points.rewind();
|
points.rewind();
|
||||||
for (int i = 0; i < length; i++) {
|
for (int i = 0; i < length; i++) {
|
||||||
BufferUtils.populateFromBuffer(compVec1, points, i);
|
BufferUtils.populateFromBuffer(compVec1, points, i);
|
||||||
compVec1.subtract(origin, compVec2);
|
compVec1.subtract(origin, compVec2);
|
||||||
sumXX += compVec2.x * compVec2.x;
|
sumXX += compVec2.x * compVec2.x;
|
||||||
sumXY += compVec2.x * compVec2.y;
|
sumXY += compVec2.x * compVec2.y;
|
||||||
sumXZ += compVec2.x * compVec2.z;
|
sumXZ += compVec2.x * compVec2.z;
|
||||||
sumYY += compVec2.y * compVec2.y;
|
sumYY += compVec2.y * compVec2.y;
|
||||||
sumYZ += compVec2.y * compVec2.z;
|
sumYZ += compVec2.y * compVec2.z;
|
||||||
sumZZ += compVec2.z * compVec2.z;
|
sumZZ += compVec2.z * compVec2.z;
|
||||||
}
|
}
|
||||||
|
|
||||||
//find the smallest eigen vector for the direction vector
|
//find the smallest eigen vector for the direction vector
|
||||||
compMat1.m00 = sumYY + sumZZ;
|
compMat1.m00 = sumYY + sumZZ;
|
||||||
compMat1.m01 = -sumXY;
|
compMat1.m01 = -sumXY;
|
||||||
compMat1.m02 = -sumXZ;
|
compMat1.m02 = -sumXZ;
|
||||||
compMat1.m10 = -sumXY;
|
compMat1.m10 = -sumXY;
|
||||||
compMat1.m11 = sumXX + sumZZ;
|
compMat1.m11 = sumXX + sumZZ;
|
||||||
compMat1.m12 = -sumYZ;
|
compMat1.m12 = -sumYZ;
|
||||||
compMat1.m20 = -sumXZ;
|
compMat1.m20 = -sumXZ;
|
||||||
compMat1.m21 = -sumYZ;
|
compMat1.m21 = -sumYZ;
|
||||||
compMat1.m22 = sumXX + sumYY;
|
compMat1.m22 = sumXX + sumYY;
|
||||||
|
|
||||||
compEigen1.calculateEigen(compMat1);
|
compEigen1.calculateEigen(compMat1);
|
||||||
direction = compEigen1.getEigenVector(0);
|
direction = compEigen1.getEigenVector(0);
|
||||||
|
|
||||||
assert vars.unlock();
|
vars.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
@ -224,8 +223,8 @@ public class Line implements Savable, Cloneable {
|
|||||||
|
|
||||||
public void read(JmeImporter e) throws IOException {
|
public void read(JmeImporter e) throws IOException {
|
||||||
InputCapsule capsule = e.getCapsule(this);
|
InputCapsule capsule = e.getCapsule(this);
|
||||||
origin = (Vector3f)capsule.readSavable("origin", Vector3f.ZERO.clone());
|
origin = (Vector3f) capsule.readSavable("origin", Vector3f.ZERO.clone());
|
||||||
direction = (Vector3f)capsule.readSavable("direction", Vector3f.ZERO.clone());
|
direction = (Vector3f) capsule.readSavable("direction", Vector3f.ZERO.clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -110,8 +110,8 @@ public class LineSegment implements Cloneable, Savable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public float distanceSquared(Vector3f point) {
|
public float distanceSquared(Vector3f point) {
|
||||||
assert TempVars.get().lock();
|
TempVars vars = TempVars.get();
|
||||||
Vector3f compVec1 = TempVars.get().vect1;
|
Vector3f compVec1 = vars.vect1;
|
||||||
|
|
||||||
point.subtract(origin, compVec1);
|
point.subtract(origin, compVec1);
|
||||||
float segmentParameter = direction.dot(compVec1);
|
float segmentParameter = direction.dot(compVec1);
|
||||||
@ -129,20 +129,20 @@ public class LineSegment implements Cloneable, Savable {
|
|||||||
|
|
||||||
compVec1.subtractLocal(point);
|
compVec1.subtractLocal(point);
|
||||||
float len = compVec1.lengthSquared();
|
float len = compVec1.lengthSquared();
|
||||||
assert TempVars.get().unlock();
|
vars.release();
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
public float distanceSquared(LineSegment test) {
|
public float distanceSquared(LineSegment test) {
|
||||||
assert TempVars.get().lock();
|
TempVars vars = TempVars.get();
|
||||||
Vector3f compVec1 = TempVars.get().vect1;
|
Vector3f compVec1 = vars.vect1;
|
||||||
|
|
||||||
origin.subtract(test.getOrigin(), compVec1);
|
origin.subtract(test.getOrigin(), compVec1);
|
||||||
float negativeDirectionDot = -(direction.dot(test.getDirection()));
|
float negativeDirectionDot = -(direction.dot(test.getDirection()));
|
||||||
float diffThisDot = compVec1.dot(direction);
|
float diffThisDot = compVec1.dot(direction);
|
||||||
float diffTestDot = -(compVec1.dot(test.getDirection()));
|
float diffTestDot = -(compVec1.dot(test.getDirection()));
|
||||||
float lengthOfDiff = compVec1.lengthSquared();
|
float lengthOfDiff = compVec1.lengthSquared();
|
||||||
assert TempVars.get().unlock();
|
vars.release();
|
||||||
float determinant = FastMath.abs(1.0f - negativeDirectionDot
|
float determinant = FastMath.abs(1.0f - negativeDirectionDot
|
||||||
* negativeDirectionDot);
|
* negativeDirectionDot);
|
||||||
float s0, s1, squareDistance, extentDeterminant0, extentDeterminant1, tempS0, tempS1;
|
float s0, s1, squareDistance, extentDeterminant0, extentDeterminant1, tempS0, tempS1;
|
||||||
|
@ -29,7 +29,6 @@
|
|||||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.jme3.math;
|
package com.jme3.math;
|
||||||
|
|
||||||
import com.jme3.export.InputCapsule;
|
import com.jme3.export.InputCapsule;
|
||||||
@ -55,12 +54,10 @@ import java.util.logging.Logger;
|
|||||||
public final class Matrix3f implements Savable, Cloneable {
|
public final class Matrix3f implements Savable, Cloneable {
|
||||||
|
|
||||||
private static final Logger logger = Logger.getLogger(Matrix3f.class.getName());
|
private static final Logger logger = Logger.getLogger(Matrix3f.class.getName());
|
||||||
|
|
||||||
protected float m00, m01, m02;
|
protected float m00, m01, m02;
|
||||||
protected float m10, m11, m12;
|
protected float m10, m11, m12;
|
||||||
protected float m20, m21, m22;
|
protected float m20, m21, m22;
|
||||||
|
public static final Matrix3f ZERO = new Matrix3f(0, 0, 0, 0, 0, 0, 0, 0, 0);
|
||||||
public static final Matrix3f ZERO = new Matrix3f(0,0,0,0,0,0,0,0,0);
|
|
||||||
public static final Matrix3f IDENTITY = new Matrix3f();
|
public static final Matrix3f IDENTITY = new Matrix3f();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -174,24 +171,33 @@ public final class Matrix3f implements Savable, Cloneable {
|
|||||||
@SuppressWarnings("fallthrough")
|
@SuppressWarnings("fallthrough")
|
||||||
public float get(int i, int j) {
|
public float get(int i, int j) {
|
||||||
switch (i) {
|
switch (i) {
|
||||||
case 0:
|
case 0:
|
||||||
switch (j) {
|
switch (j) {
|
||||||
case 0: return m00;
|
case 0:
|
||||||
case 1: return m01;
|
return m00;
|
||||||
case 2: return m02;
|
case 1:
|
||||||
}
|
return m01;
|
||||||
case 1:
|
case 2:
|
||||||
switch (j) {
|
return m02;
|
||||||
case 0: return m10;
|
}
|
||||||
case 1: return m11;
|
case 1:
|
||||||
case 2: return m12;
|
switch (j) {
|
||||||
}
|
case 0:
|
||||||
case 2:
|
return m10;
|
||||||
switch (j) {
|
case 1:
|
||||||
case 0: return m20;
|
return m11;
|
||||||
case 1: return m21;
|
case 2:
|
||||||
case 2: return m22;
|
return m12;
|
||||||
}
|
}
|
||||||
|
case 2:
|
||||||
|
switch (j) {
|
||||||
|
case 0:
|
||||||
|
return m20;
|
||||||
|
case 1:
|
||||||
|
return m21;
|
||||||
|
case 2:
|
||||||
|
return m22;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.warning("Invalid matrix index.");
|
logger.warning("Invalid matrix index.");
|
||||||
@ -220,8 +226,7 @@ public final class Matrix3f implements Savable, Cloneable {
|
|||||||
data[6] = m20;
|
data[6] = m20;
|
||||||
data[7] = m21;
|
data[7] = m21;
|
||||||
data[8] = m22;
|
data[8] = m22;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
data[0] = m00;
|
data[0] = m00;
|
||||||
data[1] = m10;
|
data[1] = m10;
|
||||||
data[2] = m20;
|
data[2] = m20;
|
||||||
@ -232,8 +237,7 @@ public final class Matrix3f implements Savable, Cloneable {
|
|||||||
data[7] = m12;
|
data[7] = m12;
|
||||||
data[8] = m22;
|
data[8] = m22;
|
||||||
}
|
}
|
||||||
}
|
} else if (data.length == 16) {
|
||||||
else if (data.length == 16) {
|
|
||||||
if (rowMajor) {
|
if (rowMajor) {
|
||||||
data[0] = m00;
|
data[0] = m00;
|
||||||
data[1] = m01;
|
data[1] = m01;
|
||||||
@ -244,8 +248,7 @@ public final class Matrix3f implements Savable, Cloneable {
|
|||||||
data[8] = m20;
|
data[8] = m20;
|
||||||
data[9] = m21;
|
data[9] = m21;
|
||||||
data[10] = m22;
|
data[10] = m22;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
data[0] = m00;
|
data[0] = m00;
|
||||||
data[1] = m10;
|
data[1] = m10;
|
||||||
data[2] = m20;
|
data[2] = m20;
|
||||||
@ -256,8 +259,7 @@ public final class Matrix3f implements Savable, Cloneable {
|
|||||||
data[9] = m12;
|
data[9] = m12;
|
||||||
data[10] = m22;
|
data[10] = m22;
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
throw new IndexOutOfBoundsException("Array size must be 9 or 16 in Matrix3f.get().");
|
throw new IndexOutOfBoundsException("Array size must be 9 or 16 in Matrix3f.get().");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -286,26 +288,28 @@ public final class Matrix3f implements Savable, Cloneable {
|
|||||||
* @return the column specified by the index.
|
* @return the column specified by the index.
|
||||||
*/
|
*/
|
||||||
public Vector3f getColumn(int i, Vector3f store) {
|
public Vector3f getColumn(int i, Vector3f store) {
|
||||||
if (store == null) store = new Vector3f();
|
if (store == null) {
|
||||||
|
store = new Vector3f();
|
||||||
|
}
|
||||||
switch (i) {
|
switch (i) {
|
||||||
case 0:
|
case 0:
|
||||||
store.x = m00;
|
store.x = m00;
|
||||||
store.y = m10;
|
store.y = m10;
|
||||||
store.z = m20;
|
store.z = m20;
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
store.x = m01;
|
store.x = m01;
|
||||||
store.y = m11;
|
store.y = m11;
|
||||||
store.z = m21;
|
store.z = m21;
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
store.x = m02;
|
store.x = m02;
|
||||||
store.y = m12;
|
store.y = m12;
|
||||||
store.z = m22;
|
store.z = m22;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
logger.warning("Invalid column index.");
|
logger.warning("Invalid column index.");
|
||||||
throw new IllegalArgumentException("Invalid column index. " + i);
|
throw new IllegalArgumentException("Invalid column index. " + i);
|
||||||
}
|
}
|
||||||
return store;
|
return store;
|
||||||
}
|
}
|
||||||
@ -334,26 +338,28 @@ public final class Matrix3f implements Savable, Cloneable {
|
|||||||
* @return the row specified by the index.
|
* @return the row specified by the index.
|
||||||
*/
|
*/
|
||||||
public Vector3f getRow(int i, Vector3f store) {
|
public Vector3f getRow(int i, Vector3f store) {
|
||||||
if (store == null) store = new Vector3f();
|
if (store == null) {
|
||||||
|
store = new Vector3f();
|
||||||
|
}
|
||||||
switch (i) {
|
switch (i) {
|
||||||
case 0:
|
case 0:
|
||||||
store.x = m00;
|
store.x = m00;
|
||||||
store.y = m01;
|
store.y = m01;
|
||||||
store.z = m02;
|
store.z = m02;
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
store.x = m10;
|
store.x = m10;
|
||||||
store.y = m11;
|
store.y = m11;
|
||||||
store.z = m12;
|
store.z = m12;
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
store.x = m20;
|
store.x = m20;
|
||||||
store.y = m21;
|
store.y = m21;
|
||||||
store.z = m22;
|
store.z = m22;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
logger.warning("Invalid row index.");
|
logger.warning("Invalid row index.");
|
||||||
throw new IllegalArgumentException("Invalid row index. " + i);
|
throw new IllegalArgumentException("Invalid row index. " + i);
|
||||||
}
|
}
|
||||||
return store;
|
return store;
|
||||||
}
|
}
|
||||||
@ -396,17 +402,17 @@ public final class Matrix3f implements Savable, Cloneable {
|
|||||||
// }
|
// }
|
||||||
|
|
||||||
TempVars vars = TempVars.get();
|
TempVars vars = TempVars.get();
|
||||||
assert vars.lock();
|
|
||||||
|
|
||||||
fillFloatArray(vars.matrixWrite, columnMajor);
|
fillFloatArray(vars.matrixWrite, columnMajor);
|
||||||
fb.put(vars.matrixWrite, 0, 9);
|
fb.put(vars.matrixWrite, 0, 9);
|
||||||
|
|
||||||
assert vars.unlock();
|
vars.release();
|
||||||
|
|
||||||
return fb;
|
return fb;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void fillFloatArray(float[] f, boolean columnMajor){
|
public void fillFloatArray(float[] f, boolean columnMajor) {
|
||||||
if (columnMajor) {
|
if (columnMajor) {
|
||||||
f[ 0] = m00;
|
f[ 0] = m00;
|
||||||
f[ 1] = m10;
|
f[ 1] = m10;
|
||||||
@ -417,7 +423,7 @@ public final class Matrix3f implements Savable, Cloneable {
|
|||||||
f[ 6] = m02;
|
f[ 6] = m02;
|
||||||
f[ 7] = m12;
|
f[ 7] = m12;
|
||||||
f[ 8] = m22;
|
f[ 8] = m22;
|
||||||
}else{
|
} else {
|
||||||
f[ 0] = m00;
|
f[ 0] = m00;
|
||||||
f[ 1] = m01;
|
f[ 1] = m01;
|
||||||
f[ 2] = m02;
|
f[ 2] = m02;
|
||||||
@ -448,29 +454,28 @@ public final class Matrix3f implements Savable, Cloneable {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
switch (i) {
|
switch (i) {
|
||||||
case 0:
|
case 0:
|
||||||
m00 = column.x;
|
m00 = column.x;
|
||||||
m10 = column.y;
|
m10 = column.y;
|
||||||
m20 = column.z;
|
m20 = column.z;
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
m01 = column.x;
|
m01 = column.x;
|
||||||
m11 = column.y;
|
m11 = column.y;
|
||||||
m21 = column.z;
|
m21 = column.z;
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
m02 = column.x;
|
m02 = column.x;
|
||||||
m12 = column.y;
|
m12 = column.y;
|
||||||
m22 = column.z;
|
m22 = column.z;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
logger.warning("Invalid column index.");
|
logger.warning("Invalid column index.");
|
||||||
throw new IllegalArgumentException("Invalid column index. " + i);
|
throw new IllegalArgumentException("Invalid column index. " + i);
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* <code>setRow</code> sets a particular row of this matrix to that
|
* <code>setRow</code> sets a particular row of this matrix to that
|
||||||
@ -489,24 +494,24 @@ public final class Matrix3f implements Savable, Cloneable {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
switch (i) {
|
switch (i) {
|
||||||
case 0:
|
case 0:
|
||||||
m00 = row.x;
|
m00 = row.x;
|
||||||
m01 = row.y;
|
m01 = row.y;
|
||||||
m02 = row.z;
|
m02 = row.z;
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
m10 = row.x;
|
m10 = row.x;
|
||||||
m11 = row.y;
|
m11 = row.y;
|
||||||
m12 = row.z;
|
m12 = row.z;
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
m20 = row.x;
|
m20 = row.x;
|
||||||
m21 = row.y;
|
m21 = row.y;
|
||||||
m22 = row.z;
|
m22 = row.z;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
logger.warning("Invalid row index.");
|
logger.warning("Invalid row index.");
|
||||||
throw new IllegalArgumentException("Invalid row index. " + i);
|
throw new IllegalArgumentException("Invalid row index. " + i);
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@ -527,24 +532,42 @@ public final class Matrix3f implements Savable, Cloneable {
|
|||||||
@SuppressWarnings("fallthrough")
|
@SuppressWarnings("fallthrough")
|
||||||
public Matrix3f set(int i, int j, float value) {
|
public Matrix3f set(int i, int j, float value) {
|
||||||
switch (i) {
|
switch (i) {
|
||||||
case 0:
|
case 0:
|
||||||
switch (j) {
|
switch (j) {
|
||||||
case 0: m00 = value; return this;
|
case 0:
|
||||||
case 1: m01 = value; return this;
|
m00 = value;
|
||||||
case 2: m02 = value; return this;
|
return this;
|
||||||
}
|
case 1:
|
||||||
case 1:
|
m01 = value;
|
||||||
switch (j) {
|
return this;
|
||||||
case 0: m10 = value; return this;
|
case 2:
|
||||||
case 1: m11 = value; return this;
|
m02 = value;
|
||||||
case 2: m12 = value; return this;
|
return this;
|
||||||
}
|
}
|
||||||
case 2:
|
case 1:
|
||||||
switch (j) {
|
switch (j) {
|
||||||
case 0: m20 = value; return this;
|
case 0:
|
||||||
case 1: m21 = value; return this;
|
m10 = value;
|
||||||
case 2: m22 = value; return this;
|
return this;
|
||||||
}
|
case 1:
|
||||||
|
m11 = value;
|
||||||
|
return this;
|
||||||
|
case 2:
|
||||||
|
m12 = value;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
case 2:
|
||||||
|
switch (j) {
|
||||||
|
case 0:
|
||||||
|
m20 = value;
|
||||||
|
return this;
|
||||||
|
case 1:
|
||||||
|
m21 = value;
|
||||||
|
return this;
|
||||||
|
case 2:
|
||||||
|
m22 = value;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.warning("Invalid matrix index.");
|
logger.warning("Invalid matrix index.");
|
||||||
@ -563,8 +586,10 @@ public final class Matrix3f implements Savable, Cloneable {
|
|||||||
* @return this
|
* @return this
|
||||||
*/
|
*/
|
||||||
public Matrix3f set(float[][] matrix) {
|
public Matrix3f set(float[][] matrix) {
|
||||||
if (matrix.length != 3 || matrix[0].length != 3) { throw new IllegalArgumentException(
|
if (matrix.length != 3 || matrix[0].length != 3) {
|
||||||
"Array must be of size 9."); }
|
throw new IllegalArgumentException(
|
||||||
|
"Array must be of size 9.");
|
||||||
|
}
|
||||||
|
|
||||||
m00 = matrix[0][0];
|
m00 = matrix[0][0];
|
||||||
m01 = matrix[0][1];
|
m01 = matrix[0][1];
|
||||||
@ -626,29 +651,31 @@ public final class Matrix3f implements Savable, Cloneable {
|
|||||||
* @return this
|
* @return this
|
||||||
*/
|
*/
|
||||||
public Matrix3f set(float[] matrix, boolean rowMajor) {
|
public Matrix3f set(float[] matrix, boolean rowMajor) {
|
||||||
if (matrix.length != 9) throw new IllegalArgumentException(
|
if (matrix.length != 9) {
|
||||||
"Array must be of size 9.");
|
throw new IllegalArgumentException(
|
||||||
|
"Array must be of size 9.");
|
||||||
|
}
|
||||||
|
|
||||||
if (rowMajor) {
|
if (rowMajor) {
|
||||||
m00 = matrix[0];
|
m00 = matrix[0];
|
||||||
m01 = matrix[1];
|
m01 = matrix[1];
|
||||||
m02 = matrix[2];
|
m02 = matrix[2];
|
||||||
m10 = matrix[3];
|
m10 = matrix[3];
|
||||||
m11 = matrix[4];
|
m11 = matrix[4];
|
||||||
m12 = matrix[5];
|
m12 = matrix[5];
|
||||||
m20 = matrix[6];
|
m20 = matrix[6];
|
||||||
m21 = matrix[7];
|
m21 = matrix[7];
|
||||||
m22 = matrix[8];
|
m22 = matrix[8];
|
||||||
} else {
|
} else {
|
||||||
m00 = matrix[0];
|
m00 = matrix[0];
|
||||||
m01 = matrix[3];
|
m01 = matrix[3];
|
||||||
m02 = matrix[6];
|
m02 = matrix[6];
|
||||||
m10 = matrix[1];
|
m10 = matrix[1];
|
||||||
m11 = matrix[4];
|
m11 = matrix[4];
|
||||||
m12 = matrix[7];
|
m12 = matrix[7];
|
||||||
m20 = matrix[2];
|
m20 = matrix[2];
|
||||||
m21 = matrix[5];
|
m21 = matrix[5];
|
||||||
m22 = matrix[8];
|
m22 = matrix[8];
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@ -681,10 +708,9 @@ public final class Matrix3f implements Savable, Cloneable {
|
|||||||
* @return true if this matrix is identity
|
* @return true if this matrix is identity
|
||||||
*/
|
*/
|
||||||
public boolean isIdentity() {
|
public boolean isIdentity() {
|
||||||
return
|
return (m00 == 1 && m01 == 0 && m02 == 0)
|
||||||
(m00 == 1 && m01 == 0 && m02 == 0) &&
|
&& (m10 == 0 && m11 == 1 && m12 == 0)
|
||||||
(m10 == 0 && m11 == 1 && m12 == 0) &&
|
&& (m20 == 0 && m21 == 0 && m22 == 1);
|
||||||
(m20 == 0 && m21 == 0 && m22 == 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -714,26 +740,26 @@ public final class Matrix3f implements Savable, Cloneable {
|
|||||||
public void fromAngleNormalAxis(float angle, Vector3f axis) {
|
public void fromAngleNormalAxis(float angle, Vector3f axis) {
|
||||||
float fCos = FastMath.cos(angle);
|
float fCos = FastMath.cos(angle);
|
||||||
float fSin = FastMath.sin(angle);
|
float fSin = FastMath.sin(angle);
|
||||||
float fOneMinusCos = ((float)1.0)-fCos;
|
float fOneMinusCos = ((float) 1.0) - fCos;
|
||||||
float fX2 = axis.x*axis.x;
|
float fX2 = axis.x * axis.x;
|
||||||
float fY2 = axis.y*axis.y;
|
float fY2 = axis.y * axis.y;
|
||||||
float fZ2 = axis.z*axis.z;
|
float fZ2 = axis.z * axis.z;
|
||||||
float fXYM = axis.x*axis.y*fOneMinusCos;
|
float fXYM = axis.x * axis.y * fOneMinusCos;
|
||||||
float fXZM = axis.x*axis.z*fOneMinusCos;
|
float fXZM = axis.x * axis.z * fOneMinusCos;
|
||||||
float fYZM = axis.y*axis.z*fOneMinusCos;
|
float fYZM = axis.y * axis.z * fOneMinusCos;
|
||||||
float fXSin = axis.x*fSin;
|
float fXSin = axis.x * fSin;
|
||||||
float fYSin = axis.y*fSin;
|
float fYSin = axis.y * fSin;
|
||||||
float fZSin = axis.z*fSin;
|
float fZSin = axis.z * fSin;
|
||||||
|
|
||||||
m00 = fX2*fOneMinusCos+fCos;
|
m00 = fX2 * fOneMinusCos + fCos;
|
||||||
m01 = fXYM-fZSin;
|
m01 = fXYM - fZSin;
|
||||||
m02 = fXZM+fYSin;
|
m02 = fXZM + fYSin;
|
||||||
m10 = fXYM+fZSin;
|
m10 = fXYM + fZSin;
|
||||||
m11 = fY2*fOneMinusCos+fCos;
|
m11 = fY2 * fOneMinusCos + fCos;
|
||||||
m12 = fYZM-fXSin;
|
m12 = fYZM - fXSin;
|
||||||
m20 = fXZM-fYSin;
|
m20 = fXZM - fYSin;
|
||||||
m21 = fYZM+fXSin;
|
m21 = fYZM + fXSin;
|
||||||
m22 = fZ2*fOneMinusCos+fCos;
|
m22 = fZ2 * fOneMinusCos + fCos;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -766,7 +792,9 @@ public final class Matrix3f implements Savable, Cloneable {
|
|||||||
float temp10, temp11, temp12;
|
float temp10, temp11, temp12;
|
||||||
float temp20, temp21, temp22;
|
float temp20, temp21, temp22;
|
||||||
|
|
||||||
if (product == null) product = new Matrix3f();
|
if (product == null) {
|
||||||
|
product = new Matrix3f();
|
||||||
|
}
|
||||||
temp00 = m00 * mat.m00 + m01 * mat.m10 + m02 * mat.m20;
|
temp00 = m00 * mat.m00 + m01 * mat.m10 + m02 * mat.m20;
|
||||||
temp01 = m00 * mat.m01 + m01 * mat.m11 + m02 * mat.m21;
|
temp01 = m00 * mat.m01 + m01 * mat.m11 + m02 * mat.m21;
|
||||||
temp02 = m00 * mat.m02 + m01 * mat.m12 + m02 * mat.m22;
|
temp02 = m00 * mat.m02 + m01 * mat.m12 + m02 * mat.m22;
|
||||||
@ -862,7 +890,9 @@ public final class Matrix3f implements Savable, Cloneable {
|
|||||||
* @return The passed vector after multiplication
|
* @return The passed vector after multiplication
|
||||||
*/
|
*/
|
||||||
public Vector3f multLocal(Vector3f vec) {
|
public Vector3f multLocal(Vector3f vec) {
|
||||||
if (vec == null) return null;
|
if (vec == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
float x = vec.x;
|
float x = vec.x;
|
||||||
float y = vec.y;
|
float y = vec.y;
|
||||||
vec.x = m00 * x + m01 * y + m02 * vec.z;
|
vec.x = m00 * x + m01 * y + m02 * vec.z;
|
||||||
@ -925,23 +955,26 @@ public final class Matrix3f implements Savable, Cloneable {
|
|||||||
* @return The store
|
* @return The store
|
||||||
*/
|
*/
|
||||||
public Matrix3f invert(Matrix3f store) {
|
public Matrix3f invert(Matrix3f store) {
|
||||||
if (store == null) store = new Matrix3f();
|
if (store == null) {
|
||||||
|
store = new Matrix3f();
|
||||||
|
}
|
||||||
|
|
||||||
float det = determinant();
|
float det = determinant();
|
||||||
if ( FastMath.abs(det) <= FastMath.FLT_EPSILON )
|
if (FastMath.abs(det) <= FastMath.FLT_EPSILON) {
|
||||||
return store.zero();
|
return store.zero();
|
||||||
|
}
|
||||||
|
|
||||||
store.m00 = m11*m22 - m12*m21;
|
store.m00 = m11 * m22 - m12 * m21;
|
||||||
store.m01 = m02*m21 - m01*m22;
|
store.m01 = m02 * m21 - m01 * m22;
|
||||||
store.m02 = m01*m12 - m02*m11;
|
store.m02 = m01 * m12 - m02 * m11;
|
||||||
store.m10 = m12*m20 - m10*m22;
|
store.m10 = m12 * m20 - m10 * m22;
|
||||||
store.m11 = m00*m22 - m02*m20;
|
store.m11 = m00 * m22 - m02 * m20;
|
||||||
store.m12 = m02*m10 - m00*m12;
|
store.m12 = m02 * m10 - m00 * m12;
|
||||||
store.m20 = m10*m21 - m11*m20;
|
store.m20 = m10 * m21 - m11 * m20;
|
||||||
store.m21 = m01*m20 - m00*m21;
|
store.m21 = m01 * m20 - m00 * m21;
|
||||||
store.m22 = m00*m11 - m01*m10;
|
store.m22 = m00 * m11 - m01 * m10;
|
||||||
|
|
||||||
store.multLocal(1f/det);
|
store.multLocal(1f / det);
|
||||||
return store;
|
return store;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -952,18 +985,19 @@ public final class Matrix3f implements Savable, Cloneable {
|
|||||||
*/
|
*/
|
||||||
public Matrix3f invertLocal() {
|
public Matrix3f invertLocal() {
|
||||||
float det = determinant();
|
float det = determinant();
|
||||||
if ( FastMath.abs(det) <= FastMath.FLT_EPSILON )
|
if (FastMath.abs(det) <= FastMath.FLT_EPSILON) {
|
||||||
return zero();
|
return zero();
|
||||||
|
}
|
||||||
|
|
||||||
float f00 = m11*m22 - m12*m21;
|
float f00 = m11 * m22 - m12 * m21;
|
||||||
float f01 = m02*m21 - m01*m22;
|
float f01 = m02 * m21 - m01 * m22;
|
||||||
float f02 = m01*m12 - m02*m11;
|
float f02 = m01 * m12 - m02 * m11;
|
||||||
float f10 = m12*m20 - m10*m22;
|
float f10 = m12 * m20 - m10 * m22;
|
||||||
float f11 = m00*m22 - m02*m20;
|
float f11 = m00 * m22 - m02 * m20;
|
||||||
float f12 = m02*m10 - m00*m12;
|
float f12 = m02 * m10 - m00 * m12;
|
||||||
float f20 = m10*m21 - m11*m20;
|
float f20 = m10 * m21 - m11 * m20;
|
||||||
float f21 = m01*m20 - m00*m21;
|
float f21 = m01 * m20 - m00 * m21;
|
||||||
float f22 = m00*m11 - m01*m10;
|
float f22 = m00 * m11 - m01 * m10;
|
||||||
|
|
||||||
m00 = f00;
|
m00 = f00;
|
||||||
m01 = f01;
|
m01 = f01;
|
||||||
@ -975,7 +1009,7 @@ public final class Matrix3f implements Savable, Cloneable {
|
|||||||
m21 = f21;
|
m21 = f21;
|
||||||
m22 = f22;
|
m22 = f22;
|
||||||
|
|
||||||
multLocal(1f/det);
|
multLocal(1f / det);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -996,17 +1030,19 @@ public final class Matrix3f implements Savable, Cloneable {
|
|||||||
* @return store
|
* @return store
|
||||||
*/
|
*/
|
||||||
public Matrix3f adjoint(Matrix3f store) {
|
public Matrix3f adjoint(Matrix3f store) {
|
||||||
if (store == null) store = new Matrix3f();
|
if (store == null) {
|
||||||
|
store = new Matrix3f();
|
||||||
|
}
|
||||||
|
|
||||||
store.m00 = m11*m22 - m12*m21;
|
store.m00 = m11 * m22 - m12 * m21;
|
||||||
store.m01 = m02*m21 - m01*m22;
|
store.m01 = m02 * m21 - m01 * m22;
|
||||||
store.m02 = m01*m12 - m02*m11;
|
store.m02 = m01 * m12 - m02 * m11;
|
||||||
store.m10 = m12*m20 - m10*m22;
|
store.m10 = m12 * m20 - m10 * m22;
|
||||||
store.m11 = m00*m22 - m02*m20;
|
store.m11 = m00 * m22 - m02 * m20;
|
||||||
store.m12 = m02*m10 - m00*m12;
|
store.m12 = m02 * m10 - m00 * m12;
|
||||||
store.m20 = m10*m21 - m11*m20;
|
store.m20 = m10 * m21 - m11 * m20;
|
||||||
store.m21 = m01*m20 - m00*m21;
|
store.m21 = m01 * m20 - m00 * m21;
|
||||||
store.m22 = m00*m11 - m01*m10;
|
store.m22 = m00 * m11 - m01 * m10;
|
||||||
|
|
||||||
return store;
|
return store;
|
||||||
}
|
}
|
||||||
@ -1017,10 +1053,10 @@ public final class Matrix3f implements Savable, Cloneable {
|
|||||||
* @return the determinate
|
* @return the determinate
|
||||||
*/
|
*/
|
||||||
public float determinant() {
|
public float determinant() {
|
||||||
float fCo00 = m11*m22 - m12*m21;
|
float fCo00 = m11 * m22 - m12 * m21;
|
||||||
float fCo10 = m12*m20 - m10*m22;
|
float fCo10 = m12 * m20 - m10 * m22;
|
||||||
float fCo20 = m10*m21 - m11*m20;
|
float fCo20 = m10 * m21 - m11 * m20;
|
||||||
float fDet = m00*fCo00 + m01*fCo10 + m02*fCo20;
|
float fDet = m00 * fCo00 + m01 * fCo10 + m02 * fCo20;
|
||||||
return fDet;
|
return fDet;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1138,17 +1174,35 @@ public final class Matrix3f implements Savable, Cloneable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Matrix3f comp = (Matrix3f) o;
|
Matrix3f comp = (Matrix3f) o;
|
||||||
if (Float.compare(m00,comp.m00) != 0) return false;
|
if (Float.compare(m00, comp.m00) != 0) {
|
||||||
if (Float.compare(m01,comp.m01) != 0) return false;
|
return false;
|
||||||
if (Float.compare(m02,comp.m02) != 0) return false;
|
}
|
||||||
|
if (Float.compare(m01, comp.m01) != 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (Float.compare(m02, comp.m02) != 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (Float.compare(m10,comp.m10) != 0) return false;
|
if (Float.compare(m10, comp.m10) != 0) {
|
||||||
if (Float.compare(m11,comp.m11) != 0) return false;
|
return false;
|
||||||
if (Float.compare(m12,comp.m12) != 0) return false;
|
}
|
||||||
|
if (Float.compare(m11, comp.m11) != 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (Float.compare(m12, comp.m12) != 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (Float.compare(m20,comp.m20) != 0) return false;
|
if (Float.compare(m20, comp.m20) != 0) {
|
||||||
if (Float.compare(m21,comp.m21) != 0) return false;
|
return false;
|
||||||
if (Float.compare(m22,comp.m22) != 0) return false;
|
}
|
||||||
|
if (Float.compare(m21, comp.m21) != 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (Float.compare(m22, comp.m22) != 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -1278,32 +1332,50 @@ public final class Matrix3f implements Savable, Cloneable {
|
|||||||
* The scale applied to each of the X, Y and Z output values.
|
* The scale applied to each of the X, Y and Z output values.
|
||||||
*/
|
*/
|
||||||
public void scale(Vector3f scale) {
|
public void scale(Vector3f scale) {
|
||||||
m00 *= scale.x;
|
m00 *= scale.x;
|
||||||
m10 *= scale.x;
|
m10 *= scale.x;
|
||||||
m20 *= scale.x;
|
m20 *= scale.x;
|
||||||
m01 *= scale.y;
|
m01 *= scale.y;
|
||||||
m11 *= scale.y;
|
m11 *= scale.y;
|
||||||
m21 *= scale.y;
|
m21 *= scale.y;
|
||||||
m02 *= scale.z;
|
m02 *= scale.z;
|
||||||
m12 *= scale.z;
|
m12 *= scale.z;
|
||||||
m22 *= scale.z;
|
m22 *= scale.z;
|
||||||
}
|
}
|
||||||
|
|
||||||
static boolean equalIdentity(Matrix3f mat) {
|
static boolean equalIdentity(Matrix3f mat) {
|
||||||
if (Math.abs(mat.m00 - 1) > 1e-4) return false;
|
if (Math.abs(mat.m00 - 1) > 1e-4) {
|
||||||
if (Math.abs(mat.m11 - 1) > 1e-4) return false;
|
return false;
|
||||||
if (Math.abs(mat.m22 - 1) > 1e-4) return false;
|
}
|
||||||
|
if (Math.abs(mat.m11 - 1) > 1e-4) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (Math.abs(mat.m22 - 1) > 1e-4) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (Math.abs(mat.m01) > 1e-4) return false;
|
if (Math.abs(mat.m01) > 1e-4) {
|
||||||
if (Math.abs(mat.m02) > 1e-4) return false;
|
return false;
|
||||||
|
}
|
||||||
|
if (Math.abs(mat.m02) > 1e-4) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (Math.abs(mat.m10) > 1e-4) return false;
|
if (Math.abs(mat.m10) > 1e-4) {
|
||||||
if (Math.abs(mat.m12) > 1e-4) return false;
|
return false;
|
||||||
|
}
|
||||||
|
if (Math.abs(mat.m12) > 1e-4) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (Math.abs(mat.m20) > 1e-4) return false;
|
if (Math.abs(mat.m20) > 1e-4) {
|
||||||
if (Math.abs(mat.m21) > 1e-4) return false;
|
return false;
|
||||||
|
}
|
||||||
|
if (Math.abs(mat.m21) > 1e-4) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -159,7 +159,6 @@ public final class Matrix4f implements Savable, Cloneable {
|
|||||||
loadIdentity();
|
loadIdentity();
|
||||||
|
|
||||||
TempVars vars = TempVars.get();
|
TempVars vars = TempVars.get();
|
||||||
assert vars.lock();
|
|
||||||
|
|
||||||
Vector3f f = vars.vect1.set(direction);
|
Vector3f f = vars.vect1.set(direction);
|
||||||
Vector3f s = vars.vect2.set(f).crossLocal(up);
|
Vector3f s = vars.vect2.set(f).crossLocal(up);
|
||||||
@ -192,14 +191,14 @@ public final class Matrix4f implements Savable, Cloneable {
|
|||||||
// m22 = -direction.z;
|
// m22 = -direction.z;
|
||||||
//
|
//
|
||||||
|
|
||||||
Matrix4f transMatrix = TempVars.get().tempMat4;
|
Matrix4f transMatrix = vars.tempMat4;
|
||||||
transMatrix.loadIdentity();
|
transMatrix.loadIdentity();
|
||||||
transMatrix.m03 = -location.x;
|
transMatrix.m03 = -location.x;
|
||||||
transMatrix.m13 = -location.y;
|
transMatrix.m13 = -location.y;
|
||||||
transMatrix.m23 = -location.z;
|
transMatrix.m23 = -location.z;
|
||||||
this.multLocal(transMatrix);
|
this.multLocal(transMatrix);
|
||||||
|
|
||||||
assert TempVars.get().unlock();
|
vars.release();
|
||||||
|
|
||||||
// transMatrix.multLocal(this);
|
// transMatrix.multLocal(this);
|
||||||
|
|
||||||
@ -746,12 +745,12 @@ public final class Matrix4f implements Savable, Cloneable {
|
|||||||
// }
|
// }
|
||||||
|
|
||||||
TempVars vars = TempVars.get();
|
TempVars vars = TempVars.get();
|
||||||
assert vars.lock();
|
|
||||||
|
|
||||||
fillFloatArray(vars.matrixWrite, columnMajor);
|
fillFloatArray(vars.matrixWrite, columnMajor);
|
||||||
fb.put(vars.matrixWrite, 0, 16);
|
fb.put(vars.matrixWrite, 0, 16);
|
||||||
|
|
||||||
assert vars.unlock();
|
vars.release();
|
||||||
|
|
||||||
return fb;
|
return fb;
|
||||||
}
|
}
|
||||||
|
@ -1276,12 +1276,11 @@ public final class Quaternion implements Savable, Cloneable {
|
|||||||
*/
|
*/
|
||||||
public void lookAt(Vector3f direction, Vector3f up) {
|
public void lookAt(Vector3f direction, Vector3f up) {
|
||||||
TempVars vars = TempVars.get();
|
TempVars vars = TempVars.get();
|
||||||
assert vars.lock();
|
|
||||||
vars.vect3.set(direction).normalizeLocal();
|
vars.vect3.set(direction).normalizeLocal();
|
||||||
vars.vect1.set(up).crossLocal(direction).normalizeLocal();
|
vars.vect1.set(up).crossLocal(direction).normalizeLocal();
|
||||||
vars.vect2.set(direction).crossLocal(vars.vect1).normalizeLocal();
|
vars.vect2.set(direction).crossLocal(vars.vect1).normalizeLocal();
|
||||||
fromAxes(vars.vect1, vars.vect2, vars.vect3);
|
fromAxes(vars.vect1, vars.vect2, vars.vect3);
|
||||||
assert vars.unlock();
|
vars.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void write(JmeExporter e) throws IOException {
|
public void write(JmeExporter e) throws IOException {
|
||||||
|
@ -29,7 +29,6 @@
|
|||||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.jme3.math;
|
package com.jme3.math;
|
||||||
|
|
||||||
import com.jme3.bounding.BoundingVolume;
|
import com.jme3.bounding.BoundingVolume;
|
||||||
@ -45,7 +44,6 @@ import com.jme3.export.Savable;
|
|||||||
import com.jme3.util.TempVars;
|
import com.jme3.util.TempVars;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <code>Ray</code> defines a line segment which has an origin and a direction.
|
* <code>Ray</code> defines a line segment which has an origin and a direction.
|
||||||
* That is, a point and an infinite ray is cast from this point. The ray is
|
* That is, a point and an infinite ray is cast from this point. The ray is
|
||||||
@ -57,19 +55,16 @@ import java.io.IOException;
|
|||||||
public final class Ray implements Savable, Cloneable, Collidable {
|
public final class Ray implements Savable, Cloneable, Collidable {
|
||||||
|
|
||||||
//todo: merge with Line?
|
//todo: merge with Line?
|
||||||
|
|
||||||
/** The ray's begining point. */
|
/** The ray's begining point. */
|
||||||
public Vector3f origin;
|
public Vector3f origin;
|
||||||
/** The direction of the ray. */
|
/** The direction of the ray. */
|
||||||
public Vector3f direction;
|
public Vector3f direction;
|
||||||
|
|
||||||
public float limit = Float.POSITIVE_INFINITY;
|
public float limit = Float.POSITIVE_INFINITY;
|
||||||
|
|
||||||
// protected static final Vector3f tempVa=new Vector3f();
|
// protected static final Vector3f tempVa=new Vector3f();
|
||||||
// protected static final Vector3f tempVb=new Vector3f();
|
// protected static final Vector3f tempVb=new Vector3f();
|
||||||
// protected static final Vector3f tempVc=new Vector3f();
|
// protected static final Vector3f tempVc=new Vector3f();
|
||||||
// protected static final Vector3f tempVd=new Vector3f();
|
// protected static final Vector3f tempVd=new Vector3f();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor instantiates a new <code>Ray</code> object. As default, the
|
* Constructor instantiates a new <code>Ray</code> object. As default, the
|
||||||
* origin is (0,0,0) and the direction is (0,0,0).
|
* origin is (0,0,0) and the direction is (0,0,0).
|
||||||
@ -99,7 +94,6 @@ public final class Ray implements Savable, Cloneable, Collidable {
|
|||||||
// public boolean intersect(Triangle t) {
|
// public boolean intersect(Triangle t) {
|
||||||
// return intersect(t.get(0), t.get(1), t.get(2));
|
// return intersect(t.get(0), t.get(1), t.get(2));
|
||||||
// }
|
// }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <code>intersect</code> determines if the Ray intersects a triangle
|
* <code>intersect</code> determines if the Ray intersects a triangle
|
||||||
* defined by the specified points.
|
* defined by the specified points.
|
||||||
@ -115,7 +109,6 @@ public final class Ray implements Savable, Cloneable, Collidable {
|
|||||||
// public boolean intersect(Vector3f v0,Vector3f v1,Vector3f v2){
|
// public boolean intersect(Vector3f v0,Vector3f v1,Vector3f v2){
|
||||||
// return intersectWhere(v0, v1, v2, null);
|
// return intersectWhere(v0, v1, v2, null);
|
||||||
// }
|
// }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <code>intersectWhere</code> determines if the Ray intersects a triangle. It then
|
* <code>intersectWhere</code> determines if the Ray intersects a triangle. It then
|
||||||
* stores the point of intersection in the given loc vector
|
* stores the point of intersection in the given loc vector
|
||||||
@ -146,8 +139,8 @@ public final class Ray implements Savable, Cloneable, Collidable {
|
|||||||
* @return true if the ray collides.
|
* @return true if the ray collides.
|
||||||
*/
|
*/
|
||||||
public boolean intersectWhere(Vector3f v0, Vector3f v1, Vector3f v2,
|
public boolean intersectWhere(Vector3f v0, Vector3f v1, Vector3f v2,
|
||||||
Vector3f loc) {
|
Vector3f loc) {
|
||||||
return intersects(v0, v1, v2, loc, false, false );
|
return intersects(v0, v1, v2, loc, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -186,8 +179,8 @@ public final class Ray implements Savable, Cloneable, Collidable {
|
|||||||
* @return true if the ray collides.
|
* @return true if the ray collides.
|
||||||
*/
|
*/
|
||||||
public boolean intersectWherePlanar(Vector3f v0, Vector3f v1, Vector3f v2,
|
public boolean intersectWherePlanar(Vector3f v0, Vector3f v1, Vector3f v2,
|
||||||
Vector3f loc) {
|
Vector3f loc) {
|
||||||
return intersects(v0, v1, v2, loc, true, false );
|
return intersects(v0, v1, v2, loc, true, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -206,15 +199,14 @@ public final class Ray implements Savable, Cloneable, Collidable {
|
|||||||
* @param quad
|
* @param quad
|
||||||
* @return true if ray intersects triangle
|
* @return true if ray intersects triangle
|
||||||
*/
|
*/
|
||||||
private boolean intersects( Vector3f v0, Vector3f v1, Vector3f v2,
|
private boolean intersects(Vector3f v0, Vector3f v1, Vector3f v2,
|
||||||
Vector3f store, boolean doPlanar, boolean quad ) {
|
Vector3f store, boolean doPlanar, boolean quad) {
|
||||||
TempVars vars = TempVars.get();
|
TempVars vars = TempVars.get();
|
||||||
assert vars.lock();
|
|
||||||
|
|
||||||
Vector3f tempVa = vars.vect1,
|
Vector3f tempVa = vars.vect1,
|
||||||
tempVb = vars.vect2,
|
tempVb = vars.vect2,
|
||||||
tempVc = vars.vect3,
|
tempVc = vars.vect3,
|
||||||
tempVd = vars.vect4;
|
tempVd = vars.vect4;
|
||||||
|
|
||||||
Vector3f diff = origin.subtract(v0, tempVa);
|
Vector3f diff = origin.subtract(v0, tempVa);
|
||||||
Vector3f edge1 = v1.subtract(v0, tempVb);
|
Vector3f edge1 = v1.subtract(v0, tempVb);
|
||||||
@ -230,7 +222,7 @@ public final class Ray implements Savable, Cloneable, Collidable {
|
|||||||
dirDotNorm = -dirDotNorm;
|
dirDotNorm = -dirDotNorm;
|
||||||
} else {
|
} else {
|
||||||
// ray and triangle/quad are parallel
|
// ray and triangle/quad are parallel
|
||||||
assert vars.unlock();
|
vars.release();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -240,16 +232,17 @@ public final class Ray implements Savable, Cloneable, Collidable {
|
|||||||
* direction.dot(edge1.crossLocal(diff));
|
* direction.dot(edge1.crossLocal(diff));
|
||||||
|
|
||||||
if (dirDotEdge1xDiff >= 0.0f) {
|
if (dirDotEdge1xDiff >= 0.0f) {
|
||||||
if ( !quad ? dirDotDiffxEdge2 + dirDotEdge1xDiff <= dirDotNorm : dirDotEdge1xDiff <= dirDotNorm ) {
|
if (!quad ? dirDotDiffxEdge2 + dirDotEdge1xDiff <= dirDotNorm : dirDotEdge1xDiff <= dirDotNorm) {
|
||||||
float diffDotNorm = -sign * diff.dot(norm);
|
float diffDotNorm = -sign * diff.dot(norm);
|
||||||
if (diffDotNorm >= 0.0f) {
|
if (diffDotNorm >= 0.0f) {
|
||||||
// this method always returns
|
// this method always returns
|
||||||
assert vars.unlock();
|
vars.release();
|
||||||
|
|
||||||
// ray intersects triangle
|
// ray intersects triangle
|
||||||
// if storage vector is null, just return true,
|
// if storage vector is null, just return true,
|
||||||
if (store == null)
|
if (store == null) {
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// else fill in.
|
// else fill in.
|
||||||
float inv = 1f / dirDotNorm;
|
float inv = 1f / dirDotNorm;
|
||||||
@ -273,11 +266,11 @@ public final class Ray implements Savable, Cloneable, Collidable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
assert vars.unlock();
|
vars.release();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public float intersects(Vector3f v0, Vector3f v1, Vector3f v2){
|
public float intersects(Vector3f v0, Vector3f v1, Vector3f v2) {
|
||||||
float edge1X = v1.x - v0.x;
|
float edge1X = v1.x - v0.x;
|
||||||
float edge1Y = v1.y - v0.y;
|
float edge1Y = v1.y - v0.y;
|
||||||
float edge1Z = v1.z - v0.z;
|
float edge1Z = v1.z - v0.z;
|
||||||
@ -312,8 +305,8 @@ public final class Ray implements Savable, Cloneable, Collidable {
|
|||||||
float diffEdge2Z = ((diffX * edge2Y) - (diffY * edge2X));
|
float diffEdge2Z = ((diffX * edge2Y) - (diffY * edge2X));
|
||||||
|
|
||||||
float dirDotDiffxEdge2 = sign * (direction.x * diffEdge2X
|
float dirDotDiffxEdge2 = sign * (direction.x * diffEdge2X
|
||||||
+ direction.y * diffEdge2Y
|
+ direction.y * diffEdge2Y
|
||||||
+ direction.z * diffEdge2Z);
|
+ direction.z * diffEdge2Z);
|
||||||
|
|
||||||
if (dirDotDiffxEdge2 >= 0.0f) {
|
if (dirDotDiffxEdge2 >= 0.0f) {
|
||||||
diffEdge2X = ((edge1Y * diffZ) - (edge1Z * diffY));
|
diffEdge2X = ((edge1Y * diffZ) - (edge1Z * diffY));
|
||||||
@ -321,8 +314,8 @@ public final class Ray implements Savable, Cloneable, Collidable {
|
|||||||
diffEdge2Z = ((edge1X * diffY) - (edge1Y * diffX));
|
diffEdge2Z = ((edge1X * diffY) - (edge1Y * diffX));
|
||||||
|
|
||||||
float dirDotEdge1xDiff = sign * (direction.x * diffEdge2X
|
float dirDotEdge1xDiff = sign * (direction.x * diffEdge2X
|
||||||
+ direction.y * diffEdge2Y
|
+ direction.y * diffEdge2Y
|
||||||
+ direction.z * diffEdge2Z);
|
+ direction.z * diffEdge2Z);
|
||||||
|
|
||||||
if (dirDotEdge1xDiff >= 0.0f) {
|
if (dirDotEdge1xDiff >= 0.0f) {
|
||||||
if (dirDotDiffxEdge2 + dirDotEdge1xDiff <= dirDotNorm) {
|
if (dirDotDiffxEdge2 + dirDotEdge1xDiff <= dirDotNorm) {
|
||||||
@ -364,8 +357,8 @@ public final class Ray implements Savable, Cloneable, Collidable {
|
|||||||
* @return true if the ray collides with the quad.
|
* @return true if the ray collides with the quad.
|
||||||
*/
|
*/
|
||||||
public boolean intersectWherePlanarQuad(Vector3f v0, Vector3f v1, Vector3f v2,
|
public boolean intersectWherePlanarQuad(Vector3f v0, Vector3f v1, Vector3f v2,
|
||||||
Vector3f loc) {
|
Vector3f loc) {
|
||||||
return intersects( v0, v1, v2, loc, true, true );
|
return intersects(v0, v1, v2, loc, true, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -377,57 +370,57 @@ public final class Ray implements Savable, Cloneable, Collidable {
|
|||||||
public boolean intersectsWherePlane(Plane p, Vector3f loc) {
|
public boolean intersectsWherePlane(Plane p, Vector3f loc) {
|
||||||
float denominator = p.getNormal().dot(direction);
|
float denominator = p.getNormal().dot(direction);
|
||||||
|
|
||||||
if (denominator > -FastMath.FLT_EPSILON && denominator < FastMath.FLT_EPSILON)
|
if (denominator > -FastMath.FLT_EPSILON && denominator < FastMath.FLT_EPSILON) {
|
||||||
return false; // coplanar
|
return false; // coplanar
|
||||||
|
}
|
||||||
float numerator = -(p.getNormal().dot(origin) - p.getConstant());
|
float numerator = -(p.getNormal().dot(origin) - p.getConstant());
|
||||||
float ratio = numerator / denominator;
|
float ratio = numerator / denominator;
|
||||||
|
|
||||||
if (ratio < FastMath.FLT_EPSILON)
|
if (ratio < FastMath.FLT_EPSILON) {
|
||||||
return false; // intersects behind origin
|
return false; // intersects behind origin
|
||||||
|
}
|
||||||
loc.set(direction).multLocal(ratio).addLocal(origin);
|
loc.set(direction).multLocal(ratio).addLocal(origin);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int collideWith(Collidable other, CollisionResults results){
|
public int collideWith(Collidable other, CollisionResults results) {
|
||||||
if (other instanceof BoundingVolume){
|
if (other instanceof BoundingVolume) {
|
||||||
BoundingVolume bv = (BoundingVolume) other;
|
BoundingVolume bv = (BoundingVolume) other;
|
||||||
return bv.collideWith(this, results);
|
return bv.collideWith(this, results);
|
||||||
}else if (other instanceof AbstractTriangle){
|
} else if (other instanceof AbstractTriangle) {
|
||||||
AbstractTriangle tri = (AbstractTriangle) other;
|
AbstractTriangle tri = (AbstractTriangle) other;
|
||||||
float d = intersects(tri.get1(), tri.get2(), tri.get3());
|
float d = intersects(tri.get1(), tri.get2(), tri.get3());
|
||||||
if (Float.isInfinite(d) || Float.isNaN(d))
|
if (Float.isInfinite(d) || Float.isNaN(d)) {
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
Vector3f point = new Vector3f(direction).multLocal(d).addLocal(origin);
|
Vector3f point = new Vector3f(direction).multLocal(d).addLocal(origin);
|
||||||
results.addCollision(new CollisionResult(point, d));
|
results.addCollision(new CollisionResult(point, d));
|
||||||
return 1;
|
return 1;
|
||||||
}else{
|
} else {
|
||||||
throw new UnsupportedCollisionException();
|
throw new UnsupportedCollisionException();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public float distanceSquared(Vector3f point) {
|
public float distanceSquared(Vector3f point) {
|
||||||
TempVars vars = TempVars.get();
|
TempVars vars = TempVars.get();
|
||||||
assert vars.lock();
|
|
||||||
|
|
||||||
Vector3f tempVa = vars.vect1,
|
Vector3f tempVa = vars.vect1,
|
||||||
tempVb = vars.vect2;
|
tempVb = vars.vect2;
|
||||||
|
|
||||||
point.subtract(origin, tempVa);
|
point.subtract(origin, tempVa);
|
||||||
float rayParam = direction.dot(tempVa);
|
float rayParam = direction.dot(tempVa);
|
||||||
if (rayParam > 0){
|
if (rayParam > 0) {
|
||||||
origin.add(direction.mult(rayParam, tempVb), tempVb);
|
origin.add(direction.mult(rayParam, tempVb), tempVb);
|
||||||
}else{
|
} else {
|
||||||
tempVb.set(origin);
|
tempVb.set(origin);
|
||||||
rayParam = 0.0f;
|
rayParam = 0.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
tempVb.subtract(point, tempVa);
|
tempVb.subtract(point, tempVa);
|
||||||
float len = tempVa.lengthSquared();
|
float len = tempVa.lengthSquared();
|
||||||
assert vars.unlock();
|
vars.release();
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -457,7 +450,7 @@ public final class Ray implements Savable, Cloneable, Collidable {
|
|||||||
*
|
*
|
||||||
* @return the limit or the ray, aka the length.
|
* @return the limit or the ray, aka the length.
|
||||||
*/
|
*/
|
||||||
public float getLimit(){
|
public float getLimit() {
|
||||||
return limit;
|
return limit;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -466,7 +459,7 @@ public final class Ray implements Savable, Cloneable, Collidable {
|
|||||||
* @param limit the limit of the ray.
|
* @param limit the limit of the ray.
|
||||||
* @see Ray#getLimit()
|
* @see Ray#getLimit()
|
||||||
*/
|
*/
|
||||||
public void setLimit(float limit){
|
public void setLimit(float limit) {
|
||||||
this.limit = limit;
|
this.limit = limit;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -499,8 +492,8 @@ public final class Ray implements Savable, Cloneable, Collidable {
|
|||||||
direction.set(source.getDirection());
|
direction.set(source.getDirection());
|
||||||
}
|
}
|
||||||
|
|
||||||
public String toString(){
|
public String toString() {
|
||||||
return getClass().getSimpleName()+" [Origin: "+origin+", Direction: "+direction+"]";
|
return getClass().getSimpleName() + " [Origin: " + origin + ", Direction: " + direction + "]";
|
||||||
}
|
}
|
||||||
|
|
||||||
public void write(JmeExporter e) throws IOException {
|
public void write(JmeExporter e) throws IOException {
|
||||||
@ -511,8 +504,8 @@ public final class Ray implements Savable, Cloneable, Collidable {
|
|||||||
|
|
||||||
public void read(JmeImporter e) throws IOException {
|
public void read(JmeImporter e) throws IOException {
|
||||||
InputCapsule capsule = e.getCapsule(this);
|
InputCapsule capsule = e.getCapsule(this);
|
||||||
origin = (Vector3f)capsule.readSavable("origin", Vector3f.ZERO.clone());
|
origin = (Vector3f) capsule.readSavable("origin", Vector3f.ZERO.clone());
|
||||||
direction = (Vector3f)capsule.readSavable("direction", Vector3f.ZERO.clone());
|
direction = (Vector3f) capsule.readSavable("direction", Vector3f.ZERO.clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -527,4 +520,3 @@ public final class Ray implements Savable, Cloneable, Collidable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -98,7 +98,6 @@ public class Camera implements Savable, Cloneable {
|
|||||||
*/
|
*/
|
||||||
Intersects;
|
Intersects;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* LEFT_PLANE represents the left plane of the camera frustum.
|
* LEFT_PLANE represents the left plane of the camera frustum.
|
||||||
*/
|
*/
|
||||||
@ -131,7 +130,6 @@ public class Camera implements Savable, Cloneable {
|
|||||||
* MAX_WORLD_PLANES holds the maximum planes allowed by the system.
|
* MAX_WORLD_PLANES holds the maximum planes allowed by the system.
|
||||||
*/
|
*/
|
||||||
private static final int MAX_WORLD_PLANES = 6;
|
private static final int MAX_WORLD_PLANES = 6;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Camera's location
|
* Camera's location
|
||||||
*/
|
*/
|
||||||
@ -164,14 +162,12 @@ public class Camera implements Savable, Cloneable {
|
|||||||
* Distance from camera to bottom frustum plane.
|
* Distance from camera to bottom frustum plane.
|
||||||
*/
|
*/
|
||||||
protected float frustumBottom;
|
protected float frustumBottom;
|
||||||
|
|
||||||
//Temporary values computed in onFrustumChange that are needed if a
|
//Temporary values computed in onFrustumChange that are needed if a
|
||||||
//call is made to onFrameChange.
|
//call is made to onFrameChange.
|
||||||
protected float[] coeffLeft;
|
protected float[] coeffLeft;
|
||||||
protected float[] coeffRight;
|
protected float[] coeffRight;
|
||||||
protected float[] coeffBottom;
|
protected float[] coeffBottom;
|
||||||
protected float[] coeffTop;
|
protected float[] coeffTop;
|
||||||
|
|
||||||
//view port coordinates
|
//view port coordinates
|
||||||
/**
|
/**
|
||||||
* Percent value on display where horizontal viewing starts for this camera.
|
* Percent value on display where horizontal viewing starts for this camera.
|
||||||
@ -197,13 +193,11 @@ public class Camera implements Savable, Cloneable {
|
|||||||
* Array holding the planes that this camera will check for culling.
|
* Array holding the planes that this camera will check for culling.
|
||||||
*/
|
*/
|
||||||
protected Plane[] worldPlane;
|
protected Plane[] worldPlane;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A mask value set during contains() that allows fast culling of a Node's
|
* A mask value set during contains() that allows fast culling of a Node's
|
||||||
* children.
|
* children.
|
||||||
*/
|
*/
|
||||||
private int planeState;
|
private int planeState;
|
||||||
|
|
||||||
protected int width;
|
protected int width;
|
||||||
protected int height;
|
protected int height;
|
||||||
protected boolean viewportChanged = true;
|
protected boolean viewportChanged = true;
|
||||||
@ -758,10 +752,9 @@ public class Camera implements Savable, Cloneable {
|
|||||||
*/
|
*/
|
||||||
public void lookAt(Vector3f pos, Vector3f worldUpVector) {
|
public void lookAt(Vector3f pos, Vector3f worldUpVector) {
|
||||||
TempVars vars = TempVars.get();
|
TempVars vars = TempVars.get();
|
||||||
assert vars.lock();
|
Vector3f newDirection = vars.vect1;
|
||||||
Vector3f newDirection = TempVars.get().vect1;
|
Vector3f newUp = vars.vect2;
|
||||||
Vector3f newUp = TempVars.get().vect2;
|
Vector3f newLeft = vars.vect3;
|
||||||
Vector3f newLeft = TempVars.get().vect3;
|
|
||||||
|
|
||||||
newDirection.set(pos).subtractLocal(location).normalizeLocal();
|
newDirection.set(pos).subtractLocal(location).normalizeLocal();
|
||||||
|
|
||||||
@ -783,7 +776,7 @@ public class Camera implements Savable, Cloneable {
|
|||||||
|
|
||||||
this.rotation.fromAxes(newLeft, newUp, newDirection);
|
this.rotation.fromAxes(newLeft, newUp, newDirection);
|
||||||
this.rotation.normalizeLocal();
|
this.rotation.normalizeLocal();
|
||||||
assert vars.unlock();
|
vars.release();
|
||||||
|
|
||||||
onFrameChange();
|
onFrameChange();
|
||||||
}
|
}
|
||||||
@ -1285,15 +1278,15 @@ public class Camera implements Savable, Cloneable {
|
|||||||
store = new Vector3f();
|
store = new Vector3f();
|
||||||
}
|
}
|
||||||
|
|
||||||
// assert TempVars.get().lock();
|
// TempVars vars = vars.lock();
|
||||||
// Quaternion tmp_quat = TempVars.get().quat1;
|
// Quaternion tmp_quat = vars.quat1;
|
||||||
// tmp_quat.set( worldPosition.x, worldPosition.y, worldPosition.z, 1 );
|
// tmp_quat.set( worldPosition.x, worldPosition.y, worldPosition.z, 1 );
|
||||||
// viewProjectionMatrix.mult(tmp_quat, tmp_quat);
|
// viewProjectionMatrix.mult(tmp_quat, tmp_quat);
|
||||||
// tmp_quat.multLocal( 1.0f / tmp_quat.getW() );
|
// tmp_quat.multLocal( 1.0f / tmp_quat.getW() );
|
||||||
// store.x = ( ( tmp_quat.getX() + 1 ) * ( viewPortRight - viewPortLeft ) / 2 + viewPortLeft ) * getWidth();
|
// store.x = ( ( tmp_quat.getX() + 1 ) * ( viewPortRight - viewPortLeft ) / 2 + viewPortLeft ) * getWidth();
|
||||||
// store.y = ( ( tmp_quat.getY() + 1 ) * ( viewPortTop - viewPortBottom ) / 2 + viewPortBottom ) * getHeight();
|
// store.y = ( ( tmp_quat.getY() + 1 ) * ( viewPortTop - viewPortBottom ) / 2 + viewPortBottom ) * getHeight();
|
||||||
// store.z = ( tmp_quat.getZ() + 1 ) / 2;
|
// store.z = ( tmp_quat.getZ() + 1 ) / 2;
|
||||||
// assert TempVars.get().unlock();
|
// vars.release();
|
||||||
|
|
||||||
float w = viewProjectionMatrix.multProj(worldPosition, store);
|
float w = viewProjectionMatrix.multProj(worldPosition, store);
|
||||||
store.divideLocal(w);
|
store.divideLocal(w);
|
||||||
|
@ -75,7 +75,6 @@ import java.util.logging.Logger;
|
|||||||
public class RenderManager {
|
public class RenderManager {
|
||||||
|
|
||||||
private static final Logger logger = Logger.getLogger(RenderManager.class.getName());
|
private static final Logger logger = Logger.getLogger(RenderManager.class.getName());
|
||||||
|
|
||||||
private Renderer renderer;
|
private Renderer renderer;
|
||||||
private Timer timer;
|
private Timer timer;
|
||||||
private ArrayList<ViewPort> preViewPorts = new ArrayList<ViewPort>();
|
private ArrayList<ViewPort> preViewPorts = new ArrayList<ViewPort>();
|
||||||
@ -344,7 +343,6 @@ public class RenderManager {
|
|||||||
public void updateUniformBindings(List<Uniform> params) {
|
public void updateUniformBindings(List<Uniform> params) {
|
||||||
// assums worldMatrix is properly set.
|
// assums worldMatrix is properly set.
|
||||||
TempVars vars = TempVars.get();
|
TempVars vars = TempVars.get();
|
||||||
assert vars.lock();
|
|
||||||
|
|
||||||
Matrix4f tempMat4 = vars.tempMat4;
|
Matrix4f tempMat4 = vars.tempMat4;
|
||||||
Matrix3f tempMat3 = vars.tempMat3;
|
Matrix3f tempMat3 = vars.tempMat3;
|
||||||
@ -465,7 +463,7 @@ public class RenderManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
assert vars.unlock();
|
vars.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1167,5 +1165,4 @@ public class RenderManager {
|
|||||||
renderViewPort(postViewPorts.get(i), tpf);
|
renderViewPort(postViewPorts.get(i), tpf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -29,7 +29,6 @@
|
|||||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.jme3.scene;
|
package com.jme3.scene;
|
||||||
|
|
||||||
import com.jme3.asset.AssetNotFoundException;
|
import com.jme3.asset.AssetNotFoundException;
|
||||||
@ -60,24 +59,19 @@ import java.util.logging.Logger;
|
|||||||
public class Geometry extends Spatial {
|
public class Geometry extends Spatial {
|
||||||
|
|
||||||
private static final Logger logger = Logger.getLogger(Geometry.class.getName());
|
private static final Logger logger = Logger.getLogger(Geometry.class.getName());
|
||||||
|
|
||||||
protected Mesh mesh;
|
protected Mesh mesh;
|
||||||
|
|
||||||
protected transient int lodLevel = 0;
|
protected transient int lodLevel = 0;
|
||||||
|
|
||||||
protected Material material;
|
protected Material material;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* When true, the geometry's transform will not be applied.
|
* When true, the geometry's transform will not be applied.
|
||||||
*/
|
*/
|
||||||
protected boolean ignoreTransform = false;
|
protected boolean ignoreTransform = false;
|
||||||
|
|
||||||
protected transient Matrix4f cachedWorldMat = new Matrix4f();
|
protected transient Matrix4f cachedWorldMat = new Matrix4f();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Serialization only. Do not use.
|
* Serialization only. Do not use.
|
||||||
*/
|
*/
|
||||||
public Geometry(){
|
public Geometry() {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -87,7 +81,7 @@ public class Geometry extends Spatial {
|
|||||||
*
|
*
|
||||||
* @param name The name of this geometry
|
* @param name The name of this geometry
|
||||||
*/
|
*/
|
||||||
public Geometry(String name){
|
public Geometry(String name) {
|
||||||
super(name);
|
super(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -99,10 +93,11 @@ public class Geometry extends Spatial {
|
|||||||
* @param name The name of this geometry
|
* @param name The name of this geometry
|
||||||
* @param mesh The mesh data for this geometry
|
* @param mesh The mesh data for this geometry
|
||||||
*/
|
*/
|
||||||
public Geometry(String name, Mesh mesh){
|
public Geometry(String name, Mesh mesh) {
|
||||||
this(name);
|
this(name);
|
||||||
if (mesh == null)
|
if (mesh == null) {
|
||||||
throw new NullPointerException();
|
throw new NullPointerException();
|
||||||
|
}
|
||||||
|
|
||||||
this.mesh = mesh;
|
this.mesh = mesh;
|
||||||
}
|
}
|
||||||
@ -132,12 +127,14 @@ public class Geometry extends Spatial {
|
|||||||
* @param lod The lod level to set
|
* @param lod The lod level to set
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void setLodLevel(int lod){
|
public void setLodLevel(int lod) {
|
||||||
if (mesh.getNumLodLevels() == 0)
|
if (mesh.getNumLodLevels() == 0) {
|
||||||
throw new IllegalStateException("LOD levels are not set on this mesh");
|
throw new IllegalStateException("LOD levels are not set on this mesh");
|
||||||
|
}
|
||||||
|
|
||||||
if (lod < 0 || lod >= mesh.getNumLodLevels())
|
if (lod < 0 || lod >= mesh.getNumLodLevels()) {
|
||||||
throw new IllegalArgumentException("LOD level is out of range: "+lod);
|
throw new IllegalArgumentException("LOD level is out of range: " + lod);
|
||||||
|
}
|
||||||
|
|
||||||
lodLevel = lod;
|
lodLevel = lod;
|
||||||
}
|
}
|
||||||
@ -147,7 +144,7 @@ public class Geometry extends Spatial {
|
|||||||
*
|
*
|
||||||
* @return the LOD level set
|
* @return the LOD level set
|
||||||
*/
|
*/
|
||||||
public int getLodLevel(){
|
public int getLodLevel() {
|
||||||
return lodLevel;
|
return lodLevel;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -158,7 +155,7 @@ public class Geometry extends Spatial {
|
|||||||
*
|
*
|
||||||
* @see Mesh#getVertexCount()
|
* @see Mesh#getVertexCount()
|
||||||
*/
|
*/
|
||||||
public int getVertexCount(){
|
public int getVertexCount() {
|
||||||
return mesh.getVertexCount();
|
return mesh.getVertexCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -169,7 +166,7 @@ public class Geometry extends Spatial {
|
|||||||
*
|
*
|
||||||
* @see Mesh#getTriangleCount()
|
* @see Mesh#getTriangleCount()
|
||||||
*/
|
*/
|
||||||
public int getTriangleCount(){
|
public int getTriangleCount() {
|
||||||
return mesh.getTriangleCount();
|
return mesh.getTriangleCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -180,9 +177,10 @@ public class Geometry extends Spatial {
|
|||||||
*
|
*
|
||||||
* @throws IllegalArgumentException If mesh is null
|
* @throws IllegalArgumentException If mesh is null
|
||||||
*/
|
*/
|
||||||
public void setMesh(Mesh mesh){
|
public void setMesh(Mesh mesh) {
|
||||||
if (mesh == null)
|
if (mesh == null) {
|
||||||
throw new IllegalArgumentException();
|
throw new IllegalArgumentException();
|
||||||
|
}
|
||||||
|
|
||||||
this.mesh = mesh;
|
this.mesh = mesh;
|
||||||
setBoundRefresh();
|
setBoundRefresh();
|
||||||
@ -195,7 +193,7 @@ public class Geometry extends Spatial {
|
|||||||
*
|
*
|
||||||
* @see #setMesh(com.jme3.scene.Mesh)
|
* @see #setMesh(com.jme3.scene.Mesh)
|
||||||
*/
|
*/
|
||||||
public Mesh getMesh(){
|
public Mesh getMesh() {
|
||||||
return mesh;
|
return mesh;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -205,7 +203,7 @@ public class Geometry extends Spatial {
|
|||||||
* @param material the material to use for this geometry
|
* @param material the material to use for this geometry
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void setMaterial(Material material){
|
public void setMaterial(Material material) {
|
||||||
this.material = material;
|
this.material = material;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -216,14 +214,14 @@ public class Geometry extends Spatial {
|
|||||||
*
|
*
|
||||||
* @see #setMaterial(com.jme3.material.Material)
|
* @see #setMaterial(com.jme3.material.Material)
|
||||||
*/
|
*/
|
||||||
public Material getMaterial(){
|
public Material getMaterial() {
|
||||||
return material;
|
return material;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return The bounding volume of the mesh, in model space.
|
* @return The bounding volume of the mesh, in model space.
|
||||||
*/
|
*/
|
||||||
public BoundingVolume getModelBound(){
|
public BoundingVolume getModelBound() {
|
||||||
return mesh.getBound();
|
return mesh.getBound();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -246,22 +244,23 @@ public class Geometry extends Spatial {
|
|||||||
@Override
|
@Override
|
||||||
protected void updateWorldBound() {
|
protected void updateWorldBound() {
|
||||||
super.updateWorldBound();
|
super.updateWorldBound();
|
||||||
if (mesh == null)
|
if (mesh == null) {
|
||||||
throw new NullPointerException("Geometry: "+getName()+" has null mesh");
|
throw new NullPointerException("Geometry: " + getName() + " has null mesh");
|
||||||
|
}
|
||||||
|
|
||||||
if (mesh.getBound() != null) {
|
if (mesh.getBound() != null) {
|
||||||
if (ignoreTransform){
|
if (ignoreTransform) {
|
||||||
// we do not transform the model bound by the world transform,
|
// we do not transform the model bound by the world transform,
|
||||||
// just use the model bound as-is
|
// just use the model bound as-is
|
||||||
worldBound = mesh.getBound().clone(worldBound);
|
worldBound = mesh.getBound().clone(worldBound);
|
||||||
}else{
|
} else {
|
||||||
worldBound = mesh.getBound().transform(worldTransform, worldBound);
|
worldBound = mesh.getBound().transform(worldTransform, worldBound);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void updateWorldTransforms(){
|
protected void updateWorldTransforms() {
|
||||||
super.updateWorldTransforms();
|
super.updateWorldTransforms();
|
||||||
|
|
||||||
computeWorldMatrix();
|
computeWorldMatrix();
|
||||||
@ -274,7 +273,7 @@ public class Geometry extends Spatial {
|
|||||||
* Recomputes the matrix returned by {@link Geometry#getWorldMatrix() }.
|
* Recomputes the matrix returned by {@link Geometry#getWorldMatrix() }.
|
||||||
* This will require a localized transform update for this geometry.
|
* This will require a localized transform update for this geometry.
|
||||||
*/
|
*/
|
||||||
public void computeWorldMatrix(){
|
public void computeWorldMatrix() {
|
||||||
// Force a local update of the geometry's transform
|
// Force a local update of the geometry's transform
|
||||||
checkDoTransformUpdate();
|
checkDoTransformUpdate();
|
||||||
|
|
||||||
@ -283,12 +282,12 @@ public class Geometry extends Spatial {
|
|||||||
cachedWorldMat.setRotationQuaternion(worldTransform.getRotation());
|
cachedWorldMat.setRotationQuaternion(worldTransform.getRotation());
|
||||||
cachedWorldMat.setTranslation(worldTransform.getTranslation());
|
cachedWorldMat.setTranslation(worldTransform.getTranslation());
|
||||||
|
|
||||||
assert TempVars.get().lock();
|
TempVars vars = TempVars.get();
|
||||||
Matrix4f scaleMat = TempVars.get().tempMat4;
|
Matrix4f scaleMat = vars.tempMat4;
|
||||||
scaleMat.loadIdentity();
|
scaleMat.loadIdentity();
|
||||||
scaleMat.scale(worldTransform.getScale());
|
scaleMat.scale(worldTransform.getScale());
|
||||||
cachedWorldMat.multLocal(scaleMat);
|
cachedWorldMat.multLocal(scaleMat);
|
||||||
assert TempVars.get().unlock();
|
vars.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -300,7 +299,7 @@ public class Geometry extends Spatial {
|
|||||||
*
|
*
|
||||||
* @return Matrix to transform from local space to world space
|
* @return Matrix to transform from local space to world space
|
||||||
*/
|
*/
|
||||||
public Matrix4f getWorldMatrix(){
|
public Matrix4f getWorldMatrix() {
|
||||||
return cachedWorldMat;
|
return cachedWorldMat;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -319,7 +318,7 @@ public class Geometry extends Spatial {
|
|||||||
updateModelBound();
|
updateModelBound();
|
||||||
}
|
}
|
||||||
|
|
||||||
public int collideWith(Collidable other, CollisionResults results){
|
public int collideWith(Collidable other, CollisionResults results) {
|
||||||
// Force bound to update
|
// Force bound to update
|
||||||
checkDoBoundUpdate();
|
checkDoBoundUpdate();
|
||||||
// Update transform, and compute cached world matrix
|
// Update transform, and compute cached world matrix
|
||||||
@ -327,13 +326,13 @@ public class Geometry extends Spatial {
|
|||||||
|
|
||||||
assert (refreshFlags & (RF_BOUND | RF_TRANSFORM)) == 0;
|
assert (refreshFlags & (RF_BOUND | RF_TRANSFORM)) == 0;
|
||||||
|
|
||||||
if (mesh != null){
|
if (mesh != null) {
|
||||||
// NOTE: BIHTree in mesh already checks collision with the
|
// NOTE: BIHTree in mesh already checks collision with the
|
||||||
// mesh's bound
|
// mesh's bound
|
||||||
int prevSize = results.size();
|
int prevSize = results.size();
|
||||||
int added = mesh.collideWith(other, cachedWorldMat, worldBound, results);
|
int added = mesh.collideWith(other, cachedWorldMat, worldBound, results);
|
||||||
int newSize = results.size();
|
int newSize = results.size();
|
||||||
for (int i = prevSize; i < newSize; i++){
|
for (int i = prevSize; i < newSize; i++) {
|
||||||
results.getCollisionDirect(i).setGeometry(this);
|
results.getCollisionDirect(i).setGeometry(this);
|
||||||
}
|
}
|
||||||
return added;
|
return added;
|
||||||
@ -358,17 +357,18 @@ public class Geometry extends Spatial {
|
|||||||
* and normals are deep copied.
|
* and normals are deep copied.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Geometry clone(boolean cloneMaterial){
|
public Geometry clone(boolean cloneMaterial) {
|
||||||
Geometry geomClone = (Geometry) super.clone(cloneMaterial);
|
Geometry geomClone = (Geometry) super.clone(cloneMaterial);
|
||||||
geomClone.cachedWorldMat = cachedWorldMat.clone();
|
geomClone.cachedWorldMat = cachedWorldMat.clone();
|
||||||
if (material != null){
|
if (material != null) {
|
||||||
if (cloneMaterial)
|
if (cloneMaterial) {
|
||||||
geomClone.material = material.clone();
|
geomClone.material = material.clone();
|
||||||
else
|
} else {
|
||||||
geomClone.material = material;
|
geomClone.material = material;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mesh != null && mesh.getBuffer(Type.BindPosePosition) != null){
|
if (mesh != null && mesh.getBuffer(Type.BindPosePosition) != null) {
|
||||||
geomClone.mesh = mesh.cloneForAnim();
|
geomClone.mesh = mesh.cloneForAnim();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -383,7 +383,7 @@ public class Geometry extends Spatial {
|
|||||||
* and normals are deep copied.
|
* and normals are deep copied.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Geometry clone(){
|
public Geometry clone() {
|
||||||
return clone(true);
|
return clone(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -393,7 +393,7 @@ public class Geometry extends Spatial {
|
|||||||
* with the vertexbuffer data duplicated.
|
* with the vertexbuffer data duplicated.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Spatial deepClone(){
|
public Spatial deepClone() {
|
||||||
Geometry geomClone = clone(true);
|
Geometry geomClone = clone(true);
|
||||||
geomClone.mesh = mesh.deepClone();
|
geomClone.mesh = mesh.deepClone();
|
||||||
return geomClone;
|
return geomClone;
|
||||||
@ -404,7 +404,7 @@ public class Geometry extends Spatial {
|
|||||||
super.write(ex);
|
super.write(ex);
|
||||||
OutputCapsule oc = ex.getCapsule(this);
|
OutputCapsule oc = ex.getCapsule(this);
|
||||||
oc.write(mesh, "mesh", null);
|
oc.write(mesh, "mesh", null);
|
||||||
if (material != null){
|
if (material != null) {
|
||||||
oc.write(material.getAssetName(), "materialName", null);
|
oc.write(material.getAssetName(), "materialName", null);
|
||||||
}
|
}
|
||||||
oc.write(material, "material", null);
|
oc.write(material, "material", null);
|
||||||
@ -419,22 +419,21 @@ public class Geometry extends Spatial {
|
|||||||
|
|
||||||
material = null;
|
material = null;
|
||||||
String matName = ic.readString("materialName", null);
|
String matName = ic.readString("materialName", null);
|
||||||
if (matName != null){
|
if (matName != null) {
|
||||||
// Material name is set,
|
// Material name is set,
|
||||||
// Attempt to load material via J3M
|
// Attempt to load material via J3M
|
||||||
try {
|
try {
|
||||||
material = im.getAssetManager().loadMaterial(matName);
|
material = im.getAssetManager().loadMaterial(matName);
|
||||||
} catch (AssetNotFoundException ex){
|
} catch (AssetNotFoundException ex) {
|
||||||
// Cannot find J3M file.
|
// Cannot find J3M file.
|
||||||
logger.log(Level.FINE, "Could not load J3M file {0} for Geometry.",
|
logger.log(Level.FINE, "Could not load J3M file {0} for Geometry.",
|
||||||
matName);
|
matName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// If material is NULL, try to load it from the geometry
|
// If material is NULL, try to load it from the geometry
|
||||||
if (material == null){
|
if (material == null) {
|
||||||
material = (Material) ic.readSavable("material", null);
|
material = (Material) ic.readSavable("material", null);
|
||||||
}
|
}
|
||||||
ignoreTransform = ic.readBoolean("ignoreTransform", false);
|
ignoreTransform = ic.readBoolean("ignoreTransform", false);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -340,7 +340,6 @@ public abstract class Spatial implements Savable, Cloneable, Collidable {
|
|||||||
*/
|
*/
|
||||||
public void rotateUpTo(Vector3f newUp) {
|
public void rotateUpTo(Vector3f newUp) {
|
||||||
TempVars vars = TempVars.get();
|
TempVars vars = TempVars.get();
|
||||||
assert vars.lock();
|
|
||||||
|
|
||||||
Vector3f compVecA = vars.vect1;
|
Vector3f compVecA = vars.vect1;
|
||||||
Quaternion q = vars.quat1;
|
Quaternion q = vars.quat1;
|
||||||
@ -360,7 +359,7 @@ public abstract class Spatial implements Savable, Cloneable, Collidable {
|
|||||||
q.fromAngleNormalAxis(angle, rotAxis);
|
q.fromAngleNormalAxis(angle, rotAxis);
|
||||||
q.mult(rot, rot);
|
q.mult(rot, rot);
|
||||||
|
|
||||||
assert vars.unlock();
|
vars.release();
|
||||||
|
|
||||||
setTransformRefresh();
|
setTransformRefresh();
|
||||||
}
|
}
|
||||||
@ -382,9 +381,9 @@ public abstract class Spatial implements Savable, Cloneable, Collidable {
|
|||||||
Vector3f worldTranslation = getWorldTranslation();
|
Vector3f worldTranslation = getWorldTranslation();
|
||||||
|
|
||||||
TempVars vars = TempVars.get();
|
TempVars vars = TempVars.get();
|
||||||
assert vars.lock();
|
|
||||||
Vector3f compVecA = vars.vect4;
|
Vector3f compVecA = vars.vect4;
|
||||||
assert vars.unlock();
|
vars.release();
|
||||||
|
|
||||||
compVecA.set(position).subtractLocal(worldTranslation);
|
compVecA.set(position).subtractLocal(worldTranslation);
|
||||||
getLocalRotation().lookAt(compVecA, upVector);
|
getLocalRotation().lookAt(compVecA, upVector);
|
||||||
@ -448,7 +447,6 @@ public abstract class Spatial implements Savable, Cloneable, Collidable {
|
|||||||
refreshFlags &= ~RF_TRANSFORM;
|
refreshFlags &= ~RF_TRANSFORM;
|
||||||
} else {
|
} else {
|
||||||
TempVars vars = TempVars.get();
|
TempVars vars = TempVars.get();
|
||||||
assert vars.lock();
|
|
||||||
|
|
||||||
Spatial[] stack = vars.spatialStack;
|
Spatial[] stack = vars.spatialStack;
|
||||||
Spatial rootNode = this;
|
Spatial rootNode = this;
|
||||||
@ -472,7 +470,7 @@ public abstract class Spatial implements Savable, Cloneable, Collidable {
|
|||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
assert vars.unlock();
|
vars.release();
|
||||||
|
|
||||||
for (int j = i; j >= 0; j--) {
|
for (int j = i; j >= 0; j--) {
|
||||||
rootNode = stack[j];
|
rootNode = stack[j];
|
||||||
@ -978,11 +976,11 @@ public abstract class Spatial implements Savable, Cloneable, Collidable {
|
|||||||
* @return The spatial on which this method is called, e.g <code>this</code>.
|
* @return The spatial on which this method is called, e.g <code>this</code>.
|
||||||
*/
|
*/
|
||||||
public Spatial rotate(float yaw, float roll, float pitch) {
|
public Spatial rotate(float yaw, float roll, float pitch) {
|
||||||
assert TempVars.get().lock();
|
TempVars vars = TempVars.get();
|
||||||
Quaternion q = TempVars.get().quat1;
|
Quaternion q = vars.quat1;
|
||||||
q.fromAngles(yaw, roll, pitch);
|
q.fromAngles(yaw, roll, pitch);
|
||||||
rotate(q);
|
rotate(q);
|
||||||
assert TempVars.get().unlock();
|
vars.release();
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
@ -116,7 +116,6 @@ public class CameraControl extends AbstractControl {
|
|||||||
// set the localtransform, so that the worldtransform would be equal to the camera's transform.
|
// set the localtransform, so that the worldtransform would be equal to the camera's transform.
|
||||||
// Location:
|
// Location:
|
||||||
TempVars vars = TempVars.get();
|
TempVars vars = TempVars.get();
|
||||||
assert vars.lock();
|
|
||||||
|
|
||||||
Vector3f vecDiff = vars.vect1.set(camera.getLocation()).subtractLocal(spatial.getWorldTranslation());
|
Vector3f vecDiff = vars.vect1.set(camera.getLocation()).subtractLocal(spatial.getWorldTranslation());
|
||||||
spatial.setLocalTranslation(vecDiff.addLocal(spatial.getLocalTranslation()));
|
spatial.setLocalTranslation(vecDiff.addLocal(spatial.getLocalTranslation()));
|
||||||
@ -124,7 +123,7 @@ public class CameraControl extends AbstractControl {
|
|||||||
// Rotation:
|
// Rotation:
|
||||||
Quaternion worldDiff = vars.quat1.set(camera.getRotation()).subtractLocal(spatial.getWorldRotation());
|
Quaternion worldDiff = vars.quat1.set(camera.getRotation()).subtractLocal(spatial.getWorldRotation());
|
||||||
spatial.setLocalRotation(worldDiff.addLocal(spatial.getLocalRotation()));
|
spatial.setLocalRotation(worldDiff.addLocal(spatial.getLocalRotation()));
|
||||||
assert vars.unlock();
|
vars.release();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -126,12 +126,11 @@ public class LightControl extends AbstractControl {
|
|||||||
((PointLight) light).setPosition(spatial.getWorldTranslation());
|
((PointLight) light).setPosition(spatial.getWorldTranslation());
|
||||||
}
|
}
|
||||||
TempVars vars = TempVars.get();
|
TempVars vars = TempVars.get();
|
||||||
assert vars.lock();
|
|
||||||
|
|
||||||
if (light instanceof DirectionalLight) {
|
if (light instanceof DirectionalLight) {
|
||||||
((DirectionalLight) light).setDirection(vars.vect1.set(spatial.getWorldTranslation()).multLocal(-1.0f));
|
((DirectionalLight) light).setDirection(vars.vect1.set(spatial.getWorldTranslation()).multLocal(-1.0f));
|
||||||
}
|
}
|
||||||
assert vars.unlock();
|
vars.release();
|
||||||
//TODO add code for Spot light here when it's done
|
//TODO add code for Spot light here when it's done
|
||||||
// if( light instanceof SpotLight){
|
// if( light instanceof SpotLight){
|
||||||
// ((SpotLight)light).setPosition(spatial.getWorldTranslation());
|
// ((SpotLight)light).setPosition(spatial.getWorldTranslation());
|
||||||
@ -142,15 +141,12 @@ public class LightControl extends AbstractControl {
|
|||||||
|
|
||||||
private void lightToSpatial(Light light) {
|
private void lightToSpatial(Light light) {
|
||||||
TempVars vars = TempVars.get();
|
TempVars vars = TempVars.get();
|
||||||
assert vars.lock();
|
|
||||||
if (light instanceof PointLight) {
|
if (light instanceof PointLight) {
|
||||||
|
|
||||||
PointLight pLight = (PointLight) light;
|
PointLight pLight = (PointLight) light;
|
||||||
|
|
||||||
Vector3f vecDiff = vars.vect1.set(pLight.getPosition()).subtractLocal(spatial.getWorldTranslation());
|
Vector3f vecDiff = vars.vect1.set(pLight.getPosition()).subtractLocal(spatial.getWorldTranslation());
|
||||||
spatial.setLocalTranslation(vecDiff.addLocal(spatial.getLocalTranslation()));
|
spatial.setLocalTranslation(vecDiff.addLocal(spatial.getLocalTranslation()));
|
||||||
assert vars.unlock();
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (light instanceof DirectionalLight) {
|
if (light instanceof DirectionalLight) {
|
||||||
@ -159,7 +155,7 @@ public class LightControl extends AbstractControl {
|
|||||||
Vector3f vecDiff = vars.vect1.subtractLocal(spatial.getWorldTranslation());
|
Vector3f vecDiff = vars.vect1.subtractLocal(spatial.getWorldTranslation());
|
||||||
spatial.setLocalTranslation(vecDiff.addLocal(spatial.getLocalTranslation()));
|
spatial.setLocalTranslation(vecDiff.addLocal(spatial.getLocalTranslation()));
|
||||||
}
|
}
|
||||||
assert vars.unlock();
|
vars.release();
|
||||||
//TODO add code for Spot light here when it's done
|
//TODO add code for Spot light here when it's done
|
||||||
|
|
||||||
|
|
||||||
|
@ -67,4 +67,14 @@ public class SkeletonDebugger extends Node {
|
|||||||
wires.updateGeometry();
|
wires.updateGeometry();
|
||||||
points.updateGeometry();
|
points.updateGeometry();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public SkeletonPoints getPoints() {
|
||||||
|
return points;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SkeletonWire getWires() {
|
||||||
|
return wires;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -29,11 +29,9 @@
|
|||||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// $Id: Dome.java 4131 2009-03-19 20:15:28Z blaine.dev $
|
// $Id: Dome.java 4131 2009-03-19 20:15:28Z blaine.dev $
|
||||||
package com.jme3.scene.shape;
|
package com.jme3.scene.shape;
|
||||||
|
|
||||||
|
|
||||||
import com.jme3.scene.*;
|
import com.jme3.scene.*;
|
||||||
import com.jme3.export.JmeImporter;
|
import com.jme3.export.JmeImporter;
|
||||||
import com.jme3.export.InputCapsule;
|
import com.jme3.export.InputCapsule;
|
||||||
@ -58,15 +56,11 @@ import java.nio.ShortBuffer;
|
|||||||
public class Dome extends Mesh {
|
public class Dome extends Mesh {
|
||||||
|
|
||||||
private int planes;
|
private int planes;
|
||||||
|
|
||||||
private int radialSamples;
|
private int radialSamples;
|
||||||
|
|
||||||
/** The radius of the dome */
|
/** The radius of the dome */
|
||||||
private float radius;
|
private float radius;
|
||||||
|
|
||||||
/** The center of the dome */
|
/** The center of the dome */
|
||||||
private Vector3f center;
|
private Vector3f center;
|
||||||
|
|
||||||
private boolean outsideView = true;
|
private boolean outsideView = true;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -202,7 +196,7 @@ public class Dome extends Mesh {
|
|||||||
FloatBuffer nb = BufferUtils.createVector3Buffer(vertCount);
|
FloatBuffer nb = BufferUtils.createVector3Buffer(vertCount);
|
||||||
FloatBuffer tb = BufferUtils.createVector2Buffer(vertCount);
|
FloatBuffer tb = BufferUtils.createVector2Buffer(vertCount);
|
||||||
setBuffer(Type.Position, 3, vb);
|
setBuffer(Type.Position, 3, vb);
|
||||||
setBuffer(Type.Normal, 3, nb);
|
setBuffer(Type.Normal, 3, nb);
|
||||||
setBuffer(Type.TexCoord, 2, tb);
|
setBuffer(Type.TexCoord, 2, tb);
|
||||||
|
|
||||||
// generate geometry
|
// generate geometry
|
||||||
@ -220,7 +214,6 @@ public class Dome extends Mesh {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TempVars vars = TempVars.get();
|
TempVars vars = TempVars.get();
|
||||||
assert vars.lock();
|
|
||||||
Vector3f tempVc = vars.vect3;
|
Vector3f tempVc = vars.vect3;
|
||||||
Vector3f tempVb = vars.vect2;
|
Vector3f tempVb = vars.vect2;
|
||||||
Vector3f tempVa = vars.vect1;
|
Vector3f tempVa = vars.vect1;
|
||||||
@ -251,10 +244,11 @@ public class Dome extends Mesh {
|
|||||||
BufferUtils.populateFromBuffer(tempVa, vb, i);
|
BufferUtils.populateFromBuffer(tempVa, vb, i);
|
||||||
kNormal = tempVa.subtractLocal(center);
|
kNormal = tempVa.subtractLocal(center);
|
||||||
kNormal.normalizeLocal();
|
kNormal.normalizeLocal();
|
||||||
if (outsideView)
|
if (outsideView) {
|
||||||
nb.put(kNormal.x).put(kNormal.y).put(kNormal.z);
|
nb.put(kNormal.x).put(kNormal.y).put(kNormal.z);
|
||||||
else
|
} else {
|
||||||
nb.put(-kNormal.x).put(-kNormal.y).put(-kNormal.z);
|
nb.put(-kNormal.x).put(-kNormal.y).put(-kNormal.z);
|
||||||
|
}
|
||||||
|
|
||||||
tb.put(fRadialFraction).put(fYFraction);
|
tb.put(fRadialFraction).put(fYFraction);
|
||||||
}
|
}
|
||||||
@ -263,7 +257,7 @@ public class Dome extends Mesh {
|
|||||||
tb.put(1.0f).put(fYFraction);
|
tb.put(1.0f).put(fYFraction);
|
||||||
}
|
}
|
||||||
|
|
||||||
assert vars.unlock();
|
vars.release();
|
||||||
|
|
||||||
// pole
|
// pole
|
||||||
vb.put(center.x).put(center.y + radius).put(center.z);
|
vb.put(center.x).put(center.y + radius).put(center.z);
|
||||||
@ -282,21 +276,21 @@ public class Dome extends Mesh {
|
|||||||
int bottomPlaneStart = ((plane - 1) * (radialSamples + 1));
|
int bottomPlaneStart = ((plane - 1) * (radialSamples + 1));
|
||||||
int topPlaneStart = (plane * (radialSamples + 1));
|
int topPlaneStart = (plane * (radialSamples + 1));
|
||||||
for (int sample = 0; sample < radialSamples; sample++, index += 6) {
|
for (int sample = 0; sample < radialSamples; sample++, index += 6) {
|
||||||
ib.put((short)(bottomPlaneStart + sample));
|
ib.put((short) (bottomPlaneStart + sample));
|
||||||
ib.put((short)(topPlaneStart + sample));
|
ib.put((short) (topPlaneStart + sample));
|
||||||
ib.put((short)(bottomPlaneStart + sample + 1));
|
ib.put((short) (bottomPlaneStart + sample + 1));
|
||||||
ib.put((short)(bottomPlaneStart + sample + 1));
|
ib.put((short) (bottomPlaneStart + sample + 1));
|
||||||
ib.put((short)(topPlaneStart + sample));
|
ib.put((short) (topPlaneStart + sample));
|
||||||
ib.put((short)(topPlaneStart + sample + 1));
|
ib.put((short) (topPlaneStart + sample + 1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// pole triangles
|
// pole triangles
|
||||||
int bottomPlaneStart = (planes - 2) * (radialSamples + 1);
|
int bottomPlaneStart = (planes - 2) * (radialSamples + 1);
|
||||||
for (int samples = 0; samples < radialSamples; samples++, index += 3) {
|
for (int samples = 0; samples < radialSamples; samples++, index += 3) {
|
||||||
ib.put((short)(bottomPlaneStart + samples));
|
ib.put((short) (bottomPlaneStart + samples));
|
||||||
ib.put((short)(vertCount - 1));
|
ib.put((short) (vertCount - 1));
|
||||||
ib.put((short)(bottomPlaneStart + samples + 1));
|
ib.put((short) (bottomPlaneStart + samples + 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
updateBound();
|
updateBound();
|
||||||
@ -321,5 +315,4 @@ public class Dome extends Mesh {
|
|||||||
capsule.write(radius, "radius", 0);
|
capsule.write(radius, "radius", 0);
|
||||||
capsule.write(center, "center", Vector3f.ZERO);
|
capsule.write(center, "center", Vector3f.ZERO);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -29,7 +29,6 @@
|
|||||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// $Id: Sphere.java 4163 2009-03-25 01:14:55Z matt.yellen $
|
// $Id: Sphere.java 4163 2009-03-25 01:14:55Z matt.yellen $
|
||||||
package com.jme3.scene.shape;
|
package com.jme3.scene.shape;
|
||||||
|
|
||||||
@ -47,7 +46,6 @@ import java.io.IOException;
|
|||||||
import java.nio.FloatBuffer;
|
import java.nio.FloatBuffer;
|
||||||
import java.nio.ShortBuffer;
|
import java.nio.ShortBuffer;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <code>Sphere</code> represents a 3D object with all points equidistance
|
* <code>Sphere</code> represents a 3D object with all points equidistance
|
||||||
* from a center point.
|
* from a center point.
|
||||||
@ -58,6 +56,7 @@ import java.nio.ShortBuffer;
|
|||||||
public class Sphere extends Mesh {
|
public class Sphere extends Mesh {
|
||||||
|
|
||||||
public enum TextureMode {
|
public enum TextureMode {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Wrap texture radially and along z-axis
|
* Wrap texture radially and along z-axis
|
||||||
*/
|
*/
|
||||||
@ -72,28 +71,20 @@ public class Sphere extends Mesh {
|
|||||||
*/
|
*/
|
||||||
Polar
|
Polar
|
||||||
}
|
}
|
||||||
|
|
||||||
protected int vertCount;
|
protected int vertCount;
|
||||||
|
|
||||||
protected int triCount;
|
protected int triCount;
|
||||||
|
|
||||||
protected int zSamples;
|
protected int zSamples;
|
||||||
|
|
||||||
protected int radialSamples;
|
protected int radialSamples;
|
||||||
|
|
||||||
protected boolean useEvenSlices;
|
protected boolean useEvenSlices;
|
||||||
|
|
||||||
protected boolean interior;
|
protected boolean interior;
|
||||||
|
|
||||||
/** the distance from the center point each point falls on */
|
/** the distance from the center point each point falls on */
|
||||||
public float radius;
|
public float radius;
|
||||||
|
|
||||||
protected TextureMode textureMode = TextureMode.Original;
|
protected TextureMode textureMode = TextureMode.Original;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Serialization only. Do not use.
|
* Serialization only. Do not use.
|
||||||
*/
|
*/
|
||||||
public Sphere(){
|
public Sphere() {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -165,7 +156,7 @@ public class Sphere extends Mesh {
|
|||||||
FloatBuffer texBuf = BufferUtils.createVector2Buffer(vertCount);
|
FloatBuffer texBuf = BufferUtils.createVector2Buffer(vertCount);
|
||||||
|
|
||||||
setBuffer(Type.Position, 3, posBuf);
|
setBuffer(Type.Position, 3, posBuf);
|
||||||
setBuffer(Type.Normal, 3, normBuf);
|
setBuffer(Type.Normal, 3, normBuf);
|
||||||
setBuffer(Type.TexCoord, 2, texBuf);
|
setBuffer(Type.TexCoord, 2, texBuf);
|
||||||
|
|
||||||
// generate geometry
|
// generate geometry
|
||||||
@ -185,7 +176,6 @@ public class Sphere extends Mesh {
|
|||||||
afCos[radialSamples] = afCos[0];
|
afCos[radialSamples] = afCos[0];
|
||||||
|
|
||||||
TempVars vars = TempVars.get();
|
TempVars vars = TempVars.get();
|
||||||
assert vars.lock();
|
|
||||||
Vector3f tempVa = vars.vect1;
|
Vector3f tempVa = vars.vect1;
|
||||||
Vector3f tempVb = vars.vect2;
|
Vector3f tempVb = vars.vect2;
|
||||||
Vector3f tempVc = vars.vect3;
|
Vector3f tempVc = vars.vect3;
|
||||||
@ -195,11 +185,11 @@ public class Sphere extends Mesh {
|
|||||||
for (int iZ = 1; iZ < (zSamples - 1); iZ++) {
|
for (int iZ = 1; iZ < (zSamples - 1); iZ++) {
|
||||||
float fAFraction = FastMath.HALF_PI * (-1.0f + fZFactor * iZ); // in (-pi/2, pi/2)
|
float fAFraction = FastMath.HALF_PI * (-1.0f + fZFactor * iZ); // in (-pi/2, pi/2)
|
||||||
float fZFraction;
|
float fZFraction;
|
||||||
if (useEvenSlices)
|
if (useEvenSlices) {
|
||||||
fZFraction = -1.0f + fZFactor * iZ; // in (-1, 1)
|
fZFraction = -1.0f + fZFactor * iZ; // in (-1, 1)
|
||||||
else
|
} else {
|
||||||
fZFraction = FastMath.sin(fAFraction); // in (-1,1)
|
fZFraction = FastMath.sin(fAFraction); // in (-1,1)
|
||||||
|
}
|
||||||
float fZ = radius * fZFraction;
|
float fZ = radius * fZFraction;
|
||||||
|
|
||||||
// compute center of slice
|
// compute center of slice
|
||||||
@ -218,28 +208,29 @@ public class Sphere extends Mesh {
|
|||||||
Vector3f kRadial = tempVc.set(afCos[iR], afSin[iR], 0);
|
Vector3f kRadial = tempVc.set(afCos[iR], afSin[iR], 0);
|
||||||
kRadial.mult(fSliceRadius, tempVa);
|
kRadial.mult(fSliceRadius, tempVa);
|
||||||
posBuf.put(kSliceCenter.x + tempVa.x).put(
|
posBuf.put(kSliceCenter.x + tempVa.x).put(
|
||||||
kSliceCenter.y + tempVa.y).put(
|
kSliceCenter.y + tempVa.y).put(
|
||||||
kSliceCenter.z + tempVa.z);
|
kSliceCenter.z + tempVa.z);
|
||||||
|
|
||||||
BufferUtils.populateFromBuffer(tempVa, posBuf, i);
|
BufferUtils.populateFromBuffer(tempVa, posBuf, i);
|
||||||
kNormal = tempVa;
|
kNormal = tempVa;
|
||||||
kNormal.normalizeLocal();
|
kNormal.normalizeLocal();
|
||||||
if (!interior) // allow interior texture vs. exterior
|
if (!interior) // allow interior texture vs. exterior
|
||||||
|
{
|
||||||
normBuf.put(kNormal.x).put(kNormal.y).put(
|
normBuf.put(kNormal.x).put(kNormal.y).put(
|
||||||
kNormal.z);
|
kNormal.z);
|
||||||
else
|
} else {
|
||||||
normBuf.put(-kNormal.x).put(-kNormal.y).put(
|
normBuf.put(-kNormal.x).put(-kNormal.y).put(
|
||||||
-kNormal.z);
|
-kNormal.z);
|
||||||
|
}
|
||||||
|
|
||||||
if (textureMode == TextureMode.Original)
|
if (textureMode == TextureMode.Original) {
|
||||||
texBuf.put(fRadialFraction).put(
|
texBuf.put(fRadialFraction).put(
|
||||||
0.5f * (fZFraction + 1.0f));
|
0.5f * (fZFraction + 1.0f));
|
||||||
else if (textureMode == TextureMode.Projected)
|
} else if (textureMode == TextureMode.Projected) {
|
||||||
texBuf.put(fRadialFraction).put(
|
texBuf.put(fRadialFraction).put(
|
||||||
FastMath.INV_PI
|
FastMath.INV_PI
|
||||||
* (FastMath.HALF_PI + FastMath
|
* (FastMath.HALF_PI + FastMath.asin(fZFraction)));
|
||||||
.asin(fZFraction)));
|
} else if (textureMode == TextureMode.Polar) {
|
||||||
else if (textureMode == TextureMode.Polar) {
|
|
||||||
float r = (FastMath.HALF_PI - FastMath.abs(fAFraction)) / FastMath.PI;
|
float r = (FastMath.HALF_PI - FastMath.abs(fAFraction)) / FastMath.PI;
|
||||||
float u = r * afCos[iR] + 0.5f;
|
float u = r * afCos[iR] + 0.5f;
|
||||||
float v = r * afSin[iR] + 0.5f;
|
float v = r * afSin[iR] + 0.5f;
|
||||||
@ -252,43 +243,41 @@ public class Sphere extends Mesh {
|
|||||||
BufferUtils.copyInternalVector3(posBuf, iSave, i);
|
BufferUtils.copyInternalVector3(posBuf, iSave, i);
|
||||||
BufferUtils.copyInternalVector3(normBuf, iSave, i);
|
BufferUtils.copyInternalVector3(normBuf, iSave, i);
|
||||||
|
|
||||||
if (textureMode == TextureMode.Original)
|
if (textureMode == TextureMode.Original) {
|
||||||
texBuf.put(1.0f).put(
|
texBuf.put(1.0f).put(
|
||||||
0.5f * (fZFraction + 1.0f));
|
0.5f * (fZFraction + 1.0f));
|
||||||
else if (textureMode == TextureMode.Projected)
|
} else if (textureMode == TextureMode.Projected) {
|
||||||
texBuf.put(1.0f)
|
texBuf.put(1.0f).put(
|
||||||
.put(
|
FastMath.INV_PI
|
||||||
FastMath.INV_PI
|
* (FastMath.HALF_PI + FastMath.asin(fZFraction)));
|
||||||
* (FastMath.HALF_PI + FastMath
|
} else if (textureMode == TextureMode.Polar) {
|
||||||
.asin(fZFraction)));
|
|
||||||
else if (textureMode == TextureMode.Polar) {
|
|
||||||
float r = (FastMath.HALF_PI - FastMath.abs(fAFraction)) / FastMath.PI;
|
float r = (FastMath.HALF_PI - FastMath.abs(fAFraction)) / FastMath.PI;
|
||||||
texBuf.put(r+0.5f).put(0.5f);
|
texBuf.put(r + 0.5f).put(0.5f);
|
||||||
}
|
}
|
||||||
|
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
assert vars.unlock();
|
vars.release();
|
||||||
|
|
||||||
// south pole
|
// south pole
|
||||||
posBuf.position(i * 3);
|
posBuf.position(i * 3);
|
||||||
posBuf.put(0f).put(0f).put(-radius);
|
posBuf.put(0f).put(0f).put(-radius);
|
||||||
|
|
||||||
normBuf.position(i * 3);
|
normBuf.position(i * 3);
|
||||||
if (!interior)
|
if (!interior) {
|
||||||
normBuf.put(0).put(0).put(-1); // allow for inner
|
normBuf.put(0).put(0).put(-1); // allow for inner
|
||||||
// texture orientation
|
} // texture orientation
|
||||||
// later.
|
// later.
|
||||||
else
|
else {
|
||||||
normBuf.put(0).put(0).put(1);
|
normBuf.put(0).put(0).put(1);
|
||||||
|
}
|
||||||
|
|
||||||
texBuf.position(i * 2);
|
texBuf.position(i * 2);
|
||||||
|
|
||||||
if (textureMode == TextureMode.Polar) {
|
if (textureMode == TextureMode.Polar) {
|
||||||
texBuf.put(0.5f).put(0.5f);
|
texBuf.put(0.5f).put(0.5f);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
texBuf.put(0.5f).put(0.0f);
|
texBuf.put(0.5f).put(0.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -297,10 +286,11 @@ public class Sphere extends Mesh {
|
|||||||
// north pole
|
// north pole
|
||||||
posBuf.put(0).put(0).put(radius);
|
posBuf.put(0).put(0).put(radius);
|
||||||
|
|
||||||
if (!interior)
|
if (!interior) {
|
||||||
normBuf.put(0).put(0).put(1);
|
normBuf.put(0).put(0).put(1);
|
||||||
else
|
} else {
|
||||||
normBuf.put(0).put(0).put(-1);
|
normBuf.put(0).put(0).put(-1);
|
||||||
|
}
|
||||||
|
|
||||||
if (textureMode == TextureMode.Polar) {
|
if (textureMode == TextureMode.Polar) {
|
||||||
texBuf.put(0.5f).put(0.5f);
|
texBuf.put(0.5f).put(0.5f);
|
||||||
@ -331,19 +321,19 @@ public class Sphere extends Mesh {
|
|||||||
int i3 = i2 + 1;
|
int i3 = i2 + 1;
|
||||||
for (int i = 0; i < radialSamples; i++, index += 6) {
|
for (int i = 0; i < radialSamples; i++, index += 6) {
|
||||||
if (!interior) {
|
if (!interior) {
|
||||||
idxBuf.put((short)i0++);
|
idxBuf.put((short) i0++);
|
||||||
idxBuf.put((short)i1);
|
idxBuf.put((short) i1);
|
||||||
idxBuf.put((short)i2);
|
idxBuf.put((short) i2);
|
||||||
idxBuf.put((short)i1++);
|
idxBuf.put((short) i1++);
|
||||||
idxBuf.put((short)i3++);
|
idxBuf.put((short) i3++);
|
||||||
idxBuf.put((short)i2++);
|
idxBuf.put((short) i2++);
|
||||||
} else { // inside view
|
} else { // inside view
|
||||||
idxBuf.put((short)i0++);
|
idxBuf.put((short) i0++);
|
||||||
idxBuf.put((short)i2);
|
idxBuf.put((short) i2);
|
||||||
idxBuf.put((short)i1);
|
idxBuf.put((short) i1);
|
||||||
idxBuf.put((short)i1++);
|
idxBuf.put((short) i1++);
|
||||||
idxBuf.put((short)i2++);
|
idxBuf.put((short) i2++);
|
||||||
idxBuf.put((short)i3++);
|
idxBuf.put((short) i3++);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -351,13 +341,13 @@ public class Sphere extends Mesh {
|
|||||||
// south pole triangles
|
// south pole triangles
|
||||||
for (int i = 0; i < radialSamples; i++, index += 3) {
|
for (int i = 0; i < radialSamples; i++, index += 3) {
|
||||||
if (!interior) {
|
if (!interior) {
|
||||||
idxBuf.put((short)i);
|
idxBuf.put((short) i);
|
||||||
idxBuf.put((short)(vertCount - 2));
|
idxBuf.put((short) (vertCount - 2));
|
||||||
idxBuf.put((short)(i + 1));
|
idxBuf.put((short) (i + 1));
|
||||||
} else { // inside view
|
} else { // inside view
|
||||||
idxBuf.put((short)i);
|
idxBuf.put((short) i);
|
||||||
idxBuf.put((short)(i + 1));
|
idxBuf.put((short) (i + 1));
|
||||||
idxBuf.put((short)(vertCount - 2));
|
idxBuf.put((short) (vertCount - 2));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -365,13 +355,13 @@ public class Sphere extends Mesh {
|
|||||||
int iOffset = (zSamples - 3) * (radialSamples + 1);
|
int iOffset = (zSamples - 3) * (radialSamples + 1);
|
||||||
for (int i = 0; i < radialSamples; i++, index += 3) {
|
for (int i = 0; i < radialSamples; i++, index += 3) {
|
||||||
if (!interior) {
|
if (!interior) {
|
||||||
idxBuf.put((short)(i + iOffset));
|
idxBuf.put((short) (i + iOffset));
|
||||||
idxBuf.put((short)(i + 1 + iOffset));
|
idxBuf.put((short) (i + 1 + iOffset));
|
||||||
idxBuf.put((short)(vertCount - 1));
|
idxBuf.put((short) (vertCount - 1));
|
||||||
} else { // inside view
|
} else { // inside view
|
||||||
idxBuf.put((short)(i + iOffset));
|
idxBuf.put((short) (i + iOffset));
|
||||||
idxBuf.put((short)(vertCount - 1));
|
idxBuf.put((short) (vertCount - 1));
|
||||||
idxBuf.put((short)(i + 1 + iOffset));
|
idxBuf.put((short) (i + 1 + iOffset));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -427,5 +417,4 @@ public class Sphere extends Mesh {
|
|||||||
capsule.write(textureMode, "textureMode", TextureMode.Original);
|
capsule.write(textureMode, "textureMode", TextureMode.Original);
|
||||||
capsule.write(interior, "interior", false);
|
capsule.write(interior, "interior", false);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -29,7 +29,6 @@
|
|||||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.jme3.util;
|
package com.jme3.util;
|
||||||
|
|
||||||
import com.jme3.math.ColorRGBA;
|
import com.jme3.math.ColorRGBA;
|
||||||
@ -48,7 +47,6 @@ import java.util.Collections;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.WeakHashMap;
|
import java.util.WeakHashMap;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <code>BufferUtils</code> is a helper class for generating nio buffers from
|
* <code>BufferUtils</code> is a helper class for generating nio buffers from
|
||||||
* jME data classes such as Vectors and ColorRGBA.
|
* jME data classes such as Vectors and ColorRGBA.
|
||||||
@ -62,14 +60,12 @@ public final class BufferUtils {
|
|||||||
// private static final Vector2f _tempVec2 = new Vector2f();
|
// private static final Vector2f _tempVec2 = new Vector2f();
|
||||||
// private static final Vector3f _tempVec3 = new Vector3f();
|
// private static final Vector3f _tempVec3 = new Vector3f();
|
||||||
// private static final ColorRGBA _tempColor = new ColorRGBA();
|
// private static final ColorRGBA _tempColor = new ColorRGBA();
|
||||||
|
|
||||||
//// -- TRACKER HASH -- ////
|
//// -- TRACKER HASH -- ////
|
||||||
private static final Map<Buffer, Object> trackingHash = Collections.synchronizedMap(new WeakHashMap<Buffer, Object>());
|
private static final Map<Buffer, Object> trackingHash = Collections.synchronizedMap(new WeakHashMap<Buffer, Object>());
|
||||||
private static final Object ref = new Object();
|
private static final Object ref = new Object();
|
||||||
private static final boolean trackDirectMemory = false;
|
private static final boolean trackDirectMemory = false;
|
||||||
|
|
||||||
//// -- GENERIC CLONE -- ////
|
//// -- GENERIC CLONE -- ////
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a clone of the given buffer. The clone's capacity is
|
* Creates a clone of the given buffer. The clone's capacity is
|
||||||
* equal to the given buffer's limit.
|
* equal to the given buffer's limit.
|
||||||
@ -77,25 +73,23 @@ public final class BufferUtils {
|
|||||||
* @param buf The buffer to clone
|
* @param buf The buffer to clone
|
||||||
* @return The cloned buffer
|
* @return The cloned buffer
|
||||||
*/
|
*/
|
||||||
public static Buffer clone(Buffer buf){
|
public static Buffer clone(Buffer buf) {
|
||||||
if (buf instanceof FloatBuffer){
|
if (buf instanceof FloatBuffer) {
|
||||||
return clone( (FloatBuffer) buf );
|
return clone((FloatBuffer) buf);
|
||||||
}else if (buf instanceof ShortBuffer){
|
} else if (buf instanceof ShortBuffer) {
|
||||||
return clone( (ShortBuffer) buf );
|
return clone((ShortBuffer) buf);
|
||||||
}else if (buf instanceof ByteBuffer){
|
} else if (buf instanceof ByteBuffer) {
|
||||||
return clone( (ByteBuffer) buf );
|
return clone((ByteBuffer) buf);
|
||||||
}else if (buf instanceof IntBuffer){
|
} else if (buf instanceof IntBuffer) {
|
||||||
return clone( (IntBuffer) buf );
|
return clone((IntBuffer) buf);
|
||||||
}else if (buf instanceof DoubleBuffer){
|
} else if (buf instanceof DoubleBuffer) {
|
||||||
return clone( (DoubleBuffer) buf );
|
return clone((DoubleBuffer) buf);
|
||||||
}else{
|
} else {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//// -- VECTOR3F METHODS -- ////
|
//// -- VECTOR3F METHODS -- ////
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate a new FloatBuffer using the given array of Vector3f objects.
|
* Generate a new FloatBuffer using the given array of Vector3f objects.
|
||||||
* The FloatBuffer will be 3 * data.length long and contain the vector data
|
* The FloatBuffer will be 3 * data.length long and contain the vector data
|
||||||
@ -103,14 +97,17 @@ public final class BufferUtils {
|
|||||||
*
|
*
|
||||||
* @param data array of Vector3f objects to place into a new FloatBuffer
|
* @param data array of Vector3f objects to place into a new FloatBuffer
|
||||||
*/
|
*/
|
||||||
public static FloatBuffer createFloatBuffer(Vector3f ... data) {
|
public static FloatBuffer createFloatBuffer(Vector3f... data) {
|
||||||
if (data == null) return null;
|
if (data == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
FloatBuffer buff = createFloatBuffer(3 * data.length);
|
FloatBuffer buff = createFloatBuffer(3 * data.length);
|
||||||
for (int x = 0; x < data.length; x++) {
|
for (int x = 0; x < data.length; x++) {
|
||||||
if (data[x] != null)
|
if (data[x] != null) {
|
||||||
buff.put(data[x].x).put(data[x].y).put(data[x].z);
|
buff.put(data[x].x).put(data[x].y).put(data[x].z);
|
||||||
else
|
} else {
|
||||||
buff.put(0).put(0).put(0);
|
buff.put(0).put(0).put(0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
buff.flip();
|
buff.flip();
|
||||||
return buff;
|
return buff;
|
||||||
@ -122,15 +119,17 @@ public final class BufferUtils {
|
|||||||
*
|
*
|
||||||
* @param data array of Quaternion objects to place into a new FloatBuffer
|
* @param data array of Quaternion objects to place into a new FloatBuffer
|
||||||
*/
|
*/
|
||||||
public static FloatBuffer createFloatBuffer(Quaternion ... data) {
|
public static FloatBuffer createFloatBuffer(Quaternion... data) {
|
||||||
if (data == null) return null;
|
if (data == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
FloatBuffer buff = createFloatBuffer(4 * data.length);
|
FloatBuffer buff = createFloatBuffer(4 * data.length);
|
||||||
for (int x = 0; x < data.length; x++) {
|
for (int x = 0; x < data.length; x++) {
|
||||||
if (data[x] != null)
|
if (data[x] != null) {
|
||||||
buff.put(data[x].getX()).put(data[x].getY())
|
buff.put(data[x].getX()).put(data[x].getY()).put(data[x].getZ()).put(data[x].getW());
|
||||||
.put(data[x].getZ()).put(data[x].getW());
|
} else {
|
||||||
else
|
|
||||||
buff.put(0).put(0).put(0);
|
buff.put(0).put(0).put(0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
buff.flip();
|
buff.flip();
|
||||||
return buff;
|
return buff;
|
||||||
@ -140,8 +139,10 @@ public final class BufferUtils {
|
|||||||
* Generate a new FloatBuffer using the given array of float primitives.
|
* Generate a new FloatBuffer using the given array of float primitives.
|
||||||
* @param data array of float primitives to place into a new FloatBuffer
|
* @param data array of float primitives to place into a new FloatBuffer
|
||||||
*/
|
*/
|
||||||
public static FloatBuffer createFloatBuffer(float ... data) {
|
public static FloatBuffer createFloatBuffer(float... data) {
|
||||||
if (data == null) return null;
|
if (data == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
FloatBuffer buff = createFloatBuffer(data.length);
|
FloatBuffer buff = createFloatBuffer(data.length);
|
||||||
buff.clear();
|
buff.clear();
|
||||||
buff.put(data);
|
buff.put(data);
|
||||||
@ -197,7 +198,7 @@ public final class BufferUtils {
|
|||||||
*/
|
*/
|
||||||
public static void setInBuffer(ColorRGBA color, FloatBuffer buf,
|
public static void setInBuffer(ColorRGBA color, FloatBuffer buf,
|
||||||
int index) {
|
int index) {
|
||||||
buf.position(index*4);
|
buf.position(index * 4);
|
||||||
buf.put(color.r);
|
buf.put(color.r);
|
||||||
buf.put(color.g);
|
buf.put(color.g);
|
||||||
buf.put(color.b);
|
buf.put(color.b);
|
||||||
@ -217,7 +218,7 @@ public final class BufferUtils {
|
|||||||
*/
|
*/
|
||||||
public static void setInBuffer(Quaternion quat, FloatBuffer buf,
|
public static void setInBuffer(Quaternion quat, FloatBuffer buf,
|
||||||
int index) {
|
int index) {
|
||||||
buf.position(index*4);
|
buf.position(index * 4);
|
||||||
buf.put(quat.getX());
|
buf.put(quat.getX());
|
||||||
buf.put(quat.getY());
|
buf.put(quat.getY());
|
||||||
buf.put(quat.getZ());
|
buf.put(quat.getZ());
|
||||||
@ -236,17 +237,17 @@ public final class BufferUtils {
|
|||||||
* the postion to place the data; in terms of vectors not floats
|
* the postion to place the data; in terms of vectors not floats
|
||||||
*/
|
*/
|
||||||
public static void setInBuffer(Vector3f vector, FloatBuffer buf, int index) {
|
public static void setInBuffer(Vector3f vector, FloatBuffer buf, int index) {
|
||||||
if(buf == null) {
|
if (buf == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(vector == null) {
|
if (vector == null) {
|
||||||
buf.put(index * 3, 0);
|
buf.put(index * 3, 0);
|
||||||
buf.put((index * 3) + 1, 0);
|
buf.put((index * 3) + 1, 0);
|
||||||
buf.put((index * 3) + 2, 0);
|
buf.put((index * 3) + 2, 0);
|
||||||
} else {
|
} else {
|
||||||
buf.put(index * 3, vector.x);
|
buf.put(index * 3, vector.x);
|
||||||
buf.put((index * 3) + 1, vector.y);
|
buf.put((index * 3) + 1, vector.y);
|
||||||
buf.put((index * 3) + 2, vector.z);
|
buf.put((index * 3) + 2, vector.z);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -263,9 +264,9 @@ public final class BufferUtils {
|
|||||||
* the buf
|
* the buf
|
||||||
*/
|
*/
|
||||||
public static void populateFromBuffer(Vector3f vector, FloatBuffer buf, int index) {
|
public static void populateFromBuffer(Vector3f vector, FloatBuffer buf, int index) {
|
||||||
vector.x = buf.get(index*3);
|
vector.x = buf.get(index * 3);
|
||||||
vector.y = buf.get(index*3+1);
|
vector.y = buf.get(index * 3 + 1);
|
||||||
vector.z = buf.get(index*3+2);
|
vector.z = buf.get(index * 3 + 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -298,7 +299,7 @@ public final class BufferUtils {
|
|||||||
* the index to copy the vector to
|
* the index to copy the vector to
|
||||||
*/
|
*/
|
||||||
public static void copyInternalVector3(FloatBuffer buf, int fromPos, int toPos) {
|
public static void copyInternalVector3(FloatBuffer buf, int fromPos, int toPos) {
|
||||||
copyInternal(buf, fromPos*3, toPos*3, 3);
|
copyInternal(buf, fromPos * 3, toPos * 3, 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -311,12 +312,12 @@ public final class BufferUtils {
|
|||||||
* to normalize
|
* to normalize
|
||||||
*/
|
*/
|
||||||
public static void normalizeVector3(FloatBuffer buf, int index) {
|
public static void normalizeVector3(FloatBuffer buf, int index) {
|
||||||
assert TempVars.get().lock();
|
TempVars vars = TempVars.get();
|
||||||
Vector3f tempVec3 = TempVars.get().vect1;
|
Vector3f tempVec3 = vars.vect1;
|
||||||
populateFromBuffer(tempVec3, buf, index);
|
populateFromBuffer(tempVec3, buf, index);
|
||||||
tempVec3.normalizeLocal();
|
tempVec3.normalizeLocal();
|
||||||
setInBuffer(tempVec3, buf, index);
|
setInBuffer(tempVec3, buf, index);
|
||||||
assert TempVars.get().unlock();
|
vars.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -331,12 +332,12 @@ public final class BufferUtils {
|
|||||||
* to add to
|
* to add to
|
||||||
*/
|
*/
|
||||||
public static void addInBuffer(Vector3f toAdd, FloatBuffer buf, int index) {
|
public static void addInBuffer(Vector3f toAdd, FloatBuffer buf, int index) {
|
||||||
assert TempVars.get().lock();
|
TempVars vars = TempVars.get();
|
||||||
Vector3f tempVec3 = TempVars.get().vect1;
|
Vector3f tempVec3 = vars.vect1;
|
||||||
populateFromBuffer(tempVec3, buf, index);
|
populateFromBuffer(tempVec3, buf, index);
|
||||||
tempVec3.addLocal(toAdd);
|
tempVec3.addLocal(toAdd);
|
||||||
setInBuffer(tempVec3, buf, index);
|
setInBuffer(tempVec3, buf, index);
|
||||||
assert TempVars.get().unlock();
|
vars.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -351,12 +352,12 @@ public final class BufferUtils {
|
|||||||
* to multiply
|
* to multiply
|
||||||
*/
|
*/
|
||||||
public static void multInBuffer(Vector3f toMult, FloatBuffer buf, int index) {
|
public static void multInBuffer(Vector3f toMult, FloatBuffer buf, int index) {
|
||||||
assert TempVars.get().lock();
|
TempVars vars = TempVars.get();
|
||||||
Vector3f tempVec3 = TempVars.get().vect1;
|
Vector3f tempVec3 = vars.vect1;
|
||||||
populateFromBuffer(tempVec3, buf, index);
|
populateFromBuffer(tempVec3, buf, index);
|
||||||
tempVec3.multLocal(toMult);
|
tempVec3.multLocal(toMult);
|
||||||
setInBuffer(tempVec3, buf, index);
|
setInBuffer(tempVec3, buf, index);
|
||||||
assert TempVars.get().unlock();
|
vars.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -373,16 +374,15 @@ public final class BufferUtils {
|
|||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public static boolean equals(Vector3f check, FloatBuffer buf, int index) {
|
public static boolean equals(Vector3f check, FloatBuffer buf, int index) {
|
||||||
assert TempVars.get().lock();
|
TempVars vars = TempVars.get();
|
||||||
Vector3f tempVec3 = TempVars.get().vect1;
|
Vector3f tempVec3 = vars.vect1;
|
||||||
populateFromBuffer(tempVec3, buf, index);
|
populateFromBuffer(tempVec3, buf, index);
|
||||||
boolean eq = tempVec3.equals(check);
|
boolean eq = tempVec3.equals(check);
|
||||||
assert TempVars.get().unlock();
|
vars.release();
|
||||||
return eq;
|
return eq;
|
||||||
}
|
}
|
||||||
|
|
||||||
// // -- VECTOR2F METHODS -- ////
|
// // -- VECTOR2F METHODS -- ////
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate a new FloatBuffer using the given array of Vector2f objects.
|
* Generate a new FloatBuffer using the given array of Vector2f objects.
|
||||||
* The FloatBuffer will be 2 * data.length long and contain the vector data
|
* The FloatBuffer will be 2 * data.length long and contain the vector data
|
||||||
@ -390,14 +390,17 @@ public final class BufferUtils {
|
|||||||
*
|
*
|
||||||
* @param data array of Vector2f objects to place into a new FloatBuffer
|
* @param data array of Vector2f objects to place into a new FloatBuffer
|
||||||
*/
|
*/
|
||||||
public static FloatBuffer createFloatBuffer(Vector2f ... data) {
|
public static FloatBuffer createFloatBuffer(Vector2f... data) {
|
||||||
if (data == null) return null;
|
if (data == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
FloatBuffer buff = createFloatBuffer(2 * data.length);
|
FloatBuffer buff = createFloatBuffer(2 * data.length);
|
||||||
for (int x = 0; x < data.length; x++) {
|
for (int x = 0; x < data.length; x++) {
|
||||||
if (data[x] != null)
|
if (data[x] != null) {
|
||||||
buff.put(data[x].x).put(data[x].y);
|
buff.put(data[x].x).put(data[x].y);
|
||||||
else
|
} else {
|
||||||
buff.put(0).put(0);
|
buff.put(0).put(0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
buff.flip();
|
buff.flip();
|
||||||
return buff;
|
return buff;
|
||||||
@ -467,8 +470,8 @@ public final class BufferUtils {
|
|||||||
* the buf
|
* the buf
|
||||||
*/
|
*/
|
||||||
public static void populateFromBuffer(Vector2f vector, FloatBuffer buf, int index) {
|
public static void populateFromBuffer(Vector2f vector, FloatBuffer buf, int index) {
|
||||||
vector.x = buf.get(index*2);
|
vector.x = buf.get(index * 2);
|
||||||
vector.y = buf.get(index*2+1);
|
vector.y = buf.get(index * 2 + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -501,7 +504,7 @@ public final class BufferUtils {
|
|||||||
* the index to copy the vector to
|
* the index to copy the vector to
|
||||||
*/
|
*/
|
||||||
public static void copyInternalVector2(FloatBuffer buf, int fromPos, int toPos) {
|
public static void copyInternalVector2(FloatBuffer buf, int fromPos, int toPos) {
|
||||||
copyInternal(buf, fromPos*2, toPos*2, 2);
|
copyInternal(buf, fromPos * 2, toPos * 2, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -514,12 +517,12 @@ public final class BufferUtils {
|
|||||||
* to normalize
|
* to normalize
|
||||||
*/
|
*/
|
||||||
public static void normalizeVector2(FloatBuffer buf, int index) {
|
public static void normalizeVector2(FloatBuffer buf, int index) {
|
||||||
assert TempVars.get().lock();
|
TempVars vars = TempVars.get();
|
||||||
Vector2f tempVec2 = TempVars.get().vect2d;
|
Vector2f tempVec2 = vars.vect2d;
|
||||||
populateFromBuffer(tempVec2, buf, index);
|
populateFromBuffer(tempVec2, buf, index);
|
||||||
tempVec2.normalizeLocal();
|
tempVec2.normalizeLocal();
|
||||||
setInBuffer(tempVec2, buf, index);
|
setInBuffer(tempVec2, buf, index);
|
||||||
assert TempVars.get().unlock();
|
vars.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -534,12 +537,12 @@ public final class BufferUtils {
|
|||||||
* to add to
|
* to add to
|
||||||
*/
|
*/
|
||||||
public static void addInBuffer(Vector2f toAdd, FloatBuffer buf, int index) {
|
public static void addInBuffer(Vector2f toAdd, FloatBuffer buf, int index) {
|
||||||
assert TempVars.get().lock();
|
TempVars vars = TempVars.get();
|
||||||
Vector2f tempVec2 = TempVars.get().vect2d;
|
Vector2f tempVec2 = vars.vect2d;
|
||||||
populateFromBuffer(tempVec2, buf, index);
|
populateFromBuffer(tempVec2, buf, index);
|
||||||
tempVec2.addLocal(toAdd);
|
tempVec2.addLocal(toAdd);
|
||||||
setInBuffer(tempVec2, buf, index);
|
setInBuffer(tempVec2, buf, index);
|
||||||
assert TempVars.get().unlock();
|
vars.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -554,12 +557,12 @@ public final class BufferUtils {
|
|||||||
* to multiply
|
* to multiply
|
||||||
*/
|
*/
|
||||||
public static void multInBuffer(Vector2f toMult, FloatBuffer buf, int index) {
|
public static void multInBuffer(Vector2f toMult, FloatBuffer buf, int index) {
|
||||||
assert TempVars.get().lock();
|
TempVars vars = TempVars.get();
|
||||||
Vector2f tempVec2 = TempVars.get().vect2d;
|
Vector2f tempVec2 = vars.vect2d;
|
||||||
populateFromBuffer(tempVec2, buf, index);
|
populateFromBuffer(tempVec2, buf, index);
|
||||||
tempVec2.multLocal(toMult);
|
tempVec2.multLocal(toMult);
|
||||||
setInBuffer(tempVec2, buf, index);
|
setInBuffer(tempVec2, buf, index);
|
||||||
assert TempVars.get().unlock();
|
vars.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -576,17 +579,15 @@ public final class BufferUtils {
|
|||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public static boolean equals(Vector2f check, FloatBuffer buf, int index) {
|
public static boolean equals(Vector2f check, FloatBuffer buf, int index) {
|
||||||
assert TempVars.get().lock();
|
TempVars vars = TempVars.get();
|
||||||
Vector2f tempVec2 = TempVars.get().vect2d;
|
Vector2f tempVec2 = vars.vect2d;
|
||||||
populateFromBuffer(tempVec2, buf, index);
|
populateFromBuffer(tempVec2, buf, index);
|
||||||
boolean eq = tempVec2.equals(check);
|
boolean eq = tempVec2.equals(check);
|
||||||
assert TempVars.get().unlock();
|
vars.release();
|
||||||
return eq;
|
return eq;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//// -- INT METHODS -- ////
|
//// -- INT METHODS -- ////
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate a new IntBuffer using the given array of ints. The IntBuffer
|
* Generate a new IntBuffer using the given array of ints. The IntBuffer
|
||||||
* will be data.length long and contain the int data as data[0], data[1]...
|
* will be data.length long and contain the int data as data[0], data[1]...
|
||||||
@ -596,7 +597,9 @@ public final class BufferUtils {
|
|||||||
* array of ints to place into a new IntBuffer
|
* array of ints to place into a new IntBuffer
|
||||||
*/
|
*/
|
||||||
public static IntBuffer createIntBuffer(int... data) {
|
public static IntBuffer createIntBuffer(int... data) {
|
||||||
if (data == null) return null;
|
if (data == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
IntBuffer buff = createIntBuffer(data.length);
|
IntBuffer buff = createIntBuffer(data.length);
|
||||||
buff.clear();
|
buff.clear();
|
||||||
buff.put(data);
|
buff.put(data);
|
||||||
@ -613,7 +616,9 @@ public final class BufferUtils {
|
|||||||
* @return a new int array populated from the IntBuffer
|
* @return a new int array populated from the IntBuffer
|
||||||
*/
|
*/
|
||||||
public static int[] getIntArray(IntBuffer buff) {
|
public static int[] getIntArray(IntBuffer buff) {
|
||||||
if (buff == null) return null;
|
if (buff == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
buff.clear();
|
buff.clear();
|
||||||
int[] inds = new int[buff.limit()];
|
int[] inds = new int[buff.limit()];
|
||||||
for (int x = 0; x < inds.length; x++) {
|
for (int x = 0; x < inds.length; x++) {
|
||||||
@ -631,7 +636,9 @@ public final class BufferUtils {
|
|||||||
* @return a new float array populated from the FloatBuffer
|
* @return a new float array populated from the FloatBuffer
|
||||||
*/
|
*/
|
||||||
public static float[] getFloatArray(FloatBuffer buff) {
|
public static float[] getFloatArray(FloatBuffer buff) {
|
||||||
if (buff == null) return null;
|
if (buff == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
buff.clear();
|
buff.clear();
|
||||||
float[] inds = new float[buff.limit()];
|
float[] inds = new float[buff.limit()];
|
||||||
for (int x = 0; x < inds.length; x++) {
|
for (int x = 0; x < inds.length; x++) {
|
||||||
@ -640,9 +647,7 @@ public final class BufferUtils {
|
|||||||
return inds;
|
return inds;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//// -- GENERAL DOUBLE ROUTINES -- ////
|
//// -- GENERAL DOUBLE ROUTINES -- ////
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new DoubleBuffer of the specified size.
|
* Create a new DoubleBuffer of the specified size.
|
||||||
*
|
*
|
||||||
@ -691,13 +696,15 @@ public final class BufferUtils {
|
|||||||
* @return the copy
|
* @return the copy
|
||||||
*/
|
*/
|
||||||
public static DoubleBuffer clone(DoubleBuffer buf) {
|
public static DoubleBuffer clone(DoubleBuffer buf) {
|
||||||
if (buf == null) return null;
|
if (buf == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
buf.rewind();
|
buf.rewind();
|
||||||
|
|
||||||
DoubleBuffer copy;
|
DoubleBuffer copy;
|
||||||
if (buf.isDirect()){
|
if (buf.isDirect()) {
|
||||||
copy = createDoubleBuffer(buf.limit());
|
copy = createDoubleBuffer(buf.limit());
|
||||||
}else{
|
} else {
|
||||||
copy = DoubleBuffer.allocate(buf.limit());
|
copy = DoubleBuffer.allocate(buf.limit());
|
||||||
}
|
}
|
||||||
copy.put(buf);
|
copy.put(buf);
|
||||||
@ -705,10 +712,7 @@ public final class BufferUtils {
|
|||||||
return copy;
|
return copy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//// -- GENERAL FLOAT ROUTINES -- ////
|
//// -- GENERAL FLOAT ROUTINES -- ////
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new FloatBuffer of the specified size.
|
* Create a new FloatBuffer of the specified size.
|
||||||
*
|
*
|
||||||
@ -756,13 +760,15 @@ public final class BufferUtils {
|
|||||||
* @return the copy
|
* @return the copy
|
||||||
*/
|
*/
|
||||||
public static FloatBuffer clone(FloatBuffer buf) {
|
public static FloatBuffer clone(FloatBuffer buf) {
|
||||||
if (buf == null) return null;
|
if (buf == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
buf.rewind();
|
buf.rewind();
|
||||||
|
|
||||||
FloatBuffer copy;
|
FloatBuffer copy;
|
||||||
if (buf.isDirect()){
|
if (buf.isDirect()) {
|
||||||
copy = createFloatBuffer(buf.limit());
|
copy = createFloatBuffer(buf.limit());
|
||||||
}else{
|
} else {
|
||||||
copy = FloatBuffer.allocate(buf.limit());
|
copy = FloatBuffer.allocate(buf.limit());
|
||||||
}
|
}
|
||||||
copy.put(buf);
|
copy.put(buf);
|
||||||
@ -770,9 +776,7 @@ public final class BufferUtils {
|
|||||||
return copy;
|
return copy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//// -- GENERAL INT ROUTINES -- ////
|
//// -- GENERAL INT ROUTINES -- ////
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new IntBuffer of the specified size.
|
* Create a new IntBuffer of the specified size.
|
||||||
*
|
*
|
||||||
@ -821,13 +825,15 @@ public final class BufferUtils {
|
|||||||
* @return the copy
|
* @return the copy
|
||||||
*/
|
*/
|
||||||
public static IntBuffer clone(IntBuffer buf) {
|
public static IntBuffer clone(IntBuffer buf) {
|
||||||
if (buf == null) return null;
|
if (buf == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
buf.rewind();
|
buf.rewind();
|
||||||
|
|
||||||
IntBuffer copy;
|
IntBuffer copy;
|
||||||
if (buf.isDirect()){
|
if (buf.isDirect()) {
|
||||||
copy = createIntBuffer(buf.limit());
|
copy = createIntBuffer(buf.limit());
|
||||||
}else{
|
} else {
|
||||||
copy = IntBuffer.allocate(buf.limit());
|
copy = IntBuffer.allocate(buf.limit());
|
||||||
}
|
}
|
||||||
copy.put(buf);
|
copy.put(buf);
|
||||||
@ -835,9 +841,7 @@ public final class BufferUtils {
|
|||||||
return copy;
|
return copy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//// -- GENERAL BYTE ROUTINES -- ////
|
//// -- GENERAL BYTE ROUTINES -- ////
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new ByteBuffer of the specified size.
|
* Create a new ByteBuffer of the specified size.
|
||||||
*
|
*
|
||||||
@ -875,14 +879,14 @@ public final class BufferUtils {
|
|||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ByteBuffer createByteBuffer(byte ... data){
|
public static ByteBuffer createByteBuffer(byte... data) {
|
||||||
ByteBuffer bb = createByteBuffer(data.length);
|
ByteBuffer bb = createByteBuffer(data.length);
|
||||||
bb.put(data);
|
bb.put(data);
|
||||||
bb.flip();
|
bb.flip();
|
||||||
return bb;
|
return bb;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ByteBuffer createByteBuffer(String data){
|
public static ByteBuffer createByteBuffer(String data) {
|
||||||
byte[] bytes = data.getBytes();
|
byte[] bytes = data.getBytes();
|
||||||
ByteBuffer bb = createByteBuffer(bytes.length);
|
ByteBuffer bb = createByteBuffer(bytes.length);
|
||||||
bb.put(bytes);
|
bb.put(bytes);
|
||||||
@ -901,13 +905,15 @@ public final class BufferUtils {
|
|||||||
* @return the copy
|
* @return the copy
|
||||||
*/
|
*/
|
||||||
public static ByteBuffer clone(ByteBuffer buf) {
|
public static ByteBuffer clone(ByteBuffer buf) {
|
||||||
if (buf == null) return null;
|
if (buf == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
buf.rewind();
|
buf.rewind();
|
||||||
|
|
||||||
ByteBuffer copy;
|
ByteBuffer copy;
|
||||||
if (buf.isDirect()){
|
if (buf.isDirect()) {
|
||||||
copy = createByteBuffer(buf.limit());
|
copy = createByteBuffer(buf.limit());
|
||||||
}else{
|
} else {
|
||||||
copy = ByteBuffer.allocate(buf.limit());
|
copy = ByteBuffer.allocate(buf.limit());
|
||||||
}
|
}
|
||||||
copy.put(buf);
|
copy.put(buf);
|
||||||
@ -915,9 +921,7 @@ public final class BufferUtils {
|
|||||||
return copy;
|
return copy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//// -- GENERAL SHORT ROUTINES -- ////
|
//// -- GENERAL SHORT ROUTINES -- ////
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new ShortBuffer of the specified size.
|
* Create a new ShortBuffer of the specified size.
|
||||||
*
|
*
|
||||||
@ -956,7 +960,9 @@ public final class BufferUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static ShortBuffer createShortBuffer(short... data) {
|
public static ShortBuffer createShortBuffer(short... data) {
|
||||||
if (data == null) return null;
|
if (data == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
ShortBuffer buff = createShortBuffer(data.length);
|
ShortBuffer buff = createShortBuffer(data.length);
|
||||||
buff.clear();
|
buff.clear();
|
||||||
buff.put(data);
|
buff.put(data);
|
||||||
@ -975,13 +981,15 @@ public final class BufferUtils {
|
|||||||
* @return the copy
|
* @return the copy
|
||||||
*/
|
*/
|
||||||
public static ShortBuffer clone(ShortBuffer buf) {
|
public static ShortBuffer clone(ShortBuffer buf) {
|
||||||
if (buf == null) return null;
|
if (buf == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
buf.rewind();
|
buf.rewind();
|
||||||
|
|
||||||
ShortBuffer copy;
|
ShortBuffer copy;
|
||||||
if (buf.isDirect()){
|
if (buf.isDirect()) {
|
||||||
copy = createShortBuffer(buf.limit());
|
copy = createShortBuffer(buf.limit());
|
||||||
}else{
|
} else {
|
||||||
copy = ShortBuffer.allocate(buf.limit());
|
copy = ShortBuffer.allocate(buf.limit());
|
||||||
}
|
}
|
||||||
copy.put(buf);
|
copy.put(buf);
|
||||||
@ -997,42 +1005,42 @@ public final class BufferUtils {
|
|||||||
* @return a buffer large enough to receive at least the <code>required</code> number of entries, same position as
|
* @return a buffer large enough to receive at least the <code>required</code> number of entries, same position as
|
||||||
* the input buffer, not null
|
* the input buffer, not null
|
||||||
*/
|
*/
|
||||||
public static FloatBuffer ensureLargeEnough( FloatBuffer buffer, int required ) {
|
public static FloatBuffer ensureLargeEnough(FloatBuffer buffer, int required) {
|
||||||
if ( buffer == null || ( buffer.remaining() < required ) ) {
|
if (buffer == null || (buffer.remaining() < required)) {
|
||||||
int position = ( buffer != null ? buffer.position() : 0 );
|
int position = (buffer != null ? buffer.position() : 0);
|
||||||
FloatBuffer newVerts = createFloatBuffer( position + required );
|
FloatBuffer newVerts = createFloatBuffer(position + required);
|
||||||
if ( buffer != null ) {
|
if (buffer != null) {
|
||||||
buffer.rewind();
|
buffer.rewind();
|
||||||
newVerts.put( buffer );
|
newVerts.put(buffer);
|
||||||
newVerts.position( position );
|
newVerts.position(position);
|
||||||
}
|
}
|
||||||
buffer = newVerts;
|
buffer = newVerts;
|
||||||
}
|
}
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ShortBuffer ensureLargeEnough( ShortBuffer buffer, int required ) {
|
public static ShortBuffer ensureLargeEnough(ShortBuffer buffer, int required) {
|
||||||
if ( buffer == null || ( buffer.remaining() < required ) ) {
|
if (buffer == null || (buffer.remaining() < required)) {
|
||||||
int position = ( buffer != null ? buffer.position() : 0 );
|
int position = (buffer != null ? buffer.position() : 0);
|
||||||
ShortBuffer newVerts = createShortBuffer( position + required );
|
ShortBuffer newVerts = createShortBuffer(position + required);
|
||||||
if ( buffer != null ) {
|
if (buffer != null) {
|
||||||
buffer.rewind();
|
buffer.rewind();
|
||||||
newVerts.put( buffer );
|
newVerts.put(buffer);
|
||||||
newVerts.position( position );
|
newVerts.position(position);
|
||||||
}
|
}
|
||||||
buffer = newVerts;
|
buffer = newVerts;
|
||||||
}
|
}
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ByteBuffer ensureLargeEnough( ByteBuffer buffer, int required ) {
|
public static ByteBuffer ensureLargeEnough(ByteBuffer buffer, int required) {
|
||||||
if ( buffer == null || ( buffer.remaining() < required ) ) {
|
if (buffer == null || (buffer.remaining() < required)) {
|
||||||
int position = ( buffer != null ? buffer.position() : 0 );
|
int position = (buffer != null ? buffer.position() : 0);
|
||||||
ByteBuffer newVerts = createByteBuffer( position + required );
|
ByteBuffer newVerts = createByteBuffer(position + required);
|
||||||
if ( buffer != null ) {
|
if (buffer != null) {
|
||||||
buffer.rewind();
|
buffer.rewind();
|
||||||
newVerts.put( buffer );
|
newVerts.put(buffer);
|
||||||
newVerts.position( position );
|
newVerts.position(position);
|
||||||
}
|
}
|
||||||
buffer = newVerts;
|
buffer = newVerts;
|
||||||
}
|
}
|
||||||
@ -1068,25 +1076,20 @@ public final class BufferUtils {
|
|||||||
dBufs++;
|
dBufs++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
long heapMem = Runtime.getRuntime().totalMemory() -
|
long heapMem = Runtime.getRuntime().totalMemory()
|
||||||
Runtime.getRuntime().freeMemory();
|
- Runtime.getRuntime().freeMemory();
|
||||||
|
|
||||||
boolean printStout = store == null;
|
boolean printStout = store == null;
|
||||||
if (store == null) {
|
if (store == null) {
|
||||||
store = new StringBuilder();
|
store = new StringBuilder();
|
||||||
}
|
}
|
||||||
store.append("Existing buffers: ").append(bufs.size()).append("\n");
|
store.append("Existing buffers: ").append(bufs.size()).append("\n");
|
||||||
store.append("(b: ").append(bBufs).append(" f: ").append(fBufs)
|
store.append("(b: ").append(bBufs).append(" f: ").append(fBufs).append(" i: ").append(iBufs).append(" s: ").append(sBufs).append(" d: ").append(dBufs).append(")").append("\n");
|
||||||
.append(" i: ").append(iBufs).append(" s: ").append(sBufs)
|
store.append("Total heap memory held: ").append(heapMem / 1024).append("kb\n");
|
||||||
.append(" d: ").append(dBufs).append(")").append("\n");
|
store.append("Total direct memory held: ").append(totalHeld / 1024).append("kb\n");
|
||||||
store.append("Total heap memory held: ").append(heapMem/1024).append("kb\n");
|
store.append("(b: ").append(bBufsM / 1024).append("kb f: ").append(fBufsM / 1024).append("kb i: ").append(iBufsM / 1024).append("kb s: ").append(sBufsM / 1024).append("kb d: ").append(dBufsM / 1024).append("kb)").append("\n");
|
||||||
store.append("Total direct memory held: ").append(totalHeld/1024).append("kb\n");
|
|
||||||
store.append("(b: ").append(bBufsM/1024).append("kb f: ").append(fBufsM/1024)
|
|
||||||
.append("kb i: ").append(iBufsM/1024).append("kb s: ").append(sBufsM/1024)
|
|
||||||
.append("kb d: ").append(dBufsM/1024).append("kb)").append("\n");
|
|
||||||
if (printStout) {
|
if (printStout) {
|
||||||
System.out.println(store.toString());
|
System.out.println(store.toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -29,7 +29,6 @@
|
|||||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.jme3.util;
|
package com.jme3.util;
|
||||||
|
|
||||||
import com.jme3.collision.bih.BIHNode.BIHStackData;
|
import com.jme3.collision.bih.BIHNode.BIHStackData;
|
||||||
@ -45,94 +44,148 @@ import com.jme3.scene.Spatial;
|
|||||||
import java.nio.FloatBuffer;
|
import java.nio.FloatBuffer;
|
||||||
import java.nio.IntBuffer;
|
import java.nio.IntBuffer;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Temporary variables assigned to each thread. Engine classes may access
|
* Temporary variables assigned to each thread. Engine classes may access
|
||||||
* these temp variables with TempVars.get(). A method using temp vars with this
|
* these temp variables with TempVars.get().
|
||||||
* class is not allowed to make calls to other methods using the class otherwise
|
* This returns an available instance of the TempVar class ensuring this particular instance is never used elsewhere in the mean time.
|
||||||
* memory corruption will occur. A locking mechanism may be implemented
|
|
||||||
* in the future to prevent the occurance of such situation.
|
|
||||||
*/
|
*/
|
||||||
public class TempVars {
|
public class TempVars {
|
||||||
|
|
||||||
private static final ThreadLocal<TempVars> varsLocal
|
private static final Logger log = Logger.getLogger(TempVars.class.getName());
|
||||||
= new ThreadLocal<TempVars>(){
|
//default array size
|
||||||
|
private static final int arraySize = 30;
|
||||||
|
//one array per thread
|
||||||
|
private static final ThreadLocal<TempVars[]> varsLocal = new ThreadLocal<TempVars[]>() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TempVars initialValue(){
|
public TempVars[] initialValue() {
|
||||||
return new TempVars();
|
TempVars[] l = new TempVars[arraySize];
|
||||||
|
//the array is initialized with one instance (should be enough in most cases)
|
||||||
|
l[0] = new TempVars();
|
||||||
|
return l;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
//the current index in the stack
|
||||||
|
private static int stackLevel = 0;
|
||||||
|
//number of instanced TempVar, just to raise a warning if too much are instanced
|
||||||
|
private static int instanceCount = 1;
|
||||||
|
|
||||||
public static TempVars get(){
|
/**
|
||||||
return varsLocal.get();
|
* Returns an available instance of the TempVar class
|
||||||
}
|
* Warning, you have to release the instance once used by calling the release() method
|
||||||
|
* @return a TempVar instance
|
||||||
|
*/
|
||||||
|
public static TempVars get() {
|
||||||
|
|
||||||
private TempVars(){
|
TempVars vars = null;
|
||||||
}
|
TempVars[] array = varsLocal.get();
|
||||||
|
//if the stack level is > 0 it means we have some instances in the array, we can return one of them
|
||||||
|
if (stackLevel >= 0) {
|
||||||
|
//getting the lastTempVar instance
|
||||||
|
vars = array[stackLevel];
|
||||||
|
//removing the reference to it in the array so if it's never released it will be garbage collected.
|
||||||
|
array[stackLevel] = null;
|
||||||
|
//decreasing the stack level since we have one less instance
|
||||||
|
stackLevel--;
|
||||||
|
|
||||||
private boolean locked = false;
|
//In some cases (when lauching jme threads from another thread), the instance at 0 can be null
|
||||||
private StackTraceElement[] lockerStack;
|
//so we check that to avoid NPE
|
||||||
|
if (vars==null){
|
||||||
public final boolean lock(){
|
vars = new TempVars();
|
||||||
if (locked){
|
//increasing the count to keep track
|
||||||
System.err.println("INTERNAL ERROR");
|
instanceCount++;
|
||||||
System.err.println("Offending trace: ");
|
}
|
||||||
|
} else {
|
||||||
StackTraceElement[] stack = new Throwable().getStackTrace();
|
//if the stack level is <0 it means the stack is empty, we have to create a new instance
|
||||||
for (int i = 1; i < stack.length; i++){
|
//there
|
||||||
System.err.println("\tat "+stack[i].toString());
|
vars = new TempVars();
|
||||||
}
|
//increasing the count to keep track
|
||||||
|
instanceCount++;
|
||||||
System.err.println("Attempted to aquire TempVars lock owned by");
|
//raising a warning if the instance count is to high, because it might be due to bad usage
|
||||||
for (int i = 1; i < lockerStack.length; i++){
|
if (instanceCount == array.length) {
|
||||||
System.err.println("\tat "+lockerStack[i].toString());
|
log.log(Level.WARNING, "TempVars has been requested {0} times, maybe you forgot to call release()?", instanceCount);
|
||||||
}
|
|
||||||
System.exit(1);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
lockerStack = new Throwable().getStackTrace();
|
|
||||||
locked = true;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public final boolean unlock(){
|
|
||||||
if (!locked){
|
|
||||||
System.err.println("INTERNAL ERROR");
|
|
||||||
System.err.println("Attempted to release non-existent lock: ");
|
|
||||||
|
|
||||||
StackTraceElement[] stack = new Throwable().getStackTrace();
|
|
||||||
for (int i = 1; i < stack.length; i++){
|
|
||||||
System.err.println("\tat "+stack[i].toString());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
System.exit(1);
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
return vars;
|
||||||
lockerStack = null;
|
|
||||||
locked = false;
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private TempVars() {
|
||||||
|
}
|
||||||
|
// private boolean locked = false;
|
||||||
|
// private StackTraceElement[] lockerStack;
|
||||||
|
|
||||||
|
// public final boolean lock() {
|
||||||
|
// if (locked) {
|
||||||
|
// System.err.println("INTERNAL ERROR");
|
||||||
|
// System.err.println("Offending trace: ");
|
||||||
|
//
|
||||||
|
// StackTraceElement[] stack = new Throwable().getStackTrace();
|
||||||
|
// for (int i = 1; i < stack.length; i++) {
|
||||||
|
// System.err.println("\tat " + stack[i].toString());
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// System.err.println("Attempted to aquire TempVars lock owned by");
|
||||||
|
// for (int i = 1; i < lockerStack.length; i++) {
|
||||||
|
// System.err.println("\tat " + lockerStack[i].toString());
|
||||||
|
// }
|
||||||
|
// System.exit(1);
|
||||||
|
// return false;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// lockerStack = new Throwable().getStackTrace();
|
||||||
|
// locked = true;
|
||||||
|
// return true;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// public final boolean unlock() {
|
||||||
|
// if (!locked) {
|
||||||
|
// System.err.println("INTERNAL ERROR");
|
||||||
|
// System.err.println("Attempted to release non-existent lock: ");
|
||||||
|
//
|
||||||
|
// StackTraceElement[] stack = new Throwable().getStackTrace();
|
||||||
|
// for (int i = 1; i < stack.length; i++) {
|
||||||
|
// System.err.println("\tat " + stack[i].toString());
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// System.exit(1);
|
||||||
|
// return false;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// lockerStack = null;
|
||||||
|
// locked = false;
|
||||||
|
// return true;
|
||||||
|
// }
|
||||||
|
/**
|
||||||
|
* Release this instance of TempVar, allowing it to be reused later.
|
||||||
|
*/
|
||||||
|
public final void release() {
|
||||||
|
|
||||||
|
//we only keep as much instances as we can,
|
||||||
|
//but if too much are instanced, we just don't readd them, they'll be garbage collected
|
||||||
|
//This can happen only in case of recursive calls that are instancing the TempVar
|
||||||
|
if (stackLevel < arraySize - 1) {
|
||||||
|
stackLevel++;
|
||||||
|
varsLocal.get()[stackLevel] = this;
|
||||||
|
}
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* For interfacing with OpenGL in Renderer.
|
* For interfacing with OpenGL in Renderer.
|
||||||
*/
|
*/
|
||||||
public final IntBuffer intBuffer1 = BufferUtils.createIntBuffer(1);
|
public final IntBuffer intBuffer1 = BufferUtils.createIntBuffer(1);
|
||||||
public final IntBuffer intBuffer16 = BufferUtils.createIntBuffer(16);
|
public final IntBuffer intBuffer16 = BufferUtils.createIntBuffer(16);
|
||||||
public final FloatBuffer floatBuffer16 = BufferUtils.createFloatBuffer(16);
|
public final FloatBuffer floatBuffer16 = BufferUtils.createFloatBuffer(16);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Skinning buffers
|
* Skinning buffers
|
||||||
*/
|
*/
|
||||||
public final float[] skinPositions = new float[512 * 3];
|
public final float[] skinPositions = new float[512 * 3];
|
||||||
public final float[] skinNormals = new float[512 * 3];
|
public final float[] skinNormals = new float[512 * 3];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fetching triangle from mesh
|
* Fetching triangle from mesh
|
||||||
*/
|
*/
|
||||||
public final Triangle triangle = new Triangle();
|
public final Triangle triangle = new Triangle();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* General vectors.
|
* General vectors.
|
||||||
*/
|
*/
|
||||||
@ -143,42 +196,36 @@ public class TempVars {
|
|||||||
public final Vector3f vect5 = new Vector3f();
|
public final Vector3f vect5 = new Vector3f();
|
||||||
public final Vector3f vect6 = new Vector3f();
|
public final Vector3f vect6 = new Vector3f();
|
||||||
public final Vector3f vect7 = new Vector3f();
|
public final Vector3f vect7 = new Vector3f();
|
||||||
|
//seems the maximum number of vector used is 7 in com.jme3.bounding.java
|
||||||
public final Vector3f vect8 = new Vector3f();
|
public final Vector3f vect8 = new Vector3f();
|
||||||
public final Vector3f vect9 = new Vector3f();
|
public final Vector3f vect9 = new Vector3f();
|
||||||
public final Vector3f vect10 = new Vector3f();
|
public final Vector3f vect10 = new Vector3f();
|
||||||
|
public final Vector3f[] tri = {new Vector3f(),
|
||||||
public final Vector3f[] tri = { new Vector3f(),
|
new Vector3f(),
|
||||||
new Vector3f(),
|
new Vector3f()};
|
||||||
new Vector3f() };
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 2D vector
|
* 2D vector
|
||||||
*/
|
*/
|
||||||
public final Vector2f vect2d = new Vector2f();
|
public final Vector2f vect2d = new Vector2f();
|
||||||
public final Vector2f vect2d2 = new Vector2f();
|
public final Vector2f vect2d2 = new Vector2f();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* General matrices.
|
* General matrices.
|
||||||
*/
|
*/
|
||||||
public final Matrix3f tempMat3 = new Matrix3f();
|
public final Matrix3f tempMat3 = new Matrix3f();
|
||||||
public final Matrix4f tempMat4 = new Matrix4f();
|
public final Matrix4f tempMat4 = new Matrix4f();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* General quaternions.
|
* General quaternions.
|
||||||
*/
|
*/
|
||||||
public final Quaternion quat1 = new Quaternion();
|
public final Quaternion quat1 = new Quaternion();
|
||||||
public final Quaternion quat2 = new Quaternion();
|
public final Quaternion quat2 = new Quaternion();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Eigen
|
* Eigen
|
||||||
*/
|
*/
|
||||||
public final Eigen3f eigen = new Eigen3f();
|
public final Eigen3f eigen = new Eigen3f();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Plane
|
* Plane
|
||||||
*/
|
*/
|
||||||
public final Plane plane = new Plane();
|
public final Plane plane = new Plane();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* BoundingBox ray collision
|
* BoundingBox ray collision
|
||||||
*/
|
*/
|
||||||
@ -187,18 +234,14 @@ public class TempVars {
|
|||||||
public final float[] fDdU = new float[3];
|
public final float[] fDdU = new float[3];
|
||||||
public final float[] fADdU = new float[3];
|
public final float[] fADdU = new float[3];
|
||||||
public final float[] fAWxDdU = new float[3];
|
public final float[] fAWxDdU = new float[3];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Maximum tree depth .. 32 levels??
|
* Maximum tree depth .. 32 levels??
|
||||||
*/
|
*/
|
||||||
public final Spatial[] spatialStack = new Spatial[32];
|
public final Spatial[] spatialStack = new Spatial[32];
|
||||||
|
|
||||||
public final float[] matrixWrite = new float[16];
|
public final float[] matrixWrite = new float[16];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* BIHTree
|
* BIHTree
|
||||||
*/
|
*/
|
||||||
public final float[] bihSwapTmp = new float[9];
|
public final float[] bihSwapTmp = new float[9];
|
||||||
public final ArrayList<BIHStackData> bihStack = new ArrayList<BIHStackData>();
|
public final ArrayList<BIHStackData> bihStack = new ArrayList<BIHStackData>();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -109,7 +109,6 @@ public class WaterFilter extends Filter {
|
|||||||
private boolean useCaustics = true;
|
private boolean useCaustics = true;
|
||||||
private boolean useRefraction = true;
|
private boolean useRefraction = true;
|
||||||
private float time = 0;
|
private float time = 0;
|
||||||
private float savedTpf = 0;
|
|
||||||
private float reflectionDisplace = 30;
|
private float reflectionDisplace = 30;
|
||||||
private float foamIntensity = 0.5f;
|
private float foamIntensity = 0.5f;
|
||||||
private boolean underWater;
|
private boolean underWater;
|
||||||
@ -168,7 +167,7 @@ public class WaterFilter extends Filter {
|
|||||||
sceneCam.getFrustumTop(),
|
sceneCam.getFrustumTop(),
|
||||||
sceneCam.getFrustumBottom());
|
sceneCam.getFrustumBottom());
|
||||||
TempVars vars = TempVars.get();
|
TempVars vars = TempVars.get();
|
||||||
assert vars.lock();
|
|
||||||
|
|
||||||
vars.vect1.set(sceneCam.getLocation()).addLocal(sceneCam.getUp());
|
vars.vect1.set(sceneCam.getLocation()).addLocal(sceneCam.getUp());
|
||||||
float planeDistance = plane.pseudoDistance(vars.vect1);
|
float planeDistance = plane.pseudoDistance(vars.vect1);
|
||||||
@ -176,8 +175,8 @@ public class WaterFilter extends Filter {
|
|||||||
vars.vect3.set(vars.vect1.subtractLocal(vars.vect2)).subtractLocal(loc).normalizeLocal().negateLocal();
|
vars.vect3.set(vars.vect1.subtractLocal(vars.vect2)).subtractLocal(loc).normalizeLocal().negateLocal();
|
||||||
|
|
||||||
reflectionCam.lookAt(targetLocation, vars.vect3);
|
reflectionCam.lookAt(targetLocation, vars.vect3);
|
||||||
|
vars.release();
|
||||||
|
|
||||||
assert vars.unlock();
|
|
||||||
if (inv) {
|
if (inv) {
|
||||||
reflectionCam.setAxes(reflectionCam.getLeft().negateLocal(), reflectionCam.getUp(), reflectionCam.getDirection().negateLocal());
|
reflectionCam.setAxes(reflectionCam.getLeft().negateLocal(), reflectionCam.getUp(), reflectionCam.getDirection().negateLocal());
|
||||||
}
|
}
|
||||||
|
@ -165,7 +165,7 @@ public class KinematicRagdollControl implements PhysicsControl, PhysicsCollision
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
TempVars vars = TempVars.get();
|
TempVars vars = TempVars.get();
|
||||||
assert vars.lock();
|
|
||||||
Quaternion tmpRot1 = vars.quat1;
|
Quaternion tmpRot1 = vars.quat1;
|
||||||
Quaternion tmpRot2 = vars.quat2;
|
Quaternion tmpRot2 = vars.quat2;
|
||||||
|
|
||||||
@ -264,7 +264,7 @@ public class KinematicRagdollControl implements PhysicsControl, PhysicsCollision
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
assert vars.unlock();
|
vars.release();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -682,7 +682,7 @@ public class KinematicRagdollControl implements PhysicsControl, PhysicsCollision
|
|||||||
|
|
||||||
baseRigidBody.setKinematic(mode == Mode.Kinetmatic);
|
baseRigidBody.setKinematic(mode == Mode.Kinetmatic);
|
||||||
TempVars vars = TempVars.get();
|
TempVars vars = TempVars.get();
|
||||||
assert vars.lock();
|
|
||||||
for (PhysicsBoneLink link : boneLinks.values()) {
|
for (PhysicsBoneLink link : boneLinks.values()) {
|
||||||
link.rigidBody.setKinematic(mode == Mode.Kinetmatic);
|
link.rigidBody.setKinematic(mode == Mode.Kinetmatic);
|
||||||
if (mode == Mode.Ragdoll) {
|
if (mode == Mode.Ragdoll) {
|
||||||
@ -693,7 +693,7 @@ public class KinematicRagdollControl implements PhysicsControl, PhysicsCollision
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
assert vars.unlock();
|
vars.release();
|
||||||
|
|
||||||
for (Bone bone : skeleton.getRoots()) {
|
for (Bone bone : skeleton.getRoots()) {
|
||||||
RagdollUtils.setUserControl(bone, mode == Mode.Ragdoll);
|
RagdollUtils.setUserControl(bone, mode == Mode.Ragdoll);
|
||||||
@ -716,9 +716,7 @@ public class KinematicRagdollControl implements PhysicsControl, PhysicsCollision
|
|||||||
animControl.setEnabled(true);
|
animControl.setEnabled(true);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
TempVars vars = TempVars.get();
|
TempVars vars = TempVars.get();
|
||||||
assert vars.lock();
|
|
||||||
for (PhysicsBoneLink link : boneLinks.values()) {
|
for (PhysicsBoneLink link : boneLinks.values()) {
|
||||||
|
|
||||||
Vector3f p = link.rigidBody.getMotionState().getWorldLocation();
|
Vector3f p = link.rigidBody.getMotionState().getWorldLocation();
|
||||||
@ -737,7 +735,7 @@ public class KinematicRagdollControl implements PhysicsControl, PhysicsCollision
|
|||||||
link.startBlendingRot.set(q2);
|
link.startBlendingRot.set(q2);
|
||||||
link.rigidBody.setKinematic(true);
|
link.rigidBody.setKinematic(true);
|
||||||
}
|
}
|
||||||
assert vars.unlock();
|
vars.release();
|
||||||
|
|
||||||
for (Bone bone : skeleton.getRoots()) {
|
for (Bone bone : skeleton.getRoots()) {
|
||||||
RagdollUtils.setUserControl(bone, false);
|
RagdollUtils.setUserControl(bone, false);
|
||||||
|
@ -90,14 +90,14 @@ public class DebugShapeFactory {
|
|||||||
|
|
||||||
// apply rotation
|
// apply rotation
|
||||||
TempVars vars = TempVars.get();
|
TempVars vars = TempVars.get();
|
||||||
assert vars.lock();
|
|
||||||
Matrix3f tempRot = vars.tempMat3;
|
Matrix3f tempRot = vars.tempMat3;
|
||||||
|
|
||||||
tempRot.set(geometry.getLocalRotation());
|
tempRot.set(geometry.getLocalRotation());
|
||||||
childCollisionShape.rotation.mult(tempRot, tempRot);
|
childCollisionShape.rotation.mult(tempRot, tempRot);
|
||||||
geometry.setLocalRotation(tempRot);
|
geometry.setLocalRotation(tempRot);
|
||||||
|
|
||||||
assert vars.unlock();
|
vars.release();
|
||||||
|
|
||||||
node.attachChild(geometry);
|
node.attachChild(geometry);
|
||||||
}
|
}
|
||||||
@ -120,17 +120,15 @@ public class DebugShapeFactory {
|
|||||||
return geom;
|
return geom;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Mesh getDebugMesh(CollisionShape shape){
|
public static Mesh getDebugMesh(CollisionShape shape) {
|
||||||
Mesh mesh=null;
|
Mesh mesh = null;
|
||||||
if(shape.getCShape() instanceof ConvexShape){
|
if (shape.getCShape() instanceof ConvexShape) {
|
||||||
mesh=new Mesh();
|
mesh = new Mesh();
|
||||||
mesh.setBuffer(Type.Position, 3, getVertices((ConvexShape)shape.getCShape()));
|
mesh.setBuffer(Type.Position, 3, getVertices((ConvexShape) shape.getCShape()));
|
||||||
mesh.getFloatBuffer(Type.Position).clear();
|
mesh.getFloatBuffer(Type.Position).clear();
|
||||||
}
|
} else if (shape.getCShape() instanceof ConcaveShape) {
|
||||||
else if(shape.getCShape() instanceof ConcaveShape)
|
mesh = new Mesh();
|
||||||
{
|
mesh.setBuffer(Type.Position, 3, getVertices((ConcaveShape) shape.getCShape()));
|
||||||
mesh=new Mesh();
|
|
||||||
mesh.setBuffer(Type.Position, 3, getVertices((ConcaveShape)shape.getCShape()));
|
|
||||||
mesh.getFloatBuffer(Type.Position).clear();
|
mesh.getFloatBuffer(Type.Position).clear();
|
||||||
}
|
}
|
||||||
return mesh;
|
return mesh;
|
||||||
|
@ -29,51 +29,82 @@
|
|||||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package jme3test.app;
|
package jme3test.app;
|
||||||
|
|
||||||
import com.jme3.util.TempVars;
|
import com.jme3.util.TempVars;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.Iterator;
|
||||||
|
|
||||||
public class TestTempVars {
|
public class TestTempVars {
|
||||||
|
|
||||||
public static void methodThatUsesTempVars(){
|
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
|
||||||
|
Date d,d2;
|
||||||
|
System.err.println("NOTE: This test simulates a data corruption attempt\n"
|
||||||
|
+ " in the engine. If assertions are enabled (-ea VM flag), the \n"
|
||||||
|
+ "data corruption will be detected and displayed below.");
|
||||||
|
|
||||||
|
//get the vars
|
||||||
TempVars vars = TempVars.get();
|
TempVars vars = TempVars.get();
|
||||||
|
|
||||||
assert vars.lock();
|
// do something with temporary vars
|
||||||
{
|
vars.vect1.addLocal(vars.vect2);
|
||||||
vars.vect1.set(123,999,-55);
|
|
||||||
}
|
|
||||||
assert vars.unlock();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void main(String[] args){
|
//release the vars
|
||||||
System.err.println("NOTE: This test simulates a data corruption attempt\n" +
|
vars.release();
|
||||||
" in the engine. If assertions are enabled (-ea VM flag), the \n" +
|
|
||||||
"data corruption will be detected and displayed below.");
|
|
||||||
|
|
||||||
TempVars vars = TempVars.get();
|
//Perf tests
|
||||||
|
|
||||||
assert vars.lock();
|
//100 million calls
|
||||||
{
|
d = new Date();
|
||||||
// do something with temporary vars
|
for (int i = 0; i < 100000000; i++) {
|
||||||
vars.vect1.addLocal(vars.vect2);
|
|
||||||
}
|
|
||||||
assert vars.unlock();
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
assert vars.lock();
|
|
||||||
{
|
|
||||||
// set a value
|
|
||||||
vars.vect1.set(1,1,1);
|
|
||||||
|
|
||||||
// method that currupts the value
|
|
||||||
methodThatUsesTempVars();
|
methodThatUsesTempVars();
|
||||||
|
|
||||||
// read the value
|
|
||||||
System.out.println(vars.vect1);
|
|
||||||
}
|
}
|
||||||
assert vars.unlock();
|
d2 = new Date();
|
||||||
|
System.out.println("100 million calls : " +(d2.getTime() - d.getTime())+" ms");
|
||||||
|
|
||||||
|
|
||||||
|
//recursive Method
|
||||||
|
d = new Date();
|
||||||
|
recursiveMethod();
|
||||||
|
d2 = new Date();
|
||||||
|
System.out.println("100 recursive calls : " +(d2.getTime() - d.getTime())+" ms");
|
||||||
|
|
||||||
|
d = new Date();
|
||||||
|
for (int i = 0; i < 1000000; i++) {
|
||||||
|
methodThatUsesTempVarsWithNoRelease();
|
||||||
|
}
|
||||||
|
d2 = new Date();
|
||||||
|
System.out.println("1 million calls with no release : " +(d2.getTime() - d.getTime())+" ms");
|
||||||
|
|
||||||
|
}
|
||||||
|
static int recurse = 0;
|
||||||
|
public static void recursiveMethod(){
|
||||||
|
TempVars vars = TempVars.get();
|
||||||
|
vars.vect1.set(123, 999, -55);
|
||||||
|
recurse++;
|
||||||
|
if(recurse<100){
|
||||||
|
recursiveMethod();
|
||||||
|
}
|
||||||
|
|
||||||
|
vars.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void methodThatUsesTempVars() {
|
||||||
|
TempVars vars = TempVars.get();
|
||||||
|
{
|
||||||
|
vars.vect1.set(123, 999, -55);
|
||||||
|
}
|
||||||
|
vars.release();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void methodThatUsesTempVarsWithNoRelease() {
|
||||||
|
TempVars vars = TempVars.get();
|
||||||
|
{
|
||||||
|
vars.vect1.set(123, 999, -55);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user