|
@@ -23,6 +23,7 @@ import com.jme3.texture.Image;
|
|
|
import com.jme3.texture.Image.Format;
|
|
|
import com.jme3.texture.Texture;
|
|
|
import com.jme3.texture.TextureCubeMap;
|
|
|
+import com.jme3.util.TempVars;
|
|
|
|
|
|
/**
|
|
|
* The generated texture loaded from blender file. The texture is not generated
|
|
@@ -32,29 +33,72 @@ import com.jme3.texture.TextureCubeMap;
|
|
|
* @author Marcin Roguski (Kaelthas)
|
|
|
*/
|
|
|
/* package */class GeneratedTexture extends Texture {
|
|
|
- private static final int POSITIVE_X = 0;
|
|
|
- private static final int NEGATIVE_X = 1;
|
|
|
- private static final int POSITIVE_Y = 2;
|
|
|
- private static final int NEGATIVE_Y = 3;
|
|
|
- private static final int POSITIVE_Z = 4;
|
|
|
- private static final int NEGATIVE_Z = 5;
|
|
|
+ private static final int POSITIVE_X = 0;
|
|
|
+ private static final int NEGATIVE_X = 1;
|
|
|
+ private static final int POSITIVE_Y = 2;
|
|
|
+ private static final int NEGATIVE_Y = 3;
|
|
|
+ private static final int POSITIVE_Z = 4;
|
|
|
+ private static final int NEGATIVE_Z = 5;
|
|
|
|
|
|
// flag values
|
|
|
- public static final int TEX_COLORBAND = 1;
|
|
|
- public static final int TEX_FLIPBLEND = 2;
|
|
|
- public static final int TEX_NEGALPHA = 4;
|
|
|
- public static final int TEX_CHECKER_ODD = 8;
|
|
|
- public static final int TEX_CHECKER_EVEN = 16;
|
|
|
- public static final int TEX_PRV_ALPHA = 32;
|
|
|
- public static final int TEX_PRV_NOR = 64;
|
|
|
- public static final int TEX_REPEAT_XMIR = 128;
|
|
|
- public static final int TEX_REPEAT_YMIR = 256;
|
|
|
- public static final int TEX_FLAG_MASK = TEX_COLORBAND | TEX_FLIPBLEND | TEX_NEGALPHA | TEX_CHECKER_ODD | TEX_CHECKER_EVEN | TEX_PRV_ALPHA | TEX_PRV_NOR | TEX_REPEAT_XMIR | TEX_REPEAT_YMIR;
|
|
|
+ public static final int TEX_COLORBAND = 1;
|
|
|
+ public static final int TEX_FLIPBLEND = 2;
|
|
|
+ public static final int TEX_NEGALPHA = 4;
|
|
|
+ public static final int TEX_CHECKER_ODD = 8;
|
|
|
+ public static final int TEX_CHECKER_EVEN = 16;
|
|
|
+ public static final int TEX_PRV_ALPHA = 32;
|
|
|
+ public static final int TEX_PRV_NOR = 64;
|
|
|
+ public static final int TEX_REPEAT_XMIR = 128;
|
|
|
+ public static final int TEX_REPEAT_YMIR = 256;
|
|
|
+ public static final int TEX_FLAG_MASK = TEX_COLORBAND | TEX_FLIPBLEND | TEX_NEGALPHA | TEX_CHECKER_ODD | TEX_CHECKER_EVEN | TEX_PRV_ALPHA | TEX_PRV_NOR | TEX_REPEAT_XMIR | TEX_REPEAT_YMIR;
|
|
|
|
|
|
/** Material-texture link structure. */
|
|
|
- private final Structure mTex;
|
|
|
+ private final Structure mTex;
|
|
|
/** Texture generateo for the specified texture type. */
|
|
|
- private final TextureGenerator textureGenerator;
|
|
|
+ private final TextureGenerator textureGenerator;
|
|
|
+ /**
|
|
|
+ * The generated texture cast functions. They are used to cas a given point on a plane to a specified shape in 3D space.
|
|
|
+ * The functions should be ordered as the ordinal of a BlenderKey.CastFunction enums.
|
|
|
+ */
|
|
|
+ private final static CastFunction[] CAST_FUNCTIONS = new CastFunction[] {
|
|
|
+ /**
|
|
|
+ * The cube casting function (does nothing except scaling if needed because the given points are already on a cube).
|
|
|
+ */
|
|
|
+ new CastFunction() {
|
|
|
+ @Override
|
|
|
+ public void cast(Vector3f pointToCast, float radius) {
|
|
|
+ //computed using the Thales' theorem
|
|
|
+ float length = 2 * pointToCast.subtractLocal(0.5f, 0.5f, 0.5f).length() * radius;
|
|
|
+ pointToCast.normalizeLocal().addLocal(0.5f, 0.5f, 0.5f).multLocal(length);
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ /**
|
|
|
+ * The sphere casting function.
|
|
|
+ */
|
|
|
+ new CastFunction() {
|
|
|
+ /**
|
|
|
+ * The method casts a point on a plane to a sphere.
|
|
|
+ * The plane is one of the faces of a cube that has a edge of length 1 and center in (0.5 0.5, 0.5). This cube is a basic 3d area where generated texture
|
|
|
+ * is created.
|
|
|
+ * To cast a point on a cube face to a sphere that is inside the cube we perform several easy vector operations.
|
|
|
+ * 1. create a vector from the cube's center to the point
|
|
|
+ * 2. setting its length to 0.5 (the radius of the sphere)
|
|
|
+ * 3. adding the value of the cube's center to get a point on the sphere
|
|
|
+ *
|
|
|
+ * The result is stored in the given vector.
|
|
|
+ *
|
|
|
+ * @param pointToCast
|
|
|
+ * the point on a plane that will be cast to a sphere
|
|
|
+ * @param radius
|
|
|
+ * the radius of the sphere
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ public void cast(Vector3f pointToCast, float radius) {
|
|
|
+ pointToCast.subtractLocal(0.5f, 0.5f, 0.5f).normalizeLocal().multLocal(radius).addLocal(0.5f, 0.5f, 0.5f);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ };
|
|
|
|
|
|
/**
|
|
|
* Constructor. Reads the required data from the 'tex' structure.
|
|
@@ -137,37 +181,48 @@ import com.jme3.texture.TextureCubeMap;
|
|
|
* the horizon color
|
|
|
* @param zenithColor
|
|
|
* the zenith color
|
|
|
+ * @param blenderContext
|
|
|
+ * the blender context
|
|
|
* @return the sky texture
|
|
|
*/
|
|
|
- public TextureCubeMap generateSkyTexture(int size, ColorRGBA horizontalColor, ColorRGBA zenithColor) {
|
|
|
+ public TextureCubeMap generateSkyTexture(int size, ColorRGBA horizontalColor, ColorRGBA zenithColor, BlenderContext blenderContext) {
|
|
|
Image image = ImageUtils.createEmptyImage(Format.RGB8, size, size, 6);
|
|
|
PixelInputOutput pixelIO = PixelIOFactory.getPixelIO(image.getFormat());
|
|
|
TexturePixel pixel = new TexturePixel();
|
|
|
|
|
|
float delta = 1 / (float) (size - 1);
|
|
|
float sideV, sideS = 1, forwardU = 1, forwardV, upS;
|
|
|
+ TempVars tempVars = TempVars.get();
|
|
|
+ CastFunction castFunction = CAST_FUNCTIONS[blenderContext.getBlenderKey().getSkyGeneratedTextureShape().ordinal()];
|
|
|
+ float castRadius = blenderContext.getBlenderKey().getSkyGeneratedTextureRadius();
|
|
|
|
|
|
for (int x = 0; x < size; ++x) {
|
|
|
sideV = 1;
|
|
|
forwardV = 1;
|
|
|
upS = 0;
|
|
|
for (int y = 0; y < size; ++y) {
|
|
|
- textureGenerator.getPixel(pixel, 1, sideV, sideS);
|
|
|
+ castFunction.cast(tempVars.vect1.set(1, sideV, sideS), castRadius);
|
|
|
+ textureGenerator.getPixel(pixel, tempVars.vect1.x, tempVars.vect1.y, tempVars.vect1.z);
|
|
|
pixelIO.write(image, NEGATIVE_X, ImageUtils.color(pixel, horizontalColor, zenithColor), x, y);// right
|
|
|
|
|
|
- textureGenerator.getPixel(pixel, 0, sideV, 1 - sideS);
|
|
|
+ castFunction.cast(tempVars.vect1.set(0, sideV, 1 - sideS), castRadius);
|
|
|
+ textureGenerator.getPixel(pixel, tempVars.vect1.x, tempVars.vect1.y, tempVars.vect1.z);
|
|
|
pixelIO.write(image, POSITIVE_X, ImageUtils.color(pixel, horizontalColor, zenithColor), x, y);// left
|
|
|
|
|
|
- textureGenerator.getPixel(pixel, forwardU, forwardV, 0);
|
|
|
+ castFunction.cast(tempVars.vect1.set(forwardU, forwardV, 0), castRadius);
|
|
|
+ textureGenerator.getPixel(pixel, tempVars.vect1.x, tempVars.vect1.y, tempVars.vect1.z);
|
|
|
pixelIO.write(image, POSITIVE_Z, ImageUtils.color(pixel, horizontalColor, zenithColor), x, y);// front
|
|
|
|
|
|
- textureGenerator.getPixel(pixel, 1 - forwardU, forwardV, 1);
|
|
|
+ castFunction.cast(tempVars.vect1.set(1 - forwardU, forwardV, 1), castRadius);
|
|
|
+ textureGenerator.getPixel(pixel, tempVars.vect1.x, tempVars.vect1.y, tempVars.vect1.z);
|
|
|
pixelIO.write(image, NEGATIVE_Z, ImageUtils.color(pixel, horizontalColor, zenithColor), x, y);// back
|
|
|
|
|
|
- textureGenerator.getPixel(pixel, forwardU, 0, upS);
|
|
|
+ castFunction.cast(tempVars.vect1.set(forwardU, 0, upS), castRadius);
|
|
|
+ textureGenerator.getPixel(pixel, tempVars.vect1.x, tempVars.vect1.y, tempVars.vect1.z);
|
|
|
pixelIO.write(image, NEGATIVE_Y, ImageUtils.color(pixel, horizontalColor, zenithColor), x, y);// top
|
|
|
|
|
|
- textureGenerator.getPixel(pixel, forwardU, 1, 1 - upS);
|
|
|
+ castFunction.cast(tempVars.vect1.set(forwardU, 1, 1 - upS), castRadius);
|
|
|
+ textureGenerator.getPixel(pixel, tempVars.vect1.x, tempVars.vect1.y, tempVars.vect1.z);
|
|
|
pixelIO.write(image, POSITIVE_Y, ImageUtils.color(pixel, horizontalColor, zenithColor), x, y);// bottom
|
|
|
|
|
|
sideV = FastMath.clamp(sideV - delta, 0, 1);
|
|
@@ -177,6 +232,7 @@ import com.jme3.texture.TextureCubeMap;
|
|
|
sideS = FastMath.clamp(sideS - delta, 0, 1);
|
|
|
forwardU = FastMath.clamp(forwardU - delta, 0, 1);
|
|
|
}
|
|
|
+ tempVars.release();
|
|
|
|
|
|
return new TextureCubeMap(image);
|
|
|
}
|
|
@@ -214,4 +270,13 @@ import com.jme3.texture.TextureCubeMap;
|
|
|
super.format = imageFormat;
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ /**
|
|
|
+ * The casting functions to create a sky generated texture against selected shape of a selected size.
|
|
|
+ *
|
|
|
+ * @author Marcin Roguski (Kaelthas)
|
|
|
+ */
|
|
|
+ private static interface CastFunction {
|
|
|
+ void cast(Vector3f pointToCast, float radius);
|
|
|
+ }
|
|
|
}
|