You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
224 lines
8.4 KiB
224 lines
8.4 KiB
8 years ago
|
package com.jme3.util;
|
||
|
|
||
|
import com.jme3.app.VREnvironment;
|
||
|
import com.jme3.post.CartoonSSAO;
|
||
|
import com.jme3.post.Filter;
|
||
|
import com.jme3.post.FilterPostProcessor;
|
||
|
import com.jme3.post.FilterUtil;
|
||
|
import com.jme3.post.SceneProcessor;
|
||
|
import com.jme3.post.filters.FogFilter;
|
||
|
import com.jme3.post.filters.TranslucentBucketFilter;
|
||
|
import com.jme3.post.ssao.SSAOFilter;
|
||
|
import com.jme3.renderer.Camera;
|
||
|
import com.jme3.renderer.ViewPort;
|
||
|
import com.jme3.shadow.DirectionalLightShadowFilter;
|
||
|
import com.jme3.shadow.VRDirectionalLightShadowRenderer;
|
||
|
import com.jme3.texture.Texture2D;
|
||
|
|
||
|
/**
|
||
|
* A VR view manager. This class holds methods that enable to submit 3D views to the VR compositor.
|
||
|
* System dependent classes should extends from this one.
|
||
|
* @author Julien Seinturier - (c) 2016 - JOrigin project - <a href="http://www.jorigin.org">http:/www.jorigin.org</a>
|
||
|
*/
|
||
|
public abstract class AbstractVRViewManager implements VRViewManager {
|
||
|
|
||
|
|
||
|
//private static final Logger logger = Logger.getLogger(AbstractVRViewManager.class.getName());
|
||
|
|
||
|
protected VREnvironment environment = null;
|
||
|
|
||
|
protected Camera leftCamera;
|
||
|
protected ViewPort leftViewport;
|
||
|
protected FilterPostProcessor leftPostProcessor;
|
||
|
protected Texture2D leftEyeTexture;
|
||
|
protected Texture2D leftEyeDepth;
|
||
|
|
||
|
protected Camera rightCamera;
|
||
|
protected ViewPort rightViewport;
|
||
|
protected FilterPostProcessor rightPostProcessor;
|
||
|
protected Texture2D rightEyeTexture;
|
||
|
protected Texture2D rightEyeDepth;
|
||
|
|
||
|
private float resMult = 1f;
|
||
|
|
||
|
private float heightAdjustment;
|
||
|
|
||
|
@Override
|
||
|
public Camera getLeftCamera() {
|
||
|
return leftCamera;
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public Camera getRightCamera() {
|
||
|
return rightCamera;
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public ViewPort getLeftViewport() {
|
||
|
return leftViewport;
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public ViewPort getRightViewport() {
|
||
|
return rightViewport;
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public Texture2D getLeftTexture(){
|
||
|
return leftEyeTexture;
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public Texture2D getRightTexture(){
|
||
|
return rightEyeTexture;
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public Texture2D getLeftDepth(){
|
||
|
return leftEyeDepth;
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public Texture2D getRightDepth(){
|
||
|
return rightEyeDepth;
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public FilterPostProcessor getLeftPostProcessor(){
|
||
|
return leftPostProcessor;
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public FilterPostProcessor getRightPostProcessor(){
|
||
|
return rightPostProcessor;
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public float getResolutionMuliplier() {
|
||
|
return resMult;
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public void setResolutionMultiplier(float resMult) {
|
||
|
this.resMult = resMult;
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public float getHeightAdjustment() {
|
||
|
return heightAdjustment;
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public void setHeightAdjustment(float amount) {
|
||
|
heightAdjustment = amount;
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public VREnvironment getVREnvironment(){
|
||
|
return environment;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Handles moving filters from the main view to each eye
|
||
|
*/
|
||
|
public void moveScreenProcessingToEyes() {
|
||
|
|
||
|
if (environment != null){
|
||
|
if( getRightViewport() == null ){
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if (environment.getApplication() != null){
|
||
|
syncScreenProcessing(environment.getApplication().getViewPort());
|
||
|
environment.getApplication().getViewPort().clearProcessors();
|
||
|
} else {
|
||
|
throw new IllegalStateException("The VR environment is not attached to any application.");
|
||
|
}
|
||
|
|
||
|
|
||
|
} else {
|
||
|
throw new IllegalStateException("This VR view manager is not attached to any VR environment.");
|
||
|
}
|
||
|
|
||
|
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Sets the two views to use the list of {@link SceneProcessor processors}.
|
||
|
* @param sourceViewport the {@link ViewPort viewport} that contains the processors to use.
|
||
|
*/
|
||
|
public void syncScreenProcessing(ViewPort sourceViewport) {
|
||
|
|
||
|
if (environment != null){
|
||
|
if( getRightViewport() == null ){
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if (environment.getApplication() != null){
|
||
|
// setup post processing filters
|
||
|
if( getRightPostProcessor() == null ) {
|
||
|
rightPostProcessor = new FilterPostProcessor(environment.getApplication().getAssetManager());
|
||
|
leftPostProcessor = new FilterPostProcessor(environment.getApplication().getAssetManager());
|
||
|
}
|
||
|
// clear out all filters & processors, to start from scratch
|
||
|
getRightPostProcessor().removeAllFilters();
|
||
|
getLeftPostProcessor().removeAllFilters();
|
||
|
getLeftViewport().clearProcessors();
|
||
|
getRightViewport().clearProcessors();
|
||
|
// if we have no processors to sync, don't add the FilterPostProcessor
|
||
|
if( sourceViewport.getProcessors().isEmpty() ) return;
|
||
|
// add post processors we just made, which are empty
|
||
|
getLeftViewport().addProcessor(getLeftPostProcessor());
|
||
|
getRightViewport().addProcessor(getRightPostProcessor());
|
||
|
// go through all of the filters in the processors list
|
||
|
// add them to the left viewport processor & clone them to the right
|
||
|
for(SceneProcessor sceneProcessor : sourceViewport.getProcessors()) {
|
||
|
if (sceneProcessor instanceof FilterPostProcessor) {
|
||
|
for(Filter f : ((FilterPostProcessor)sceneProcessor).getFilterList() ) {
|
||
|
if( f instanceof TranslucentBucketFilter ) {
|
||
|
// just remove this filter, we will add it at the end manually
|
||
|
((FilterPostProcessor)sceneProcessor).removeFilter(f);
|
||
|
} else {
|
||
|
getLeftPostProcessor().addFilter(f);
|
||
|
// clone to the right
|
||
|
Filter f2;
|
||
|
if(f instanceof FogFilter){
|
||
|
f2 = FilterUtil.cloneFogFilter((FogFilter)f);
|
||
|
} else if (f instanceof CartoonSSAO ) {
|
||
|
f2 = new CartoonSSAO((CartoonSSAO)f);
|
||
|
} else if (f instanceof SSAOFilter){
|
||
|
f2 = FilterUtil.cloneSSAOFilter((SSAOFilter)f);
|
||
|
} else if (f instanceof DirectionalLightShadowFilter){
|
||
|
f2 = FilterUtil.cloneDirectionalLightShadowFilter(environment.getApplication().getAssetManager(), (DirectionalLightShadowFilter)f);
|
||
|
} else {
|
||
|
f2 = f; // dof, bloom, lightscattering etc.
|
||
|
}
|
||
|
getRightPostProcessor().addFilter(f2);
|
||
|
}
|
||
|
}
|
||
|
} else if (sceneProcessor instanceof VRDirectionalLightShadowRenderer) {
|
||
|
// shadow processing
|
||
|
// TODO: make right shadow processor use same left shadow maps for performance
|
||
|
VRDirectionalLightShadowRenderer dlsr = (VRDirectionalLightShadowRenderer) sceneProcessor;
|
||
|
VRDirectionalLightShadowRenderer dlsrRight = dlsr.clone();
|
||
|
dlsrRight.setLight(dlsr.getLight());
|
||
|
getRightViewport().getProcessors().add(0, dlsrRight);
|
||
|
getLeftViewport().getProcessors().add(0, sceneProcessor);
|
||
|
}
|
||
|
}
|
||
|
// make sure each has a translucent filter renderer
|
||
|
getLeftPostProcessor().addFilter(new TranslucentBucketFilter());
|
||
|
getRightPostProcessor().addFilter(new TranslucentBucketFilter());
|
||
|
} else {
|
||
|
throw new IllegalStateException("The VR environment is not attached to any application.");
|
||
|
}
|
||
|
|
||
|
|
||
|
} else {
|
||
|
throw new IllegalStateException("This VR view manager is not attached to any VR environment.");
|
||
|
}
|
||
|
|
||
|
|
||
|
}
|
||
|
}
|