|
@@ -113,14 +113,13 @@
|
|
|
|
|
|
public _cameraRigParams: any;
|
|
public _cameraRigParams: any;
|
|
public _rigCameras = new Array<Camera>();
|
|
public _rigCameras = new Array<Camera>();
|
|
-
|
|
|
|
|
|
+ public _rigPostProcess : PostProcess;
|
|
|
|
|
|
// Cache
|
|
// Cache
|
|
private _computedViewMatrix = Matrix.Identity();
|
|
private _computedViewMatrix = Matrix.Identity();
|
|
public _projectionMatrix = new Matrix();
|
|
public _projectionMatrix = new Matrix();
|
|
private _worldMatrix: Matrix;
|
|
private _worldMatrix: Matrix;
|
|
public _postProcesses = new Array<PostProcess>();
|
|
public _postProcesses = new Array<PostProcess>();
|
|
- public _postProcessesTakenIndices = [];
|
|
|
|
|
|
|
|
public _activeMeshes = new SmartArray<Mesh>(256);
|
|
public _activeMeshes = new SmartArray<Mesh>(256);
|
|
|
|
|
|
@@ -275,95 +274,72 @@
|
|
|
|
|
|
public _checkInputs(): void {
|
|
public _checkInputs(): void {
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ private _cascadePostProcessesToRigCams() : void {
|
|
|
|
+ // invalidate framebuffer
|
|
|
|
+ if (this._postProcesses.length > 0){
|
|
|
|
+ this._postProcesses[0].markTextureDirty();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // glue the rigPostProcess to the end of the user postprocesses & assign to each sub-camera
|
|
|
|
+ for(var i = 0, len = this._rigCameras.length; i < len; i++){
|
|
|
|
+ var cam = this._rigCameras[i];
|
|
|
|
+ var rigPostProcess = cam._rigPostProcess;
|
|
|
|
+
|
|
|
|
+ // for VR rig, there does not have to be a post process
|
|
|
|
+ if (rigPostProcess){
|
|
|
|
+ var isPass = rigPostProcess instanceof PassPostProcess;
|
|
|
|
+ if (isPass){
|
|
|
|
+ // any rig which has a PassPostProcess for rig[0], cannot be isIntermediate when there are also user postProcesses
|
|
|
|
+ cam.isIntermediate = this._postProcesses.length === 0;
|
|
|
|
+ }
|
|
|
|
+ cam._postProcesses = this._postProcesses.slice(0).concat(rigPostProcess);
|
|
|
|
+ rigPostProcess.markTextureDirty();
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
|
|
public attachPostProcess(postProcess: PostProcess, insertAt: number = null): number {
|
|
public attachPostProcess(postProcess: PostProcess, insertAt: number = null): number {
|
|
if (!postProcess.isReusable() && this._postProcesses.indexOf(postProcess) > -1) {
|
|
if (!postProcess.isReusable() && this._postProcesses.indexOf(postProcess) > -1) {
|
|
Tools.Error("You're trying to reuse a post process not defined as reusable.");
|
|
Tools.Error("You're trying to reuse a post process not defined as reusable.");
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
if (insertAt == null || insertAt < 0) {
|
|
if (insertAt == null || insertAt < 0) {
|
|
this._postProcesses.push(postProcess);
|
|
this._postProcesses.push(postProcess);
|
|
- this._postProcessesTakenIndices.push(this._postProcesses.length - 1);
|
|
|
|
-
|
|
|
|
- return this._postProcesses.length - 1;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- var add = 0;
|
|
|
|
- var i: number;
|
|
|
|
- var start: number;
|
|
|
|
- if (this._postProcesses[insertAt]) {
|
|
|
|
- start = this._postProcesses.length - 1;
|
|
|
|
- for (i = start; i >= insertAt + 1; --i) {
|
|
|
|
- this._postProcesses[i + 1] = this._postProcesses[i];
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- add = 1;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- for (i = 0; i < this._postProcessesTakenIndices.length; ++i) {
|
|
|
|
- if (this._postProcessesTakenIndices[i] < insertAt) {
|
|
|
|
- continue;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- start = this._postProcessesTakenIndices.length - 1;
|
|
|
|
- for (var j = start; j >= i; --j) {
|
|
|
|
- this._postProcessesTakenIndices[j + 1] = this._postProcessesTakenIndices[j] + add;
|
|
|
|
- }
|
|
|
|
- this._postProcessesTakenIndices[i] = insertAt;
|
|
|
|
- break;
|
|
|
|
|
|
+
|
|
|
|
+ }else{
|
|
|
|
+ this._postProcesses.splice(insertAt, 0, postProcess);
|
|
}
|
|
}
|
|
-
|
|
|
|
- if (!add && this._postProcessesTakenIndices.indexOf(insertAt) === -1) {
|
|
|
|
- this._postProcessesTakenIndices.push(insertAt);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- var result = insertAt + add;
|
|
|
|
-
|
|
|
|
- this._postProcesses[result] = postProcess;
|
|
|
|
-
|
|
|
|
- return result;
|
|
|
|
|
|
+ this._cascadePostProcessesToRigCams(); // also ensures framebuffer invalidated
|
|
|
|
+ return this._postProcesses.indexOf(postProcess);
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
public detachPostProcess(postProcess: PostProcess, atIndices: any = null): number[] {
|
|
public detachPostProcess(postProcess: PostProcess, atIndices: any = null): number[] {
|
|
var result = [];
|
|
var result = [];
|
|
var i: number;
|
|
var i: number;
|
|
var index: number;
|
|
var index: number;
|
|
- if (!atIndices) {
|
|
|
|
-
|
|
|
|
- var length = this._postProcesses.length;
|
|
|
|
|
|
|
|
- for (i = 0; i < length; i++) {
|
|
|
|
-
|
|
|
|
- if (this._postProcesses[i] !== postProcess) {
|
|
|
|
- continue;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- delete this._postProcesses[i];
|
|
|
|
- index = this._postProcessesTakenIndices.indexOf(i);
|
|
|
|
- this._postProcessesTakenIndices.splice(index, 1);
|
|
|
|
|
|
+ if (!atIndices) {
|
|
|
|
+ var idx = this._postProcesses.indexOf(postProcess);
|
|
|
|
+ if (idx !== -1){
|
|
|
|
+ this._postProcesses.splice(idx, 1);
|
|
}
|
|
}
|
|
-
|
|
|
|
- }
|
|
|
|
- else {
|
|
|
|
|
|
+ } else {
|
|
atIndices = (atIndices instanceof Array) ? atIndices : [atIndices];
|
|
atIndices = (atIndices instanceof Array) ? atIndices : [atIndices];
|
|
- for (i = 0; i < atIndices.length; i++) {
|
|
|
|
- var foundPostProcess = this._postProcesses[atIndices[i]];
|
|
|
|
-
|
|
|
|
- if (foundPostProcess !== postProcess) {
|
|
|
|
|
|
+ // iterate descending, so can just splice as we go
|
|
|
|
+ for (i = atIndices.length - 1; i >= 0; i--) {
|
|
|
|
+ if ( this._postProcesses[atIndices[i]] !== postProcess) {
|
|
result.push(i);
|
|
result.push(i);
|
|
continue;
|
|
continue;
|
|
}
|
|
}
|
|
-
|
|
|
|
- delete this._postProcesses[atIndices[i]];
|
|
|
|
-
|
|
|
|
- index = this._postProcessesTakenIndices.indexOf(atIndices[i]);
|
|
|
|
- this._postProcessesTakenIndices.splice(index, 1);
|
|
|
|
|
|
+ this._postProcesses.splice(index, 1);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
+ this._cascadePostProcessesToRigCams(); // also ensures framebuffer invalidated
|
|
return result;
|
|
return result;
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
public getWorldMatrix(): Matrix {
|
|
public getWorldMatrix(): Matrix {
|
|
if (!this._worldMatrix) {
|
|
if (!this._worldMatrix) {
|
|
this._worldMatrix = Matrix.Identity();
|
|
this._worldMatrix = Matrix.Identity();
|
|
@@ -452,8 +428,8 @@
|
|
}
|
|
}
|
|
|
|
|
|
// Postprocesses
|
|
// Postprocesses
|
|
- for (var i = 0; i < this._postProcessesTakenIndices.length; ++i) {
|
|
|
|
- this._postProcesses[this._postProcessesTakenIndices[i]].dispose(this);
|
|
|
|
|
|
+ for (var i = 0; i < this._postProcesses.length; ++i) {
|
|
|
|
+ this._postProcesses[i].dispose(this);
|
|
}
|
|
}
|
|
|
|
|
|
super.dispose();
|
|
super.dispose();
|
|
@@ -466,82 +442,57 @@
|
|
}
|
|
}
|
|
this.cameraRigMode = mode;
|
|
this.cameraRigMode = mode;
|
|
this._cameraRigParams = {};
|
|
this._cameraRigParams = {};
|
|
|
|
+ //we have to implement stereo camera calcultating left and right viewpoints from interaxialDistance and target,
|
|
|
|
+ //not from a given angle as it is now, but until that complete code rewriting provisional stereoHalfAngle value is introduced
|
|
|
|
+ this._cameraRigParams.interaxialDistance = rigParams.interaxialDistance || 0.0637;
|
|
|
|
+ this._cameraRigParams.stereoHalfAngle = BABYLON.Tools.ToRadians(this._cameraRigParams.interaxialDistance / 0.0637);
|
|
|
|
|
|
- switch (this.cameraRigMode) {
|
|
|
|
- case Camera.RIG_MODE_STEREOSCOPIC_ANAGLYPH:
|
|
|
|
- case Camera.RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_PARALLEL:
|
|
|
|
- case Camera.RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_CROSSEYED:
|
|
|
|
- case Camera.RIG_MODE_STEREOSCOPIC_OVERUNDER:
|
|
|
|
- this._cameraRigParams.interaxialDistance = rigParams.interaxialDistance || 0.0637;
|
|
|
|
- //we have to implement stereo camera calcultating left and right viewpoints from interaxialDistance and target,
|
|
|
|
- //not from a given angle as it is now, but until that complete code rewriting provisional stereoHalfAngle value is introduced
|
|
|
|
- this._cameraRigParams.stereoHalfAngle = Tools.ToRadians(this._cameraRigParams.interaxialDistance / 0.0637);
|
|
|
|
-
|
|
|
|
- this._rigCameras.push(this.createRigCamera(this.name + "_L", 0));
|
|
|
|
- this._rigCameras.push(this.createRigCamera(this.name + "_R", 1));
|
|
|
|
- break;
|
|
|
|
|
|
+ // create the rig cameras, unless none
|
|
|
|
+ if (this.cameraRigMode !== Camera.RIG_MODE_NONE){
|
|
|
|
+ this._rigCameras.push(this.createRigCamera(this.name + "_L", 0));
|
|
|
|
+ this._rigCameras.push(this.createRigCamera(this.name + "_R", 1));
|
|
}
|
|
}
|
|
|
|
|
|
- var postProcesses = new Array<PostProcess>();
|
|
|
|
-
|
|
|
|
switch (this.cameraRigMode) {
|
|
switch (this.cameraRigMode) {
|
|
case Camera.RIG_MODE_STEREOSCOPIC_ANAGLYPH:
|
|
case Camera.RIG_MODE_STEREOSCOPIC_ANAGLYPH:
|
|
- postProcesses.push(new PassPostProcess(this.name + "_passthru", 1.0, this._rigCameras[0]));
|
|
|
|
- this._rigCameras[0].isIntermediate = true;
|
|
|
|
-
|
|
|
|
- postProcesses.push(new AnaglyphPostProcess(this.name + "_anaglyph", 1.0, this._rigCameras[1]));
|
|
|
|
- postProcesses[1].onApply = effect => {
|
|
|
|
- effect.setTextureFromPostProcess("leftSampler", postProcesses[0]);
|
|
|
|
- };
|
|
|
|
|
|
+ this._rigCameras[0]._rigPostProcess = new PassPostProcess(this.name + "_passthru", 1.0, this._rigCameras[0]);
|
|
|
|
+ this._rigCameras[1]._rigPostProcess = new AnaglyphPostProcess(this.name + "_anaglyph", 1.0, this._rigCameras);
|
|
break;
|
|
break;
|
|
|
|
|
|
case Camera.RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_PARALLEL:
|
|
case Camera.RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_PARALLEL:
|
|
case Camera.RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_CROSSEYED:
|
|
case Camera.RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_CROSSEYED:
|
|
case Camera.RIG_MODE_STEREOSCOPIC_OVERUNDER:
|
|
case Camera.RIG_MODE_STEREOSCOPIC_OVERUNDER:
|
|
- var isStereoscopicHoriz = (this.cameraRigMode === Camera.RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_PARALLEL || this.cameraRigMode === Camera.RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_CROSSEYED);
|
|
|
|
- var firstCamIndex = (this.cameraRigMode === Camera.RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_CROSSEYED) ? 1 : 0;
|
|
|
|
- var secondCamIndex = 1 - firstCamIndex;
|
|
|
|
-
|
|
|
|
- postProcesses.push(new PassPostProcess(this.name + "_passthru", 1.0, this._rigCameras[firstCamIndex]));
|
|
|
|
- this._rigCameras[firstCamIndex].isIntermediate = true;
|
|
|
|
-
|
|
|
|
- postProcesses.push(new StereoscopicInterlacePostProcess(this.name + "_stereoInterlace", this._rigCameras[secondCamIndex], postProcesses[0], isStereoscopicHoriz));
|
|
|
|
|
|
+ var isStereoscopicHoriz = this.cameraRigMode === Camera.RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_PARALLEL || this.cameraRigMode === Camera.RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_CROSSEYED;
|
|
|
|
+
|
|
|
|
+ this._rigCameras[0]._rigPostProcess = new PassPostProcess(this.name + "_passthru", 1.0, this._rigCameras[0]);
|
|
|
|
+ this._rigCameras[1]._rigPostProcess = new StereoscopicInterlacePostProcess(this.name + "_stereoInterlace", this._rigCameras, isStereoscopicHoriz);
|
|
break;
|
|
break;
|
|
|
|
|
|
case Camera.RIG_MODE_VR:
|
|
case Camera.RIG_MODE_VR:
|
|
- this._cameraRigParams.interaxialDistance = rigParams.interaxialDistance || 0.0637;
|
|
|
|
- this._cameraRigParams.stereoHalfAngle = BABYLON.Tools.ToRadians(this._cameraRigParams.interaxialDistance / 0.0637);
|
|
|
|
-
|
|
|
|
- this._rigCameras.push(this.createRigCamera(this.name + "_L", 0));
|
|
|
|
- this._rigCameras.push(this.createRigCamera(this.name + "_R", 1));
|
|
|
|
-
|
|
|
|
var metrics = rigParams.vrCameraMetrics || VRCameraMetrics.GetDefault();
|
|
var metrics = rigParams.vrCameraMetrics || VRCameraMetrics.GetDefault();
|
|
|
|
+
|
|
this._rigCameras[0]._cameraRigParams.vrMetrics = metrics;
|
|
this._rigCameras[0]._cameraRigParams.vrMetrics = metrics;
|
|
this._rigCameras[0].viewport = new Viewport(0, 0, 0.5, 1.0);
|
|
this._rigCameras[0].viewport = new Viewport(0, 0, 0.5, 1.0);
|
|
this._rigCameras[0]._cameraRigParams.vrWorkMatrix = new Matrix();
|
|
this._rigCameras[0]._cameraRigParams.vrWorkMatrix = new Matrix();
|
|
-
|
|
|
|
this._rigCameras[0]._cameraRigParams.vrHMatrix = metrics.leftHMatrix;
|
|
this._rigCameras[0]._cameraRigParams.vrHMatrix = metrics.leftHMatrix;
|
|
this._rigCameras[0]._cameraRigParams.vrPreViewMatrix = metrics.leftPreViewMatrix;
|
|
this._rigCameras[0]._cameraRigParams.vrPreViewMatrix = metrics.leftPreViewMatrix;
|
|
this._rigCameras[0].getProjectionMatrix = this._rigCameras[0]._getVRProjectionMatrix;
|
|
this._rigCameras[0].getProjectionMatrix = this._rigCameras[0]._getVRProjectionMatrix;
|
|
|
|
|
|
- if (metrics.compensateDistortion) {
|
|
|
|
- postProcesses.push(new VRDistortionCorrectionPostProcess("VR_Distort_Compensation_Left", this._rigCameras[0], false, metrics));
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- this._rigCameras[1]._cameraRigParams.vrMetrics = this._rigCameras[0]._cameraRigParams.vrMetrics;
|
|
|
|
|
|
+ this._rigCameras[1]._cameraRigParams.vrMetrics = metrics;
|
|
this._rigCameras[1].viewport = new Viewport(0.5, 0, 0.5, 1.0);
|
|
this._rigCameras[1].viewport = new Viewport(0.5, 0, 0.5, 1.0);
|
|
this._rigCameras[1]._cameraRigParams.vrWorkMatrix = new Matrix();
|
|
this._rigCameras[1]._cameraRigParams.vrWorkMatrix = new Matrix();
|
|
this._rigCameras[1]._cameraRigParams.vrHMatrix = metrics.rightHMatrix;
|
|
this._rigCameras[1]._cameraRigParams.vrHMatrix = metrics.rightHMatrix;
|
|
this._rigCameras[1]._cameraRigParams.vrPreViewMatrix = metrics.rightPreViewMatrix;
|
|
this._rigCameras[1]._cameraRigParams.vrPreViewMatrix = metrics.rightPreViewMatrix;
|
|
-
|
|
|
|
this._rigCameras[1].getProjectionMatrix = this._rigCameras[1]._getVRProjectionMatrix;
|
|
this._rigCameras[1].getProjectionMatrix = this._rigCameras[1]._getVRProjectionMatrix;
|
|
|
|
|
|
if (metrics.compensateDistortion) {
|
|
if (metrics.compensateDistortion) {
|
|
- postProcesses.push(new VRDistortionCorrectionPostProcess("VR_Distort_Compensation_Right", this._rigCameras[1], true, metrics));
|
|
|
|
|
|
+ this._rigCameras[0]._rigPostProcess = new VRDistortionCorrectionPostProcess("VR_Distort_Compensation_Left", this._rigCameras[0], false, metrics);
|
|
|
|
+ this._rigCameras[1]._rigPostProcess = new VRDistortionCorrectionPostProcess("VR_Distort_Compensation_Right", this._rigCameras[1], true, metrics);
|
|
}
|
|
}
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ this._cascadePostProcessesToRigCams();
|
|
this._update();
|
|
this._update();
|
|
}
|
|
}
|
|
|
|
|
|
@@ -552,6 +503,9 @@
|
|
}
|
|
}
|
|
|
|
|
|
public setCameraRigParameter(name: string, value: any) {
|
|
public setCameraRigParameter(name: string, value: any) {
|
|
|
|
+ if (!this._cameraRigParams){
|
|
|
|
+ this._cameraRigParams = {};
|
|
|
|
+ }
|
|
this._cameraRigParams[name] = value;
|
|
this._cameraRigParams[name] = value;
|
|
//provisionnally:
|
|
//provisionnally:
|
|
if (name === "interaxialDistance") {
|
|
if (name === "interaxialDistance") {
|
|
@@ -560,14 +514,14 @@
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
- * May needs to be overridden by children so sub has required properties to be copied
|
|
|
|
|
|
+ * needs to be overridden by children so sub has required properties to be copied
|
|
*/
|
|
*/
|
|
public createRigCamera(name: string, cameraIndex: number): Camera {
|
|
public createRigCamera(name: string, cameraIndex: number): Camera {
|
|
- return null;
|
|
|
|
|
|
+ return null;
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
- * May needs to be overridden by children
|
|
|
|
|
|
+ * May need to be overridden by children
|
|
*/
|
|
*/
|
|
public _updateRigCameras() {
|
|
public _updateRigCameras() {
|
|
for (var i = 0; i < this._rigCameras.length; i++) {
|
|
for (var i = 0; i < this._rigCameras.length; i++) {
|