use of com.jme3.bounding.BoundingSphere in project jmonkeyengine by jMonkeyEngine.
the class LightFilterTest method testSpotFiltering.
@Test
public void testSpotFiltering() {
SpotLight sl = new SpotLight(Vector3f.ZERO, Vector3f.UNIT_Z);
sl.setSpotRange(0);
geom.addLight(sl);
// Infinite spot lights are only filtered
checkFilteredLights(1);
// if the geometry is outside the infinite cone.
TempVars vars = TempVars.get();
try {
// The spot is not touching the near plane of the camera yet,
// should still be culled.
sl.setSpotRange(1f - FastMath.ZERO_TOLERANCE);
assert !sl.intersectsFrustum(cam, vars);
// should be culled from the geometry's PoV
checkFilteredLights(0);
// Now it touches the near plane.
sl.setSpotRange(1f);
// still culled from the geometry's PoV
checkFilteredLights(0);
assert sl.intersectsFrustum(cam, vars);
} finally {
vars.release();
}
// make it barely reach the geometry
sl.setSpotRange(9f);
checkFilteredLights(0);
// make it reach the geometry (touching its bound)
sl.setSpotRange(9f + FastMath.ZERO_TOLERANCE);
checkFilteredLights(1);
// rotate the cone a bit so it no longer faces the geom
sl.setDirection(new Vector3f(0.316f, 0, 0.948f).normalizeLocal());
checkFilteredLights(0);
// extent the range much farther
sl.setSpotRange(20);
checkFilteredLights(0);
// Create box of size X=10 (double the extent)
// now, the spot will touch the box.
geom.setMesh(new Box(5, 1, 1));
checkFilteredLights(1);
// ==================================
// Tests for bounding sphere, with a radius of 1f (in the box geom)
sl.setPosition(Vector3f.ZERO);
sl.setDirection(Vector3f.UNIT_Z);
geom.setLocalTranslation(Vector3f.ZERO);
geom.setModelBound(new BoundingSphere(1f, Vector3f.ZERO));
// Infinit spot lights are only filtered
// if the geometry is outside the infinite cone.
sl.setSpotRange(0);
checkFilteredLights(1);
//the geommetry is outside the infinit cone (cone direction going away from the geom)
sl.setPosition(Vector3f.UNIT_Z.mult(1 + FastMath.ZERO_TOLERANCE));
checkFilteredLights(0);
//place the spote ligth in the corner of the box geom, (in order to test bounding sphere)
sl.setDirection(new Vector3f(1, 1, 0).normalizeLocal());
geom.setLocalTranslation(0, 0, 10);
sl.setPosition(sl.getDirection().mult(-2f).add(geom.getLocalTranslation()));
// make it barely reach the sphere, incorect with a box
sl.setSpotRange(1f - FastMath.ZERO_TOLERANCE);
checkFilteredLights(0);
// make it reach the sphere
sl.setSpotRange(1f + FastMath.ZERO_TOLERANCE);
checkFilteredLights(1);
// extent the range
sl.setPosition(Vector3f.ZERO);
sl.setDirection(Vector3f.UNIT_Z);
sl.setSpotRange(20);
checkFilteredLights(1);
// rotate the cone a bit so it no longer faces the geom
sl.setDirection(new Vector3f(0, 0.3f, 0.7f).normalizeLocal());
checkFilteredLights(0);
// Create sphere of size X=10 (double the radius)
// now, the spot will touch the sphere.
geom.setModelBound(new BoundingSphere(5f, Vector3f.ZERO));
checkFilteredLights(1);
}
use of com.jme3.bounding.BoundingSphere in project jmonkeyengine by jMonkeyEngine.
the class LightFilterTest method testDirectionalFiltering.
@Test
public void testDirectionalFiltering() {
geom.addLight(new DirectionalLight(Vector3f.UNIT_Y));
// Directional lights must never be filtered
checkFilteredLights(1);
// Test for bounding Sphere
geom.setModelBound(new BoundingSphere(0.5f, Vector3f.ZERO));
// Directional lights must never be filtered
checkFilteredLights(1);
}
use of com.jme3.bounding.BoundingSphere in project jmonkeyengine by jMonkeyEngine.
the class ArrayModifier method apply.
@Override
public void apply(Node node, BlenderContext blenderContext) {
if (invalid) {
LOGGER.log(Level.WARNING, "Array modifier is invalid! Cannot be applied to: {0}", node.getName());
} else {
TemporalMesh temporalMesh = this.getTemporalMesh(node);
if (temporalMesh != null) {
LOGGER.log(Level.FINE, "Applying array modifier to: {0}", temporalMesh);
if (offset == null) {
// the node will be repeated several times in the same place
offset = new float[] { 0.0f, 0.0f, 0.0f };
}
if (scale == null) {
// the node will be repeated several times in the same place
scale = new float[] { 0.0f, 0.0f, 0.0f };
} else {
// getting bounding box
temporalMesh.updateModelBound();
BoundingVolume boundingVolume = temporalMesh.getWorldBound();
if (boundingVolume instanceof BoundingBox) {
scale[0] *= ((BoundingBox) boundingVolume).getXExtent() * 2.0f;
scale[1] *= ((BoundingBox) boundingVolume).getYExtent() * 2.0f;
scale[2] *= ((BoundingBox) boundingVolume).getZExtent() * 2.0f;
} else if (boundingVolume instanceof BoundingSphere) {
float radius = ((BoundingSphere) boundingVolume).getRadius();
scale[0] *= radius * 2.0f;
scale[1] *= radius * 2.0f;
scale[2] *= radius * 2.0f;
} else {
throw new IllegalStateException("Unknown bounding volume type: " + boundingVolume.getClass().getName());
}
}
// adding object's offset
float[] objectOffset = new float[] { 0.0f, 0.0f, 0.0f };
if (pOffsetObject != null && pOffsetObject.isNotNull()) {
FileBlockHeader offsetObjectBlock = blenderContext.getFileBlock(pOffsetObject.getOldMemoryAddress());
ObjectHelper objectHelper = blenderContext.getHelper(ObjectHelper.class);
try {
// we take the structure in case the object was not yet loaded
Structure offsetStructure = offsetObjectBlock.getStructure(blenderContext);
Vector3f translation = objectHelper.getTransformation(offsetStructure, blenderContext).getTranslation();
objectOffset[0] = translation.x;
objectOffset[1] = translation.y;
objectOffset[2] = translation.z;
} catch (BlenderFileException e) {
LOGGER.log(Level.WARNING, "Problems in blender file structure! Object offset cannot be applied! The problem: {0}", e.getMessage());
}
}
// getting start and end caps
MeshHelper meshHelper = blenderContext.getHelper(MeshHelper.class);
TemporalMesh[] caps = new TemporalMesh[] { null, null };
Pointer[] pCaps = new Pointer[] { pStartCap, pEndCap };
for (int i = 0; i < pCaps.length; ++i) {
if (pCaps[i].isNotNull()) {
FileBlockHeader capBlock = blenderContext.getFileBlock(pCaps[i].getOldMemoryAddress());
try {
// we take the structure in case the object was not yet loaded
Structure capStructure = capBlock.getStructure(blenderContext);
Pointer pMesh = (Pointer) capStructure.getFieldValue("data");
List<Structure> meshesArray = pMesh.fetchData();
caps[i] = meshHelper.toTemporalMesh(meshesArray.get(0), blenderContext);
} catch (BlenderFileException e) {
LOGGER.log(Level.WARNING, "Problems in blender file structure! Cap object cannot be applied! The problem: {0}", e.getMessage());
}
}
}
Vector3f translationVector = new Vector3f(offset[0] + scale[0] + objectOffset[0], offset[1] + scale[1] + objectOffset[1], offset[2] + scale[2] + objectOffset[2]);
if (blenderContext.getBlenderKey().isFixUpAxis()) {
float y = translationVector.y;
translationVector.y = translationVector.z;
translationVector.z = y == 0 ? 0 : -y;
}
// getting/calculating repeats amount
int count = 0;
if (fittype == 0) {
// Fixed count
count = this.count - 1;
} else if (fittype == 1) {
// Fixed length
float length = this.length;
if (translationVector.length() > 0.0f) {
count = (int) (length / translationVector.length()) - 1;
}
} else if (fittype == 2) {
// Fit curve
throw new IllegalStateException("Fit curve should be transformed to Fixed Length array type!");
} else {
throw new IllegalStateException("Unknown fit type: " + fittype);
}
// adding translated nodes and caps
Vector3f totalTranslation = new Vector3f(translationVector);
if (count > 0) {
TemporalMesh originalMesh = temporalMesh.clone();
for (int i = 0; i < count; ++i) {
TemporalMesh clone = originalMesh.clone();
for (Vector3f v : clone.getVertices()) {
v.addLocal(totalTranslation);
}
temporalMesh.append(clone);
totalTranslation.addLocal(translationVector);
}
}
if (caps[0] != null) {
translationVector.multLocal(-1);
TemporalMesh capsClone = caps[0].clone();
for (Vector3f v : capsClone.getVertices()) {
v.addLocal(translationVector);
}
temporalMesh.append(capsClone);
}
if (caps[1] != null) {
TemporalMesh capsClone = caps[1].clone();
for (Vector3f v : capsClone.getVertices()) {
v.addLocal(totalTranslation);
}
temporalMesh.append(capsClone);
}
} else {
LOGGER.log(Level.WARNING, "Cannot find temporal mesh for node: {0}. The modifier will NOT be applied!", node);
}
}
}
use of com.jme3.bounding.BoundingSphere in project jmonkeyengine by jMonkeyEngine.
the class UVCoordinatesGenerator method getBoundingSphere.
/**
* This method returns the bounding sphere of the given geometries.
*
* @param geometries
* the list of geometries
* @return bounding sphere of the given geometries
*/
/* package */
static BoundingSphere getBoundingSphere(Geometry... geometries) {
BoundingSphere result = null;
for (Geometry geometry : geometries) {
geometry.updateModelBound();
BoundingVolume bv = geometry.getModelBound();
if (bv instanceof BoundingBox) {
BoundingBox bb = (BoundingBox) bv;
float r = Math.max(bb.getXExtent(), bb.getYExtent());
r = Math.max(r, bb.getZExtent());
return new BoundingSphere(r, bb.getCenter());
} else if (bv instanceof BoundingSphere) {
return (BoundingSphere) bv;
} else {
throw new IllegalStateException("Unknown bounding volume type: " + bv.getClass().getName());
}
}
return result;
}
use of com.jme3.bounding.BoundingSphere in project jmonkeyengine by jMonkeyEngine.
the class UVCoordinatesGenerator method getBoundingBox.
/**
* This method returns the bounding box of the given geometries.
*
* @param geometries
* the list of geometries
* @return bounding box of the given geometries
*/
public static BoundingBox getBoundingBox(Geometry... geometries) {
BoundingBox result = null;
for (Geometry geometry : geometries) {
geometry.updateModelBound();
BoundingVolume bv = geometry.getModelBound();
if (bv instanceof BoundingBox) {
return (BoundingBox) bv;
} else if (bv instanceof BoundingSphere) {
BoundingSphere bs = (BoundingSphere) bv;
float r = bs.getRadius();
return new BoundingBox(bs.getCenter(), r, r, r);
} else {
throw new IllegalStateException("Unknown bounding volume type: " + bv.getClass().getName());
}
}
return result;
}
Aggregations