Search in sources :

Example 21 with BoundingSphere

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;
}
Also used : BoundingSphere(com.jme3.bounding.BoundingSphere) Sphere(com.jme3.scene.shape.Sphere) Geometry(com.jme3.scene.Geometry) BoundingSphere(com.jme3.bounding.BoundingSphere) TextureCubeMap(com.jme3.texture.TextureCubeMap) Material(com.jme3.material.Material) Image(com.jme3.texture.Image)

Example 22 with BoundingSphere

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;
}
Also used : BoundingSphere(com.jme3.bounding.BoundingSphere) Vector2f(com.jme3.math.Vector2f) BoundingBox(com.jme3.bounding.BoundingBox) ArrayList(java.util.ArrayList)

Example 23 with BoundingSphere

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;
}
Also used : Vector3f(com.jme3.math.Vector3f) Triangle(com.jme3.math.Triangle)

Example 24 with BoundingSphere

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;
}
Also used : BoundingSphere(com.jme3.bounding.BoundingSphere) Spatial(com.jme3.scene.Spatial) TempVars(com.jme3.util.TempVars)

Example 25 with BoundingSphere

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();
    }
}
Also used : BoundingSphere(com.jme3.bounding.BoundingSphere) BoundingBox(com.jme3.bounding.BoundingBox) BoundingVolume(com.jme3.bounding.BoundingVolume) TempVars(com.jme3.util.TempVars)

Aggregations

BoundingSphere (com.jme3.bounding.BoundingSphere)24 Vector3f (com.jme3.math.Vector3f)9 BoundingBox (com.jme3.bounding.BoundingBox)8 TempVars (com.jme3.util.TempVars)7 Test (org.junit.Test)7 BoundingVolume (com.jme3.bounding.BoundingVolume)5 Geometry (com.jme3.scene.Geometry)5 LightProbe (com.jme3.light.LightProbe)4 EnvironmentCamera (com.jme3.environment.EnvironmentCamera)3 Material (com.jme3.material.Material)3 Node (com.jme3.scene.Node)2 ArrayList (java.util.ArrayList)2 UnsupportedCollisionException (com.jme3.collision.UnsupportedCollisionException)1 InputCapsule (com.jme3.export.InputCapsule)1 OutputCapsule (com.jme3.export.OutputCapsule)1 Light (com.jme3.light.Light)1 Triangle (com.jme3.math.Triangle)1 Vector2f (com.jme3.math.Vector2f)1 Mesh (com.jme3.scene.Mesh)1 Spatial (com.jme3.scene.Spatial)1