159b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartapackage com.jme3.util;
259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
359b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.asset.AssetManager;
459b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.asset.TextureKey;
559b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.bounding.BoundingSphere;
659b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.material.Material;
759b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.math.Vector3f;
859b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.renderer.queue.RenderQueue.Bucket;
959b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.scene.Geometry;
1059b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.scene.Spatial;
1159b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.scene.shape.Sphere;
1259b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.texture.Image;
1359b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.texture.Image.Format;
1459b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.texture.Texture;
1559b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.texture.TextureCubeMap;
1659b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport java.nio.ByteBuffer;
1759b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport java.util.ArrayList;
1859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
1959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta/**
2059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * <code>SkyFactory</code> is used to create jME {@link Spatial}s that can
2159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * be attached to the scene to display a sky image in the background.
2259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *
2359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @author Kirill Vainer
2459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta */
2559b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartapublic class SkyFactory {
2659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
2759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
2859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Creates a sky using the given texture (cubemap or spheremap).
2959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
3059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param assetManager The asset manager to use to load materials
3159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param texture Texture to use for the sky
3259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param normalScale The normal scale is multiplied by the 3D normal
3359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * to get a texture coordinate. Use Vector3f.UNIT_XYZ to not apply
3459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * and transformation to the normal.
3559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param sphereMap The way the texture is used
3659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * depends on this value:<br>
3759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * <ul>
3859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * <li>true: Its a Texture2D with the pixels arranged for
3959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * <a href="http://en.wikipedia.org/wiki/Sphere_mapping">sphere mapping</a>.</li>
4059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * <li>false: Its either a TextureCubeMap or Texture2D. If its a Texture2D
4159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * then the image is taken from it and is inserted into a TextureCubeMap</li>
4259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * </ul>
4359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return A spatial representing the sky
4459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
4559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static Spatial createSky(AssetManager assetManager, Texture texture, Vector3f normalScale, boolean sphereMap) {
4659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return createSky(assetManager, texture, normalScale, sphereMap, 10);
4759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
4859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
4959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
5059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Creates a sky using the given texture (cubemap or spheremap).
5159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
5259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param assetManager The asset manager to use to load materials
5359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param texture Texture to use for the sky
5459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param normalScale The normal scale is multiplied by the 3D normal
5559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * to get a texture coordinate. Use Vector3f.UNIT_XYZ to not apply
5659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * and transformation to the normal.
5759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param sphereMap The way the texture is used
5859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * depends on this value:<br>
5959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * <ul>
6059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * <li>true: Its a Texture2D with the pixels arranged for
6159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * <a href="http://en.wikipedia.org/wiki/Sphere_mapping">sphere mapping</a>.</li>
6259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * <li>false: Its either a TextureCubeMap or Texture2D. If its a Texture2D
6359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * then the image is taken from it and is inserted into a TextureCubeMap</li>
6459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * </ul>
6559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param sphereRadius If specified, this will be the sky sphere's radius.
6659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * This should be the camera's near plane for optimal quality.
6759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return A spatial representing the sky
6859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
6959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static Spatial createSky(AssetManager assetManager, Texture texture, Vector3f normalScale, boolean sphereMap, int sphereRadius) {
7059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (texture == null) {
7159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            throw new IllegalArgumentException("texture cannot be null");
7259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
7359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        final Sphere sphereMesh = new Sphere(10, 10, sphereRadius, false, true);
7459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
7559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        Geometry sky = new Geometry("Sky", sphereMesh);
7659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        sky.setQueueBucket(Bucket.Sky);
7759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        sky.setCullHint(Spatial.CullHint.Never);
7859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        sky.setModelBound(new BoundingSphere(Float.POSITIVE_INFINITY, Vector3f.ZERO));
7959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
8059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        Material skyMat = new Material(assetManager, "Common/MatDefs/Misc/Sky.j3md");
8159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
8259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        skyMat.setVector3("NormalScale", normalScale);
8359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (sphereMap) {
8459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            skyMat.setBoolean("SphereMap", sphereMap);
8559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        } else if (!(texture instanceof TextureCubeMap)) {
8659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            // make sure its a cubemap
8759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            Image img = texture.getImage();
8859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            texture = new TextureCubeMap();
8959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            texture.setImage(img);
9059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
9159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        skyMat.setTexture("Texture", texture);
9259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        sky.setMaterial(skyMat);
9359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
9459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return sky;
9559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
9659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
9759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private static void checkImage(Image image) {
9859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta//        if (image.getDepth() != 1)
9959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta//            throw new IllegalArgumentException("3D/Array images not allowed");
10059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
10159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (image.getWidth() != image.getHeight()) {
10259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            throw new IllegalArgumentException("Image width and height must be the same");
10359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
10459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
10559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (image.getMultiSamples() != 1) {
10659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            throw new IllegalArgumentException("Multisample textures not allowed");
10759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
10859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
10959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
11059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private static void checkImagesForCubeMap(Image... images) {
11159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (images.length == 1) {
11259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            return;
11359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
11459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
11559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        Format fmt = images[0].getFormat();
11659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        int width = images[0].getWidth();
11759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        int height = images[0].getHeight();
11859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
11959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        ByteBuffer data = images[0].getData(0);
12059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        int size = data != null ? data.capacity() : 0;
12159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
12259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        checkImage(images[0]);
12359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
12459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        for (int i = 1; i < images.length; i++) {
12559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            Image image = images[i];
12659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            checkImage(images[i]);
12759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (image.getFormat() != fmt) {
12859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                throw new IllegalArgumentException("Images must have same format");
12959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
13059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (image.getWidth() != width || image.getHeight() != height)  {
13159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                throw new IllegalArgumentException("Images must have same resolution");
13259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
13359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            ByteBuffer data2 = image.getData(0);
13459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (data2 != null){
13559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                if (data2.capacity() != size) {
13659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    throw new IllegalArgumentException("Images must have same size");
13759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                }
13859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
13959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
14059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
14159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
14259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static Spatial createSky(AssetManager assetManager, Texture west, Texture east, Texture north, Texture south, Texture up, Texture down, Vector3f normalScale) {
14359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return createSky(assetManager, west, east, north, south, up, down, normalScale, 10);
14459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
14559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
14659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static Spatial createSky(AssetManager assetManager, Texture west, Texture east, Texture north, Texture south, Texture up, Texture down, Vector3f normalScale, int sphereRadius) {
14759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        final Sphere sphereMesh = new Sphere(10, 10, sphereRadius, false, true);
14859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        Geometry sky = new Geometry("Sky", sphereMesh);
14959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        sky.setQueueBucket(Bucket.Sky);
15059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        sky.setCullHint(Spatial.CullHint.Never);
15159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        sky.setModelBound(new BoundingSphere(Float.POSITIVE_INFINITY, Vector3f.ZERO));
15259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
15359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        Image westImg = west.getImage();
15459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        Image eastImg = east.getImage();
15559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        Image northImg = north.getImage();
15659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        Image southImg = south.getImage();
15759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        Image upImg = up.getImage();
15859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        Image downImg = down.getImage();
15959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
16059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        checkImagesForCubeMap(westImg, eastImg, northImg, southImg, upImg, downImg);
16159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
16259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        Image cubeImage = new Image(westImg.getFormat(), westImg.getWidth(), westImg.getHeight(), null);
16359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
16459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        cubeImage.addData(westImg.getData(0));
16559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        cubeImage.addData(eastImg.getData(0));
16659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
16759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        cubeImage.addData(downImg.getData(0));
16859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        cubeImage.addData(upImg.getData(0));
16959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
17059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        cubeImage.addData(southImg.getData(0));
17159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        cubeImage.addData(northImg.getData(0));
17259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
17359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (westImg.getEfficentData() != null){
17459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            // also consilidate efficient data
17559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            ArrayList<Object> efficientData = new ArrayList<Object>(6);
17659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            efficientData.add(westImg.getEfficentData());
17759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            efficientData.add(eastImg.getEfficentData());
17859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            efficientData.add(downImg.getEfficentData());
17959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            efficientData.add(upImg.getEfficentData());
18059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            efficientData.add(southImg.getEfficentData());
18159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            efficientData.add(northImg.getEfficentData());
18259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            cubeImage.setEfficentData(efficientData);
18359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
18459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
18559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        TextureCubeMap cubeMap = new TextureCubeMap(cubeImage);
18659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        cubeMap.setAnisotropicFilter(0);
18759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        cubeMap.setMagFilter(Texture.MagFilter.Bilinear);
18859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        cubeMap.setMinFilter(Texture.MinFilter.NearestNoMipMaps);
18959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        cubeMap.setWrap(Texture.WrapMode.EdgeClamp);
19059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
19159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        Material skyMat = new Material(assetManager, "Common/MatDefs/Misc/Sky.j3md");
19259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        skyMat.setTexture("Texture", cubeMap);
19359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        skyMat.setVector3("NormalScale", normalScale);
19459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        sky.setMaterial(skyMat);
19559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
19659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return sky;
19759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
19859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
19959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static Spatial createSky(AssetManager assetManager, Texture west, Texture east, Texture north, Texture south, Texture up, Texture down) {
20059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return createSky(assetManager, west, east, north, south, up, down, Vector3f.UNIT_XYZ);
20159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
20259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
20359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static Spatial createSky(AssetManager assetManager, Texture texture, boolean sphereMap) {
20459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return createSky(assetManager, texture, Vector3f.UNIT_XYZ, sphereMap);
20559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
20659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
20759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static Spatial createSky(AssetManager assetManager, String textureName, boolean sphereMap) {
20859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        TextureKey key = new TextureKey(textureName, true);
20959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        key.setGenerateMips(true);
21059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        key.setAsCube(!sphereMap);
21159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        Texture tex = assetManager.loadTexture(key);
21259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return createSky(assetManager, tex, sphereMap);
21359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
21459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta}
215