Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@
import java.util.function.Predicate;
import com.jme3.asset.AssetManager;
import com.jme3.environment.baker.IBLGLEnvBakerLight;
import com.jme3.environment.baker.IBLHybridEnvBakerLight;
import com.jme3.export.InputCapsule;
import com.jme3.export.JmeExporter;
import com.jme3.export.JmeImporter;
Expand All @@ -49,7 +48,6 @@
import com.jme3.scene.Node;
import com.jme3.scene.Spatial;
import com.jme3.scene.control.Control;
import com.jme3.texture.Image.Format;

/**
* A control that automatically handles environment bake and rebake including
Expand Down Expand Up @@ -87,10 +85,12 @@ public class EnvironmentProbeControl extends LightProbe implements Control {
private float frustumNear = 0.001f, frustumFar = 1000f;
private String uuid = "none";
private boolean enabled = true;

private IBLGLEnvBakerLight.SphericalHarmonicsMode sphericalHarmonicsMode =
IBLGLEnvBakerLight.SphericalHarmonicsMode.AUTO;
private Predicate<Geometry> filter = (s) -> {
return s.getUserData("tags.env") != null || s.getUserData("tags.env.env" + uuid) != null;
};
private transient IBLGLEnvBakerLight baker;

protected EnvironmentProbeControl() {
super();
Expand Down Expand Up @@ -187,7 +187,36 @@ public static void untagGlobal(Spatial s) {

@Override
public Control cloneForSpatial(Spatial spatial) {
throw new UnsupportedOperationException();
EnvironmentProbeControl control = new EnvironmentProbeControl(assetManager, envMapSize);
control.setFrustumFar(frustumFar);
control.setFrustumNear(frustumNear);
control.setRequiredSavableResults(requiredSavableResults);
control.setEnabled(enabled);
control.setSphericalHarmonicsMode(sphericalHarmonicsMode);
control.setColor(getColor());
control.setName(getName());
control.setFrustumCheckNeeded(isFrustumCheckNeeded());
control.setAreaType(getAreaType());
control.getArea().setRadius(getArea().getRadius());
control.setPosition(getPosition());
control.retagForClone(spatial, uuid);
control.setSpatial(spatial);
return control;
}

private void retagForClone(Spatial spatial, String sourceUuid) {
if (spatial instanceof Node) {
Node n = (Node) spatial;
for (Spatial sx : n.getChildren()) {
retagForClone(sx, sourceUuid);
}
} else if (spatial instanceof Geometry) {
String sourceTag = "tags.env.env" + sourceUuid;
if (spatial.getUserData(sourceTag) != null) {
spatial.setUserData("tags.env.env" + uuid, true);
spatial.setUserData(sourceTag, null);
}
}
}

/**
Expand All @@ -211,11 +240,47 @@ public boolean isRequiredSavableResults() {
return requiredSavableResults;
}

/**
* Sets how spherical harmonics coefficients are baked by this control.
*
* @param mode the spherical harmonics bake mode
*/
public void setSphericalHarmonicsMode(IBLGLEnvBakerLight.SphericalHarmonicsMode mode) {
if (mode == null) {
throw new IllegalArgumentException("mode cannot be null");
}
sphericalHarmonicsMode = mode;
}

/**
* Returns the spherical harmonics bake mode used by this control.
*
* @return the spherical harmonics bake mode
*/
public IBLGLEnvBakerLight.SphericalHarmonicsMode getSphericalHarmonicsMode() {
return sphericalHarmonicsMode;
}

/**
* Enables or disables the spherical harmonics fast path explicitly.
*
* @param enabled true to use the fast path, false to use the quality path
*/
public void setSphericalHarmonicsFastPathEnabled(boolean enabled) {
setSphericalHarmonicsMode(enabled
? IBLGLEnvBakerLight.SphericalHarmonicsMode.FAST
: IBLGLEnvBakerLight.SphericalHarmonicsMode.QUALITY);
}

@Override
public void setSpatial(Spatial spatial) {
if (this.spatial != null && spatial != null && spatial != this.spatial) {
throw new IllegalStateException("This control has already been added to a Spatial");
}
if (spatial == null && baker != null) {
baker.clean();
baker = null;
}
this.spatial = spatial;
if (spatial != null) spatial.addLight(this);
}
Expand All @@ -230,7 +295,12 @@ public void render(RenderManager rm, ViewPort vp) {
if (!isEnabled()) return;
if (bakeNeeded) {
bakeNeeded = false;
rebakeNow(rm);
try {
rebakeNow(rm);
} finally {
rm.getRenderer().setFrameBuffer(vp.getOutputFrameBuffer());
rm.setCamera(vp.getCamera(), false);
}
}
}

Expand Down Expand Up @@ -284,11 +354,23 @@ public float getFrustumFar() {
*/
public void setAssetManager(AssetManager assetManager) {
this.assetManager = assetManager;
if (baker != null) {
baker.clean();
baker = null;
}
}

private IBLGLEnvBakerLight getBaker(RenderManager renderManager) {
if (baker == null) {
baker = new IBLGLEnvBakerLight(renderManager, assetManager, null,
null, envMapSize, envMapSize);
}
return baker;
}

void rebakeNow(RenderManager renderManager) {
IBLHybridEnvBakerLight baker = new IBLGLEnvBakerLight(renderManager, assetManager, null,
null, envMapSize, envMapSize);
IBLGLEnvBakerLight baker = getBaker(renderManager);
baker.setSphericalHarmonicsMode(sphericalHarmonicsMode);

baker.setTexturePulling(isRequiredSavableResults());
baker.bakeEnvironment(spatial, getPosition(), frustumNear, frustumFar, filter);
Expand All @@ -303,8 +385,6 @@ void rebakeNow(RenderManager renderManager) {
setShCoeffs(baker.getSphericalHarmonicsCoefficients());
setPosition(Vector3f.ZERO);
setReady(true);

baker.clean();
}

public void setEnabled(boolean enabled) {
Expand All @@ -331,6 +411,8 @@ public void write(JmeExporter ex) throws IOException {
oc.write(frustumFar, "frustumFar", 1000f);
oc.write(frustumNear, "frustumNear", 0.001f);
oc.write(uuid, "envProbeControlUUID", "none");
oc.write(sphericalHarmonicsMode, "sphericalHarmonicsMode",
IBLGLEnvBakerLight.SphericalHarmonicsMode.AUTO);
}

@Override
Expand All @@ -346,6 +428,9 @@ public void read(JmeImporter im) throws IOException {
frustumFar = ic.readFloat("frustumFar", 1000f);
frustumNear = ic.readFloat("frustumNear", 0.001f);
uuid = ic.readString("envProbeControlUUID", "none");
sphericalHarmonicsMode = ic.readEnum("sphericalHarmonicsMode",
IBLGLEnvBakerLight.SphericalHarmonicsMode.class,
IBLGLEnvBakerLight.SphericalHarmonicsMode.AUTO);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ public abstract class GenericEnvBaker implements EnvBaker {
protected final Camera cam;
protected boolean texturePulling = false;
protected List<ByteArrayOutputStream> bos = new ArrayList<>();
private FrameBuffer[] envBakers;

protected GenericEnvBaker(RenderManager rm, AssetManager am, Format colorFormat, Format depthFormat, int env_size) {
this.depthFormat = depthFormat;
Expand Down Expand Up @@ -178,18 +179,35 @@ protected Camera updateAndGetInternalCamera(int faceId, int w, int h, Vector3f p

@Override
public void clean() {
if (envBakers != null) {
for (FrameBuffer envBaker : envBakers) {
if (envBaker != null) {
envBaker.dispose();
}
}
envBakers = null;
}

}

@Override
public void bakeEnvironment(Spatial scene, Vector3f position, float frustumNear, float frustumFar, Predicate<Geometry> filter) {
FrameBuffer envbakers[] = new FrameBuffer[6];
private FrameBuffer[] getEnvBakers() {
if (envBakers != null) {
return envBakers;
}

envBakers = new FrameBuffer[6];
for (int i = 0; i < 6; i++) {
envbakers[i] = new FrameBuffer(envMap.getImage().getWidth(), envMap.getImage().getHeight(), 1);
envbakers[i].setDepthTarget(FrameBufferTarget.newTarget(getDepthFormat()));
envbakers[i].setSrgb(false);
envbakers[i].addColorTarget(FrameBufferTarget.newTarget(envMap).face(TextureCubeMap.Face.values()[i]));
envBakers[i] = new FrameBuffer(envMap.getImage().getWidth(), envMap.getImage().getHeight(), 1);
envBakers[i].setDepthTarget(FrameBufferTarget.newTarget(getDepthFormat()));
envBakers[i].setSrgb(false);
envBakers[i].addColorTarget(FrameBufferTarget.newTarget(envMap).face(TextureCubeMap.Face.values()[i]));
}
return envBakers;
}

@Override
public void bakeEnvironment(Spatial scene, Vector3f position, float frustumNear, float frustumFar, Predicate<Geometry> filter) {
FrameBuffer envbakers[] = getEnvBakers();

if (isTexturePulling()) {
startPulling();
Expand All @@ -212,8 +230,11 @@ public void bakeEnvironment(Spatial scene, Vector3f position, float frustumNear,
Predicate<Geometry> ofilter = renderManager.getRenderFilter();

renderManager.setRenderFilter(filter);
renderManager.renderViewPort(viewPort, 0.16f);
renderManager.setRenderFilter(ofilter);
try {
renderManager.renderViewPort(viewPort, 0.16f);
} finally {
renderManager.setRenderFilter(ofilter);
}

if (isTexturePulling()) {
pull(envbaker, envMap, i);
Expand All @@ -226,10 +247,6 @@ public void bakeEnvironment(Spatial scene, Vector3f position, float frustumNear,
}

envMap.getImage().clearUpdateNeeded();

for (int i = 0; i < 6; i++) {
envbakers[i].dispose();
}
}

/**
Expand Down
Loading
Loading