@ -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 ) ;
}
}