Skip to content

Commit f5366c8

Browse files
committed
Add ability to set asymmetrical FOV on HMDVRDevice, as well as IPD and viewport.
1 parent ec9c445 commit f5366c8

File tree

2 files changed

+160
-22
lines changed

2 files changed

+160
-22
lines changed

build/webvr-polyfill.js

Lines changed: 79 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -62,36 +62,80 @@ var HMDVRDevice = _dereq_('./base.js').HMDVRDevice;
6262
var DEFAULT_INTERPUPILLARY_DISTANCE = 0.06;
6363
var DEFAULT_FIELD_OF_VIEW = 40;
6464

65+
var Eye = {
66+
LEFT: 'left',
67+
RIGHT: 'right'
68+
};
69+
6570
/**
6671
* The HMD itself, providing rendering parameters.
6772
*/
6873
function CardboardHMDVRDevice() {
6974
// From com/google/vrtoolkit/cardboard/FieldOfView.java.
70-
this.setFieldOfView(DEFAULT_FIELD_OF_VIEW);
75+
this.setMonocularFieldOfView_(DEFAULT_FIELD_OF_VIEW);
7176
// Set display constants.
7277
this.setInterpupillaryDistance(DEFAULT_INTERPUPILLARY_DISTANCE);
7378
}
7479
CardboardHMDVRDevice.prototype = new HMDVRDevice();
7580

7681
CardboardHMDVRDevice.prototype.getEyeParameters = function(whichEye) {
7782
var eyeTranslation;
78-
if (whichEye == 'left') {
83+
var fieldOfView;
84+
var renderRect;
85+
86+
if (whichEye == Eye.LEFT) {
7987
eyeTranslation = this.eyeTranslationLeft;
80-
} else if (whichEye == 'right') {
88+
fieldOfView = this.fieldOfViewLeft;
89+
renderRect = this.renderRectLeft;
90+
} else if (whichEye == Eye.RIGHT) {
8191
eyeTranslation = this.eyeTranslationRight;
92+
fieldOfView = this.fieldOfViewRight;
93+
renderRect = this.renderRectRight;
8294
} else {
8395
console.error('Invalid eye provided: %s', whichEye);
8496
return null;
8597
}
8698
return {
87-
recommendedFieldOfView: this.fov,
88-
eyeTranslation: eyeTranslation
99+
recommendedFieldOfView: fieldOfView,
100+
eyeTranslation: eyeTranslation,
101+
renderRect: renderRect
89102
};
90103
};
91104

92105
/**
93-
* Sets the IPD (in m) of this device. Useful for initialization and for
94-
* changing viewer parameters dynamically.
106+
* Sets the field of view for both eyes. This is according to WebVR spec:
107+
*
108+
* @param {FieldOfView} opt_fovLeft Field of view of the left eye.
109+
* @param {FieldOfView} opt_fovRight Field of view of the right eye.
110+
* @param {Number} opt_zNear The near plane.
111+
* @param {Number} opt_zFar The far plane.
112+
*
113+
* http://mozvr.github.io/webvr-spec/webvr.html#dom-hmdvrdevice-setfieldofviewleftfov-rightfov-znear-zfar
114+
*/
115+
CardboardHMDVRDevice.prototype.setFieldOfView =
116+
function(opt_fovLeft, opt_fovRight, opt_zNear, opt_zFar) {
117+
if (opt_fovLeft) {
118+
this.fieldOfViewLeft = opt_fovLeft;
119+
}
120+
if (opt_fovRight) {
121+
this.fieldOfViewRight = opt_fovRight;
122+
}
123+
if (opt_zNear) {
124+
this.zNear = opt_zNear;
125+
}
126+
if (opt_zFar) {
127+
this.zFar = opt_zFar;
128+
}
129+
};
130+
131+
132+
/**
133+
* Changes the interpupillary distance of the rendered scene. This is useful for
134+
* changing Cardboard viewers.
135+
*
136+
* Possibly a useful addition to the WebVR spec?
137+
*
138+
* @param {Number} ipd Distance between eyes.
95139
*/
96140
CardboardHMDVRDevice.prototype.setInterpupillaryDistance = function(ipd) {
97141
this.eyeTranslationLeft = {
@@ -106,12 +150,36 @@ CardboardHMDVRDevice.prototype.setInterpupillaryDistance = function(ipd) {
106150
};
107151
};
108152

153+
154+
/**
155+
* Changes the render rect (ie. viewport) where each eye is rendered. Again,
156+
* useful for changing Cardboard viewers.
157+
*
158+
* @param {Rect} opt_rectLeft Viewport for left eye.
159+
* @param {Rect} opt_rectRight Viewport for right eye.
160+
*/
161+
CardboardHMDVRDevice.prototype.setRenderRect = function(opt_rectLeft, opt_rectRight) {
162+
if (opt_rectLeft) {
163+
this.renderRectLeft = opt_rectLeft;
164+
}
165+
if (opt_rectRight) {
166+
this.renderRectRight = opt_rectRight;
167+
}
168+
};
169+
109170
/**
110-
* Sets the FOV (in degrees) of this viewer. Useful for initialization and
111-
* changing viewer parameters dynamically.
171+
* Sets a symmetrical field of view for both eyes, with just one angle.
172+
*
173+
* @param {Number} angle Angle in degrees of left, right, top and bottom for
174+
* both eyes.
112175
*/
113-
CardboardHMDVRDevice.prototype.setFieldOfView = function(angle) {
114-
this.fov = {
176+
CardboardHMDVRDevice.prototype.setMonocularFieldOfView_ = function(angle) {
177+
this.setFieldOfView(this.createSymmetricalFieldOfView_(angle),
178+
this.createSymmetricalFieldOfView_(angle));
179+
};
180+
181+
CardboardHMDVRDevice.prototype.createSymmetricalFieldOfView_ = function(angle) {
182+
return {
115183
upDegrees: angle,
116184
downDegrees: angle,
117185
leftDegrees: angle,

src/cardboard-hmd-vr-device.js

Lines changed: 81 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -18,36 +18,80 @@ var HMDVRDevice = require('./base.js').HMDVRDevice;
1818
var DEFAULT_INTERPUPILLARY_DISTANCE = 0.06;
1919
var DEFAULT_FIELD_OF_VIEW = 40;
2020

21+
var Eye = {
22+
LEFT: 'left',
23+
RIGHT: 'right'
24+
};
25+
2126
/**
2227
* The HMD itself, providing rendering parameters.
2328
*/
2429
function CardboardHMDVRDevice() {
2530
// From com/google/vrtoolkit/cardboard/FieldOfView.java.
26-
this.setFieldOfView(DEFAULT_FIELD_OF_VIEW);
31+
this.setMonocularFieldOfView_(DEFAULT_FIELD_OF_VIEW);
2732
// Set display constants.
2833
this.setInterpupillaryDistance(DEFAULT_INTERPUPILLARY_DISTANCE);
2934
}
3035
CardboardHMDVRDevice.prototype = new HMDVRDevice();
3136

3237
CardboardHMDVRDevice.prototype.getEyeParameters = function(whichEye) {
3338
var eyeTranslation;
34-
if (whichEye == 'left') {
39+
var fieldOfView;
40+
var renderRect;
41+
42+
if (whichEye == Eye.LEFT) {
3543
eyeTranslation = this.eyeTranslationLeft;
36-
} else if (whichEye == 'right') {
44+
fieldOfView = this.fieldOfViewLeft;
45+
renderRect = this.renderRectLeft;
46+
} else if (whichEye == Eye.RIGHT) {
3747
eyeTranslation = this.eyeTranslationRight;
48+
fieldOfView = this.fieldOfViewRight;
49+
renderRect = this.renderRectRight;
3850
} else {
3951
console.error('Invalid eye provided: %s', whichEye);
4052
return null;
4153
}
4254
return {
43-
recommendedFieldOfView: this.fov,
44-
eyeTranslation: eyeTranslation
55+
recommendedFieldOfView: fieldOfView,
56+
eyeTranslation: eyeTranslation,
57+
renderRect: renderRect
4558
};
4659
};
4760

4861
/**
49-
* Sets the IPD (in m) of this device. Useful for initialization and for
50-
* changing viewer parameters dynamically.
62+
* Sets the field of view for both eyes. This is according to WebVR spec:
63+
*
64+
* @param {FieldOfView} opt_fovLeft Field of view of the left eye.
65+
* @param {FieldOfView} opt_fovRight Field of view of the right eye.
66+
* @param {Number} opt_zNear The near plane.
67+
* @param {Number} opt_zFar The far plane.
68+
*
69+
* http://mozvr.github.io/webvr-spec/webvr.html#dom-hmdvrdevice-setfieldofviewleftfov-rightfov-znear-zfar
70+
*/
71+
CardboardHMDVRDevice.prototype.setFieldOfView =
72+
function(opt_fovLeft, opt_fovRight, opt_zNear, opt_zFar) {
73+
if (opt_fovLeft) {
74+
this.fieldOfViewLeft = opt_fovLeft;
75+
}
76+
if (opt_fovRight) {
77+
this.fieldOfViewRight = opt_fovRight;
78+
}
79+
if (opt_zNear) {
80+
this.zNear = opt_zNear;
81+
}
82+
if (opt_zFar) {
83+
this.zFar = opt_zFar;
84+
}
85+
};
86+
87+
88+
/**
89+
* Changes the interpupillary distance of the rendered scene. This is useful for
90+
* changing Cardboard viewers.
91+
*
92+
* Possibly a useful addition to the WebVR spec?
93+
*
94+
* @param {Number} ipd Distance between eyes.
5195
*/
5296
CardboardHMDVRDevice.prototype.setInterpupillaryDistance = function(ipd) {
5397
this.eyeTranslationLeft = {
@@ -62,12 +106,38 @@ CardboardHMDVRDevice.prototype.setInterpupillaryDistance = function(ipd) {
62106
};
63107
};
64108

109+
110+
/**
111+
* Changes the render rect (ie. viewport) where each eye is rendered. This is
112+
* useful for changing Cardboard viewers.
113+
*
114+
* Possibly a useful addition to the WebVR spec?
115+
*
116+
* @param {Rect} opt_rectLeft Viewport for left eye.
117+
* @param {Rect} opt_rectRight Viewport for right eye.
118+
*/
119+
CardboardHMDVRDevice.prototype.setRenderRect = function(opt_rectLeft, opt_rectRight) {
120+
if (opt_rectLeft) {
121+
this.renderRectLeft = opt_rectLeft;
122+
}
123+
if (opt_rectRight) {
124+
this.renderRectRight = opt_rectRight;
125+
}
126+
};
127+
65128
/**
66-
* Sets the FOV (in degrees) of this viewer. Useful for initialization and
67-
* changing viewer parameters dynamically.
129+
* Sets a symmetrical field of view for both eyes, with just one angle.
130+
*
131+
* @param {Number} angle Angle in degrees of left, right, top and bottom for
132+
* both eyes.
68133
*/
69-
CardboardHMDVRDevice.prototype.setFieldOfView = function(angle) {
70-
this.fov = {
134+
CardboardHMDVRDevice.prototype.setMonocularFieldOfView_ = function(angle) {
135+
this.setFieldOfView(this.createSymmetricalFieldOfView_(angle),
136+
this.createSymmetricalFieldOfView_(angle));
137+
};
138+
139+
CardboardHMDVRDevice.prototype.createSymmetricalFieldOfView_ = function(angle) {
140+
return {
71141
upDegrees: angle,
72142
downDegrees: angle,
73143
leftDegrees: angle,

0 commit comments

Comments
 (0)