@ -29,98 +29,143 @@
* NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE , EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE .
* /
package jme3test.light ;
import com.jme3.app.SimpleApplication ;
import com.jme3.font.BitmapText ;
import com.jme3.input.KeyInput ;
import com.jme3.input.controls.ActionListener ;
import com.jme3.input.controls.KeyTrigger ;
import com.jme3.light.AmbientLight ;
import com.jme3.light.DirectionalLight ;
import com.jme3.material.Material ;
import com.jme3.math.ColorRGBA ;
import com.jme3.math.FastMath ;
import com.jme3.math.Quaternion ;
import com.jme3.math.Vector2f ;
import com.jme3.math.Vector3f ;
import com.jme3.renderer.RenderManager ;
import com.jme3.renderer.ViewPort ;
import com.jme3.renderer.queue.RenderQueue.ShadowMode ;
import com.jme3.scene.Geometry ;
import com.jme3.scene.Spatial ;
import com.jme3.scene.control.AbstractControl ;
import com.jme3.scene.control.Control ;
import com.jme3.scene.shape.Box ;
import com.jme3.scene.shape.Sphere ;
import com.jme3.shadow.PssmShadowRenderer ;
import com.jme3.shadow.PssmShadowRenderer.CompareMode ;
import com.jme3.shadow.PssmShadowRenderer.FilterMode ;
import java.util.Random ;
import com.jme3.texture.Texture ;
import com.jme3.texture.Texture.WrapMode ;
import com.jme3.util.SkyFactory ;
import com.jme3.util.TangentBinormalGenerator ;
public class TestPssmShadow extends SimpleApplication implements ActionListener {
private Spatial teapot ;
private Spatial [ ] obj ;
private Material [ ] mat ;
private boolean renderShadows = true ;
private boolean hardwareShadows = false ;
private PssmShadowRenderer pssmRenderer ;
private Geometry ground ;
private Material matGroundU ;
private Material matGroundL ;
public static void main ( String [ ] args ) {
public static void main ( String [ ] args ) {
TestPssmShadow app = new TestPssmShadow ( ) ;
app . start ( ) ;
}
public void loadScene ( ) {
Material mat = assetManager . loadMaterial ( "Common/Materials/RedColor.j3m" ) ;
Material matSoil = new Material ( assetManager , "Common/MatDefs/Misc/Unshaded.j3md" ) ;
matSoil . setColor ( "Color" , ColorRGBA . Cyan ) ;
public void loadScene ( ) {
obj = new Spatial [ 2 ] ;
mat = new Material [ 2 ] ;
mat [ 0 ] = assetManager . loadMaterial ( "Common/Materials/RedColor.j3m" ) ;
mat [ 1 ] = assetManager . loadMaterial ( "Textures/Terrain/Pond/Pond.j3m" ) ;
mat [ 1 ] . setBoolean ( "UseMaterialColors" , true ) ;
mat [ 1 ] . setColor ( "Ambient" , ColorRGBA . White . mult ( 0 . 5f ) ) ;
mat [ 1 ] . setColor ( "Diffuse" , ColorRGBA . White . clone ( ) ) ;
teapot = new Geometry ( "sphere" , new Sphere ( 30 , 30 , 2 ) ) ;
// teapot = new Geometry("cube", new Box(1.0f, 1.0f, 1.0f));
// teapot = assetManager.loadModel("Models/Teapot/Teapot.obj");
teapot . setLocalTranslation ( 0 , 0 , 10 ) ;
teapot . setMaterial ( mat ) ;
teapot . setShadowMode ( ShadowMode . CastAndReceive ) ;
rootNode . attachChild ( teapot ) ;
obj [ 0 ] = new Geometry ( "sphere" , new Sphere ( 30 , 30 , 2 ) ) ;
obj [ 0 ] . setShadowMode ( ShadowMode . CastAndReceive ) ;
obj [ 1 ] = new Geometry ( "cube" , new Box ( 1 . 0f , 1 . 0f , 1 . 0f ) ) ;
obj [ 1 ] . setShadowMode ( ShadowMode . CastAndReceive ) ;
TangentBinormalGenerator . generate ( obj [ 1 ] ) ;
TangentBinormalGenerator . generate ( obj [ 0 ] ) ;
long seed = 1294719330150L ; //System.currentTimeMillis();
Random random = new Random ( seed ) ;
System . out . println ( seed ) ;
for ( int i = 0 ; i < 30 ; i + + ) {
Spatial t = teapot . clone ( false ) ;
for ( int i = 0 ; i < 60 ; i + + ) {
Spatial t = obj [ FastMath . nextRandomInt ( 0 , obj . length - 1 ) ] . clone ( false ) ;
t . setLocalScale ( FastMath . nextRandomFloat ( ) * 10f ) ;
t . setMaterial ( mat [ FastMath . nextRandomInt ( 0 , mat . length - 1 ) ] ) ;
rootNode . attachChild ( t ) ;
teapot . setLocalTranslation ( ( float ) random . nextFloat ( ) * 3 , ( float ) random . nextFloat ( ) * 3 , ( i + 2 ) ) ;
t . setLocalTranslation ( FastMath . nextRandom Float( ) * 200f , FastMath . nextRandomFloat ( ) * 30f + 20 , 30f * ( i + 2f ) ) ;
}
Geometry soil = new Geometry ( "soil" , new Box ( new Vector3f ( 0 , - 13 , 550 ) , 800 , 10 , 700 ) ) ;
soil . setMaterial ( matSoil ) ;
soil . setShadowMode ( ShadowMode . Receive ) ;
rootNode . attachChild ( soil ) ;
Box b = new Box ( new Vector3f ( 0 , 10 , 550 ) , 1000 , 2 , 1000 ) ;
b . scaleTextureCoordinates ( new Vector2f ( 10 , 10 ) ) ;
ground = new Geometry ( "soil" , b ) ;
matGroundU = new Material ( assetManager , "Common/MatDefs/Misc/Unshaded.j3md" ) ;
matGroundU . setColor ( "Color" , ColorRGBA . Green ) ;
matGroundL = new Material ( assetManager , "Common/MatDefs/Light/Lighting.j3md" ) ;
Texture grass = assetManager . loadTexture ( "Textures/Terrain/splat/grass.jpg" ) ;
grass . setWrap ( WrapMode . Repeat ) ;
matGroundL . setTexture ( "DiffuseMap" , grass ) ;
ground . setMaterial ( matGroundL ) ;
ground . setShadowMode ( ShadowMode . CastAndReceive ) ;
rootNode . attachChild ( ground ) ;
for ( int i = 0 ; i < 30 ; i + + ) {
Spatial t = teapot . clone ( false ) ;
t . setLocalScale ( 10 . 0f ) ;
rootNode . attachChild ( t ) ;
teapot . setLocalTranslation ( ( float ) random . nextFloat ( ) * 300 , ( float ) random . nextFloat ( ) * 30 , 30 * ( i + 2 ) ) ;
}
DirectionalLight l = new DirectionalLight ( ) ;
l . setDirection ( new Vector3f ( - 1 , - 1 , - 1 ) ) ;
rootNode . addLight ( l ) ;
AmbientLight al = new AmbientLight ( ) ;
al . setColor ( ColorRGBA . White . mult ( 0 . 5f ) ) ;
rootNode . addLight ( al ) ;
Spatial sky = SkyFactory . createSky ( assetManager , "Scenes/Beach/FullskiesSunset0068.dds" , false ) ;
sky . setLocalScale ( 350 ) ;
rootNode . attachChild ( sky ) ;
}
@Override
public void simpleInitApp ( ) {
// put the camera in a bad position
cam . setLocation ( new Vector3f ( 41 . 59757f , 34 . 38738f , 11 . 528807f ) ) ;
cam . setRotation ( new Quaternion ( 0 . 2905285f , 0 . 3816416f , - 0 . 12772122f , 0 . 86811876f ) ) ;
cam . setLocation ( new Vector3f ( 65 . 25412f , 44 . 38738f , 9 . 087874f ) ) ;
cam . setRotation ( new Quaternion ( 0 . 078139365f , 0 . 050241485f , - 0 . 003942559f , 0 . 9956679f ) ) ;
flyCam . setMoveSpeed ( 100 ) ;
loadScene ( ) ;
pssmRenderer = new PssmShadowRenderer ( assetManager , 1024 , 3 ) ;
pssmRenderer . setDirection ( new Vector3f ( - 1 , - 1 , - 1 ) . normalizeLocal ( ) ) ;
pssmRenderer . setLambda ( 0 . 55f ) ;
pssmRenderer . setShadowIntensity ( 0 . 6f ) ;
pssmRenderer . setCompareMode ( CompareMode . Software ) ;
pssmRenderer . setFilterMode ( FilterMode . Bilinea r) ;
pssmRenderer . setFilterMode ( FilterMode . Dithe r) ;
pssmRenderer . displayDebug ( ) ;
viewPort . addProcessor ( pssmRenderer ) ;
initInputs ( ) ;
}
BitmapText infoText ;
private void initInputs ( ) {
/** Write text on the screen (HUD) */
guiFont = assetManager . loadFont ( "Interface/Fonts/Default.fnt" ) ;
infoText = new BitmapText ( guiFont , false ) ;
infoText . setSize ( guiFont . getCharSet ( ) . getRenderedSize ( ) ) ;
private void initInputs ( ) {
inputManager . addMapping ( "toggle" , new KeyTrigger ( KeyInput . KEY_SPACE ) ) ;
inputManager . addMapping ( "changeFiltering" , new KeyTrigger ( KeyInput . KEY_F ) ) ;
inputManager . addMapping ( "ShadowUp" , new KeyTrigger ( KeyInput . KEY_T ) ) ;
inputManager . addMapping ( "ShadowDown" , new KeyTrigger ( KeyInput . KEY_G ) ) ;
inputManager . addMapping ( "ThicknessUp" , new KeyTrigger ( KeyInput . KEY_Y ) ) ;
@ -128,9 +173,46 @@ public class TestPssmShadow extends SimpleApplication implements ActionListener
inputManager . addMapping ( "lambdaUp" , new KeyTrigger ( KeyInput . KEY_U ) ) ;
inputManager . addMapping ( "lambdaDown" , new KeyTrigger ( KeyInput . KEY_J ) ) ;
inputManager . addMapping ( "toggleHW" , new KeyTrigger ( KeyInput . KEY_RETURN ) ) ;
inputManager . addListener ( this , "lambdaUp" , "lambdaDown" , "toggleHW" , "toggle" , "ShadowUp" , "ShadowDown" , "ThicknessUp" , "ThicknessDown" ) ;
inputManager . addMapping ( "switchGroundMat" , new KeyTrigger ( KeyInput . KEY_M ) ) ;
inputManager . addListener ( this , "lambdaUp" , "lambdaDown" , "toggleHW" , "toggle" , "ShadowUp" , "ShadowDown" , "ThicknessUp" , "ThicknessDown" , "changeFiltering" , "switchGroundMat" ) ;
}
private void print ( String str ) {
infoText . setText ( str ) ;
infoText . setLocalTranslation ( cam . getWidth ( ) * 0 . 5f - infoText . getLineWidth ( ) * 0 . 5f , infoText . getLineHeight ( ) , 0 ) ;
guiNode . attachChild ( infoText ) ;
infoText . removeControl ( ctrl ) ;
infoText . addControl ( ctrl ) ;
}
AbstractControl ctrl = new AbstractControl ( ) {
float time ;
@Override
protected void controlUpdate ( float tpf ) {
time + = tpf ;
if ( time > 3 ) {
spatial . removeFromParent ( ) ;
spatial . removeControl ( this ) ;
}
}
@Override
public void setSpatial ( Spatial spatial ) {
super . setSpatial ( spatial ) ;
time = 0 ;
}
@Override
protected void controlRender ( RenderManager rm , ViewPort vp ) {
}
public Control cloneForSpatial ( Spatial spatial ) {
return null ;
}
} ;
int filteringIndex = 2 ;
public void onAction ( String name , boolean keyPressed , float tpf ) {
if ( name . equals ( "toggle" ) & & keyPressed ) {
if ( renderShadows ) {
@ -146,6 +228,13 @@ public class TestPssmShadow extends SimpleApplication implements ActionListener
System . out . println ( "HW Shadows: " + hardwareShadows ) ;
}
if ( name . equals ( "changeFiltering" ) & & keyPressed ) {
filteringIndex = ( filteringIndex + 1 ) % FilterMode . values ( ) . length ;
FilterMode m = FilterMode . values ( ) [ filteringIndex ] ;
pssmRenderer . setFilterMode ( m ) ;
print ( "Filter mode : " + m . toString ( ) ) ;
}
if ( name . equals ( "lambdaUp" ) & & keyPressed ) {
pssmRenderer . setLambda ( pssmRenderer . getLambda ( ) + 0 . 01f ) ;
System . out . println ( "Lambda : " + pssmRenderer . getLambda ( ) ) ;
@ -170,7 +259,13 @@ public class TestPssmShadow extends SimpleApplication implements ActionListener
pssmRenderer . setEdgesThickness ( pssmRenderer . getEdgesThickness ( ) - 1 ) ;
System . out . println ( "Shadow thickness : " + pssmRenderer . getEdgesThickness ( ) ) ;
}
if ( name . equals ( "switchGroundMat" ) & & keyPressed ) {
if ( ground . getMaterial ( ) = = matGroundL ) {
ground . setMaterial ( matGroundU ) ;
} else {
ground . setMaterial ( matGroundL ) ;
}
}
}
}