use of com.jme3.bounding.BoundingSphere in project jmonkeyengine by jMonkeyEngine.
the class SkyFactory method createSky.
/**
* Create a sky using the given cubemap or spheremap texture.
*
* @param assetManager from which to load materials
* @param texture to use
* @param normalScale The normal scale is multiplied by the 3D normal to get
* a texture coordinate. Use Vector3f.UNIT_XYZ to not apply and
* transformation to the normal.
* @param envMapType see {@link EnvMapType}
* @param sphereRadius the sky sphere's radius: for the sky to be visible,
* its radius must fall between the near and far planes of the camera's
* frustrum
* @return a new spatial representing the sky, ready to be attached to the
* scene graph
*/
public static Spatial createSky(AssetManager assetManager, Texture texture, Vector3f normalScale, EnvMapType envMapType, float sphereRadius) {
if (texture == null) {
throw new IllegalArgumentException("texture cannot be null");
}
final Sphere sphereMesh = new Sphere(10, 10, sphereRadius, false, true);
Geometry sky = new Geometry("Sky", sphereMesh);
sky.setQueueBucket(Bucket.Sky);
sky.setCullHint(Spatial.CullHint.Never);
sky.setModelBound(new BoundingSphere(Float.POSITIVE_INFINITY, Vector3f.ZERO));
Material skyMat = new Material(assetManager, "Common/MatDefs/Misc/Sky.j3md");
skyMat.setVector3("NormalScale", normalScale);
switch(envMapType) {
case CubeMap:
// make sure its a cubemap
if (!(texture instanceof TextureCubeMap)) {
Image img = texture.getImage();
texture = new TextureCubeMap();
texture.setImage(img);
}
break;
case SphereMap:
skyMat.setBoolean("SphereMap", true);
break;
case EquirectMap:
skyMat.setBoolean("EquirectMap", true);
break;
}
texture.setMagFilter(Texture.MagFilter.Bilinear);
texture.setMinFilter(Texture.MinFilter.BilinearNoMipMaps);
texture.setAnisotropicFilter(0);
texture.setWrap(Texture.WrapMode.EdgeClamp);
skyMat.setTexture("Texture", texture);
sky.setMaterial(skyMat);
return sky;
}
use of com.jme3.bounding.BoundingSphere in project jmonkeyengine by jMonkeyEngine.
the class UVCoordinatesGenerator method generateUVCoordinatesFor2DTexture.
/**
* Generates a UV coordinates for 2D texture.
*
* @param mesh
* the mesh we generate UV's for
* @param texco
* UV coordinates type
* @param projection
* projection type
* @param geometries
* the geometris the given mesh belongs to (required to compute
* bounding box)
* @return UV coordinates for the given mesh
*/
public static List<Vector2f> generateUVCoordinatesFor2DTexture(Mesh mesh, UVCoordinatesType texco, UVProjectionType projection, Geometry geometries) {
List<Vector2f> result = new ArrayList<Vector2f>();
BoundingBox bb = UVCoordinatesGenerator.getBoundingBox(geometries);
// positions, normals, reflection vectors, etc.
float[] inputData = null;
switch(texco) {
case TEXCO_ORCO:
inputData = BufferUtils.getFloatArray(mesh.getFloatBuffer(VertexBuffer.Type.Position));
break;
case // this should be used if not defined by user explicitly
TEXCO_UV:
Vector2f[] data = new Vector2f[] { new Vector2f(0, 1), new Vector2f(0, 0), new Vector2f(1, 0) };
for (int i = 0; i < mesh.getVertexCount(); ++i) {
result.add(data[i % 3]);
}
break;
case TEXCO_NORM:
inputData = BufferUtils.getFloatArray(mesh.getFloatBuffer(VertexBuffer.Type.Normal));
break;
case TEXCO_REFL:
case TEXCO_GLOB:
case TEXCO_TANGENT:
case TEXCO_STRESS:
case TEXCO_LAVECTOR:
case TEXCO_OBJECT:
case TEXCO_OSA:
case TEXCO_PARTICLE_OR_STRAND:
case TEXCO_SPEED:
case TEXCO_STICKY:
case TEXCO_VIEW:
case TEXCO_WINDOW:
LOGGER.warning("Texture coordinates type not currently supported: " + texco);
break;
default:
throw new IllegalStateException("Unknown texture coordinates value: " + texco);
}
if (inputData != null) {
// make projection calculations
switch(projection) {
case PROJECTION_FLAT:
inputData = UVProjectionGenerator.flatProjection(inputData, bb);
break;
case PROJECTION_CUBE:
inputData = UVProjectionGenerator.cubeProjection(inputData, bb);
break;
case PROJECTION_TUBE:
BoundingTube bt = UVCoordinatesGenerator.getBoundingTube(geometries);
inputData = UVProjectionGenerator.tubeProjection(inputData, bt);
break;
case PROJECTION_SPHERE:
BoundingSphere bs = UVCoordinatesGenerator.getBoundingSphere(geometries);
inputData = UVProjectionGenerator.sphereProjection(inputData, bs);
break;
default:
throw new IllegalStateException("Unknown projection type: " + projection);
}
for (int i = 0; i < inputData.length; i += 2) {
result.add(new Vector2f(inputData[i], inputData[i + 1]));
}
}
return result;
}
use of com.jme3.bounding.BoundingSphere in project jmonkeyengine by jMonkeyEngine.
the class UVProjectionGenerator method sphereProjection.
/**
* Sphere projection for 2D textures.
*
* @param positions
* points to be projected
* @param bb
* the bounding box for projecting
* @return UV coordinates after the projection
*/
public static float[] sphereProjection(float[] positions, BoundingSphere bs) {
// TODO: rotate it to be vertical
float[] uvCoordinates = new float[positions.length / 3 * 2];
Vector3f v = new Vector3f();
float cx = bs.getCenter().x, cy = bs.getCenter().y, cz = bs.getCenter().z;
Vector3f uBase = new Vector3f(0, -1, 0);
Vector3f vBase = new Vector3f(0, 0, -1);
for (int i = 0, j = 0; i < positions.length; i += 3, j += 2) {
// calculating U
v.set(positions[i] - cx, positions[i + 1] - cy, 0);
v.normalizeLocal();
// result between [0; PI]
float angle = v.angleBetween(uBase);
if (v.x < 0) {
// the angle should be greater than PI, we're on the other part of the image then
angle = FastMath.TWO_PI - angle;
}
uvCoordinates[j] = angle / FastMath.TWO_PI;
// calculating V
v.set(positions[i] - cx, positions[i + 1] - cy, positions[i + 2] - cz);
v.normalizeLocal();
// result between [0; PI]
angle = v.angleBetween(vBase);
uvCoordinates[j + 1] = angle / FastMath.PI;
}
// looking for splitted triangles
Triangle triangle = new Triangle();
for (int i = 0; i < positions.length; i += 9) {
triangle.set(0, positions[i], positions[i + 1], positions[i + 2]);
triangle.set(1, positions[i + 3], positions[i + 4], positions[i + 5]);
triangle.set(2, positions[i + 6], positions[i + 7], positions[i + 8]);
float sgn1 = Math.signum(triangle.get1().x - cx);
float sgn2 = Math.signum(triangle.get2().x - cx);
float sgn3 = Math.signum(triangle.get3().x - cx);
float xSideFactor = sgn1 + sgn2 + sgn3;
float ySideFactor = Math.signum(triangle.get1().y - cy) + Math.signum(triangle.get2().y - cy) + Math.signum(triangle.get3().y - cy);
if ((xSideFactor > -3 || xSideFactor < 3) && ySideFactor < 0) {
// the triangle is on the splitting plane
if (sgn1 == 1.0f) {
uvCoordinates[i / 3 * 2] += 1.0f;
}
if (sgn2 == 1.0f) {
uvCoordinates[(i / 3 + 1) * 2] += 1.0f;
}
if (sgn3 == 1.0f) {
uvCoordinates[(i / 3 + 2) * 2] += 1.0f;
}
}
}
return uvCoordinates;
}
use of com.jme3.bounding.BoundingSphere in project jmonkeyengine by jMonkeyEngine.
the class LightProbeBlendingProcessor method computeBlendFactors.
private float computeBlendFactors(List<BlendFactor> blendFactors) {
float sumBlendFactors = 0;
for (Spatial scene : viewPort.getScenes()) {
for (Light light : scene.getWorldLightList()) {
if (light.getType() == Light.Type.Probe) {
LightProbe p = (LightProbe) light;
TempVars vars = TempVars.get();
boolean intersect = p.intersectsFrustum(viewPort.getCamera(), vars);
vars.release();
//check if the probe is inside the camera frustum
if (intersect) {
//is the poi inside the bounds of this probe
if (poi.getWorldBound().intersects(p.getBounds())) {
//computing the distance as we need it to check if th epoi in in the inner radius and later to compute the weight
float outerRadius = ((BoundingSphere) p.getBounds()).getRadius();
float innerRadius = outerRadius * 0.5f;
float distance = p.getBounds().getCenter().distance(poi.getWorldTranslation());
// if the poi in inside the inner range of this probe, then this probe is the only one that matters.
if (distance < innerRadius) {
blendFactors.clear();
blendFactors.add(new BlendFactor(p, 1.0f));
return 1.0f;
}
//else we need to compute the weight of this probe and collect it for blending
float ndf = (distance - innerRadius) / (outerRadius - innerRadius);
sumBlendFactors += ndf;
blendFactors.add(new BlendFactor(p, ndf));
}
}
}
}
}
return sumBlendFactors;
}
use of com.jme3.bounding.BoundingSphere in project jmonkeyengine by jMonkeyEngine.
the class PoiLightProbeLightFilter method filterLights.
@Override
public void filterLights(Geometry geometry, LightList filteredLightList) {
TempVars vars = TempVars.get();
try {
LightList worldLights = geometry.getWorldLightList();
for (int i = 0; i < worldLights.size(); i++) {
Light light = worldLights.get(i);
if (light.getType() == Light.Type.Probe) {
continue;
}
if (light.frustumCheckNeeded) {
processedLights.add(light);
light.frustumCheckNeeded = false;
light.intersectsFrustum = light.intersectsFrustum(camera, vars);
}
if (!light.intersectsFrustum) {
continue;
}
BoundingVolume bv = geometry.getWorldBound();
if (bv instanceof BoundingBox) {
if (!light.intersectsBox((BoundingBox) bv, vars)) {
continue;
}
} else if (bv instanceof BoundingSphere) {
if (!Float.isInfinite(((BoundingSphere) bv).getRadius())) {
if (!light.intersectsSphere((BoundingSphere) bv, vars)) {
continue;
}
}
}
filteredLightList.add(light);
}
processor.populateProbe(filteredLightList);
} finally {
vars.release();
}
}
Aggregations