use of com.jme3.scene.plugins.blender.meshes.Point in project jmonkeyengine by jMonkeyEngine.
the class PQTorus method updateGeometry.
/**
* Rebuilds this torus based on a new set of parameters.
*
* @param p the x/z oscillation.
* @param q the y oscillation.
* @param radius the radius of the PQTorus.
* @param width the width of the torus.
* @param steps the steps along the torus.
* @param radialSamples radial samples for the torus.
*/
public void updateGeometry(float p, float q, float radius, float width, int steps, int radialSamples) {
this.p = p;
this.q = q;
this.radius = radius;
this.width = width;
this.steps = steps;
this.radialSamples = radialSamples;
final float thetaStep = (FastMath.TWO_PI / steps);
final float betaStep = (FastMath.TWO_PI / radialSamples);
Vector3f[] torusPoints = new Vector3f[steps];
// Allocate all of the required buffers
int vertCount = radialSamples * steps;
FloatBuffer fpb = createVector3Buffer(vertCount);
FloatBuffer fnb = createVector3Buffer(vertCount);
FloatBuffer ftb = createVector2Buffer(vertCount);
Vector3f pointB, T, N, B;
Vector3f tempNorm = new Vector3f();
float r, x, y, z, theta = 0.0f, beta;
int nvertex = 0;
// Move along the length of the pq torus
for (int i = 0; i < steps; i++) {
theta += thetaStep;
float circleFraction = ((float) i) / (float) steps;
// Find the point on the torus
r = (0.5f * (2.0f + FastMath.sin(q * theta)) * radius);
x = (r * FastMath.cos(p * theta) * radius);
y = (r * FastMath.sin(p * theta) * radius);
z = (r * FastMath.cos(q * theta) * radius);
torusPoints[i] = new Vector3f(x, y, z);
// Now find a point slightly farther along the torus
r = (0.5f * (2.0f + FastMath.sin(q * (theta + 0.01f))) * radius);
x = (r * FastMath.cos(p * (theta + 0.01f)) * radius);
y = (r * FastMath.sin(p * (theta + 0.01f)) * radius);
z = (r * FastMath.cos(q * (theta + 0.01f)) * radius);
pointB = new Vector3f(x, y, z);
// Approximate the Frenet Frame
T = pointB.subtract(torusPoints[i]);
N = torusPoints[i].add(pointB);
B = T.cross(N);
N = B.cross(T);
// Normalise the two vectors and then use them to create an oriented circle
N = N.normalize();
B = B.normalize();
beta = 0.0f;
for (int j = 0; j < radialSamples; j++, nvertex++) {
beta += betaStep;
float cx = FastMath.cos(beta) * width;
float cy = FastMath.sin(beta) * width;
float radialFraction = ((float) j) / radialSamples;
tempNorm.x = (cx * N.x + cy * B.x);
tempNorm.y = (cx * N.y + cy * B.y);
tempNorm.z = (cx * N.z + cy * B.z);
fnb.put(tempNorm.x).put(tempNorm.y).put(tempNorm.z);
tempNorm.addLocal(torusPoints[i]);
fpb.put(tempNorm.x).put(tempNorm.y).put(tempNorm.z);
ftb.put(radialFraction).put(circleFraction);
}
}
// Update the indices data
ShortBuffer sib = createShortBuffer(6 * vertCount);
for (int i = 0; i < vertCount; i++) {
sib.put(new short[] { (short) (i), (short) (i - radialSamples), (short) (i + 1), (short) (i + 1), (short) (i - radialSamples), (short) (i - radialSamples + 1) });
}
for (int i = 0, len = sib.capacity(); i < len; i++) {
int ind = sib.get(i);
if (ind < 0) {
ind += vertCount;
sib.put(i, (short) ind);
} else if (ind >= vertCount) {
ind -= vertCount;
sib.put(i, (short) ind);
}
}
sib.rewind();
setBuffer(Type.Position, 3, fpb);
setBuffer(Type.Normal, 3, fnb);
setBuffer(Type.TexCoord, 2, ftb);
setBuffer(Type.Index, 3, sib);
}
use of com.jme3.scene.plugins.blender.meshes.Point in project jmonkeyengine by jMonkeyEngine.
the class LightFilterTest method testPointFiltering.
@Test
public void testPointFiltering() {
PointLight pl = new PointLight(Vector3f.ZERO);
geom.addLight(pl);
// Infinite point lights must never be filtered
checkFilteredLights(1);
// Light at origin does not intersect geom which is at Z=10
pl.setRadius(1);
checkFilteredLights(0);
// Put it closer to geom, the very edge of the sphere touches the box.
// Still not considered an intersection though.
pl.setPosition(new Vector3f(0, 0, 8f));
checkFilteredLights(0);
// And more close - now its an intersection.
pl.setPosition(new Vector3f(0, 0, 8f + FastMath.ZERO_TOLERANCE));
checkFilteredLights(1);
// Move the geometry away
geom.move(0, 0, FastMath.ZERO_TOLERANCE);
checkFilteredLights(0);
// Test if the algorithm converts the sphere
// to a box before testing the collision (incorrect)
float sqrt3 = FastMath.sqrt(3);
pl.setPosition(new Vector3f(2, 2, 8));
pl.setRadius(sqrt3);
checkFilteredLights(0);
// Make it a wee bit larger.
pl.setRadius(sqrt3 + FastMath.ZERO_TOLERANCE);
checkFilteredLights(1);
// Rotate the camera so it is up, light is outside frustum.
cam.lookAtDirection(Vector3f.UNIT_Y, Vector3f.UNIT_Y);
checkFilteredLights(0);
// ==================================
// Tests for bounding Sphere
geom.setModelBound(new BoundingSphere(1f, Vector3f.ZERO));
geom.setLocalTranslation(0, 0, 2);
pl.setPosition(new Vector3f(0, 0, 2f));
// Infinite point lights must never be filtered
pl.setRadius(0);
checkFilteredLights(1);
pl.setRadius(1f);
// Put the light at the very close to the geom,
// the very edge of the sphere touches the other bounding sphere
// Still not considered an intersection though.
pl.setPosition(new Vector3f(0, 0, 0));
checkFilteredLights(0);
// And more close - now its an intersection.
pl.setPosition(new Vector3f(0, 0, 0f + FastMath.ZERO_TOLERANCE));
checkFilteredLights(1);
geom.setLocalTranslation(0, 0, 0);
// In this case its an intersection for pointLight v. box
// But not for pointLight v. sphere
// Vector3f(0, 0.5f, 0.5f).normalize().mult(2) ~ >= (0.0, 1.4142135, 1.4142135)
//pl.setPosition(new Vector3f(0, 0.5f, 0.5f).normalizeLocal().multLocal(2 + FastMath.ZERO_TOLERANCE));
pl.setPosition(new Vector3f(0f, 1.4142135f, 1.4142135f).multLocal(1 + FastMath.ZERO_TOLERANCE));
checkFilteredLights(0);
// Make the distance a wee bit closer, now its an intersection
//pl.setPosition(new Vector3f(0, 0.5f, 0.5f).normalizeLocal().multLocal(2 - FastMath.ZERO_TOLERANCE));
pl.setPosition(new Vector3f(0f, 1.4142135f, 1.4142135f).multLocal(1 - FastMath.ZERO_TOLERANCE));
checkFilteredLights(1);
// it's a point light, also test for the other corner
pl.setPosition(new Vector3f(0f, -1.4142135f, -1.4142135f).multLocal(1 - FastMath.ZERO_TOLERANCE));
checkFilteredLights(0);
}
use of com.jme3.scene.plugins.blender.meshes.Point in project jmonkeyengine by jMonkeyEngine.
the class LightSortTest method testSimpleSort.
@Test
public void testSimpleSort() {
Geometry g = new Geometry("test", new Mesh());
LightList list = new LightList(g);
list.add(new SpotLight(Vector3f.ZERO, Vector3f.UNIT_X));
list.add(new PointLight(Vector3f.UNIT_X));
list.add(new DirectionalLight(Vector3f.UNIT_X));
list.add(new AmbientLight());
list.sort(true);
// Ambients always first
assert list.get(0) instanceof AmbientLight;
// .. then directionals
assert list.get(1) instanceof DirectionalLight;
// Spot is 0 units away from geom
assert list.get(2) instanceof SpotLight;
// .. and point is 1 unit away.
assert list.get(3) instanceof PointLight;
}
use of com.jme3.scene.plugins.blender.meshes.Point in project jmonkeyengine by jMonkeyEngine.
the class TestRayCollision method main.
public static void main(String[] args) {
Ray r = new Ray(Vector3f.ZERO, Vector3f.UNIT_X);
BoundingBox bbox = new BoundingBox(new Vector3f(5, 0, 0), 1, 1, 1);
CollisionResults res = new CollisionResults();
bbox.collideWith(r, res);
System.out.println("Bounding:" + bbox);
System.out.println("Ray: " + r);
System.out.println("Num collisions: " + res.size());
for (int i = 0; i < res.size(); i++) {
System.out.println("--- Collision #" + i + " ---");
float dist = res.getCollision(i).getDistance();
Vector3f pt = res.getCollision(i).getContactPoint();
System.out.println("distance: " + dist);
System.out.println("point: " + pt);
}
}
use of com.jme3.scene.plugins.blender.meshes.Point in project jmonkeyengine by jMonkeyEngine.
the class BoneEnvelope method isInEnvelope.
/**
* The method verifies if the given point is inside the envelope.
* @param point
* the point in 3D space (MUST be in a world coordinate space)
* @return <b>true</b> if the point is inside the envelope and <b>false</b> otherwise
*/
public boolean isInEnvelope(Vector3f point) {
Vector3f v = tail.subtract(head);
float boneLength = v.length();
v.normalizeLocal();
// computing a plane that contains 'point' and v is its normal vector
// the plane's equation is: Ax + By + Cz + D = 0, where v = [A, B, C]
float D = -v.dot(point);
// computing a point where a line that contains head and tail crosses the plane
float temp = -(v.dot(head) + D) / v.dot(v);
Vector3f p = head.add(v.x * temp, v.y * temp, v.z * temp);
// determining if the point p is on the same or other side of head than the tail point
Vector3f headToPointOnLineVector = p.subtract(head);
float headToPointLength = headToPointOnLineVector.length();
// the length of v is already = 1; cosinus should be either 1, 0 or -1
float cosinus = headToPointOnLineVector.dot(v) / headToPointLength;
if (cosinus < 0 && headToPointLength > boneHeadRadius || headToPointLength > boneLength + boneTailRadius) {
// the point is outside the anvelope
return false;
}
// now check if the point is inside and envelope
float pointDistanceFromLine = point.subtract(p).length(), maximumDistance = 0;
if (cosinus < 0) {
// checking if the distance from p to point is inside the half sphere defined by head envelope
// compute the distance from the line to the half sphere border
maximumDistance = boneHeadRadius;
} else if (headToPointLength < boneLength) {
// compute the maximum available distance
if (boneTailRadius > boneHeadRadius) {
// compute the distance from head to p
float headToPDistance = p.subtract(head).length();
// from tangens function we have
float x = headToPDistance * ((boneTailRadius - boneHeadRadius) / boneLength);
maximumDistance = x + boneHeadRadius;
} else if (boneTailRadius < boneHeadRadius) {
// compute the distance from head to p
float tailToPDistance = p.subtract(tail).length();
// from tangens function we have
float x = tailToPDistance * ((boneHeadRadius - boneTailRadius) / boneLength);
maximumDistance = x + boneTailRadius;
} else {
maximumDistance = boneTailRadius;
}
} else {
// checking if the distance from p to point is inside the half sphere defined by tail envelope
maximumDistance = boneTailRadius;
}
return pointDistanceFromLine <= maximumDistance + distance;
}
Aggregations