Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
cn-ray
three.js
提交
1195e0f3
T
three.js
项目概览
cn-ray
/
three.js
与 Fork 源项目一致
从无法访问的项目Fork
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
T
three.js
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
1195e0f3
编写于
3月 30, 2015
作者:
M
Mr.doob
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Refactored VREffect.
/ping @dmarcos @borismus @toji @spite
上级
155a9794
变更
1
隐藏空白更改
内联
并排
Showing
1 changed file
with
155 addition
and
145 deletion
+155
-145
examples/js/effects/VREffect.js
examples/js/effects/VREffect.js
+155
-145
未找到文件。
examples/js/effects/VREffect.js
浏览文件 @
1195e0f3
/**
* @author dmarcos / https://github.com/dmarcos
* @author mrdoob / http://mrdoob.com
*
* It handles stereo rendering
* If mozGetVRDevices and getVRDevices APIs are not available it gracefuly falls back to a
...
...
@@ -22,184 +23,189 @@
*/
THREE
.
VREffect
=
function
(
renderer
,
done
)
{
var
cameraLeft
=
new
THREE
.
PerspectiveCamera
();
var
cameraRight
=
new
THREE
.
PerspectiveCamera
();
if
(
!
navigator
.
mozGetVRDevices
&&
!
navigator
.
getVRDevices
)
{
this
.
_renderer
=
renderer
;
if
(
done
)
done
(
'
Your browser is not VR Ready
'
)
;
this
.
_init
=
function
()
{
var
self
=
this
;
if
(
!
navigator
.
mozGetVRDevices
&&
!
navigator
.
getVRDevices
)
{
if
(
done
)
{
done
(
'
Your browser is not VR Ready
'
);
}
return
;
}
if
(
navigator
.
getVRDevices
)
{
navigator
.
getVRDevices
().
then
(
gotVRDevices
);
}
else
{
navigator
.
mozGetVRDevices
(
gotVRDevices
);
}
function
gotVRDevices
(
devices
)
{
var
vrHMD
;
for
(
var
i
=
0
;
i
<
devices
.
length
;
i
++
)
{
if
(
devices
[
i
]
instanceof
HMDVRDevice
)
{
vrHMD
=
devices
[
i
];
self
.
_vrHMD
=
vrHMD
;
if
(
vrHMD
.
getEyeParameters
!==
undefined
)
{
var
leftEyeParams
=
vrHMD
.
getEyeParameters
(
'
left
'
);
var
rightEyeParams
=
vrHMD
.
getEyeParameters
(
'
right
'
);
self
.
leftEyeTranslation
=
leftEyeParams
.
eyeTranslation
;
self
.
rightEyeTranslation
=
rightEyeParams
.
eyeTranslation
;
self
.
leftEyeFOV
=
leftEyeParams
.
recommendedFieldOfView
;
self
.
rightEyeFOV
=
rightEyeParams
.
recommendedFieldOfView
;
}
else
{
// TODO: This is an older code path and not spec compliant.
// It should be removed at some point in the near future.
self
.
leftEyeTranslation
=
vrHMD
.
getEyeTranslation
(
'
left
'
);
self
.
rightEyeTranslation
=
vrHMD
.
getEyeTranslation
(
'
right
'
);
self
.
leftEyeFOV
=
vrHMD
.
getRecommendedEyeFieldOfView
(
'
left
'
);
self
.
rightEyeFOV
=
vrHMD
.
getRecommendedEyeFieldOfView
(
'
right
'
);
}
break
;
// We keep the first we encounter
}
}
if
(
done
)
{
if
(
!
vrHMD
)
{
done
(
'
HMD not available
'
);
}
}
}
};
}
this
.
_init
();
// init
this
.
render
=
function
(
scene
,
camera
)
{
var
renderer
=
this
.
_renderer
;
var
vrHMD
=
this
.
_vrHMD
;
// VR render mode if HMD is available
if
(
vrHMD
)
{
this
.
renderStereo
.
apply
(
this
,
arguments
);
return
;
}
// Regular render mode if not HMD
if
(
scene
instanceof
Array
)
scene
=
scene
[
0
];
renderer
.
render
.
apply
(
this
.
_renderer
,
arguments
);
};
var
vrHMD
;
var
leftEyeTranslation
,
leftEyeFOV
;
var
rightEyeTranslation
,
rightEyeFOV
;
this
.
renderStereo
=
function
(
scene
,
camera
,
renderTarget
,
forceClear
)
{
function
gotVRDevices
(
devices
)
{
var
sceneLeft
,
sceneRight
;
for
(
var
i
=
0
;
i
<
devices
.
length
;
i
++
)
{
if
(
scene
instanceof
Array
)
{
if
(
devices
[
i
]
instanceof
HMDVRDevice
)
{
sceneLeft
=
scene
[
0
];
sceneRight
=
scene
[
1
];
vrHMD
=
devices
[
i
];
}
else
{
if
(
vrHMD
.
getEyeParameters
!==
undefined
)
{
var
leftEyeParams
=
vrHMD
.
getEyeParameters
(
'
left
'
);
var
rightEyeParams
=
vrHMD
.
getEyeParameters
(
'
right
'
);
leftEyeTranslation
=
leftEyeParams
.
eyeTranslation
;
rightEyeTranslation
=
rightEyeParams
.
eyeTranslation
;
leftEyeFOV
=
leftEyeParams
.
recommendedFieldOfView
;
rightEyeFOV
=
rightEyeParams
.
recommendedFieldOfView
;
}
else
{
// TODO: This is an older code path and not spec compliant.
// It should be removed at some point in the near future.
leftEyeTranslation
=
vrHMD
.
getEyeTranslation
(
'
left
'
);
rightEyeTranslation
=
vrHMD
.
getEyeTranslation
(
'
right
'
);
leftEyeFOV
=
vrHMD
.
getRecommendedEyeFieldOfView
(
'
left
'
);
rightEyeFOV
=
vrHMD
.
getRecommendedEyeFieldOfView
(
'
right
'
);
}
sceneLeft
=
scene
;
sceneRight
=
scene
;
break
;
// We keep the first we encounter
}
}
var
leftEyeTranslation
=
this
.
leftEyeTranslation
;
var
rightEyeTranslation
=
this
.
rightEyeTranslation
;
var
renderer
=
this
.
_renderer
;
var
rendererSize
=
renderer
.
getSize
();
rendererSize
.
width
/=
2
;
if
(
vrHMD
===
undefined
)
{
renderer
.
enableScissorTest
(
true
);
renderer
.
clear
();
if
(
done
)
done
(
'
HMD not available
'
);
if
(
camera
.
parent
===
undefined
)
{
camera
.
updateMatrixWorld
();
}
cameraLeft
.
projectionMatrix
=
this
.
FovToProjection
(
this
.
leftEyeFOV
,
true
,
camera
.
near
,
camera
.
far
);
cameraRight
.
projectionMatrix
=
this
.
FovToProjection
(
this
.
rightEyeFOV
,
true
,
camera
.
near
,
camera
.
far
);
}
camera
.
matrixWorld
.
decompose
(
cameraLeft
.
position
,
cameraLeft
.
quaternion
,
cameraLeft
.
scale
);
camera
.
matrixWorld
.
decompose
(
cameraRight
.
position
,
cameraRight
.
quaternion
,
cameraRight
.
scale
);
if
(
navigator
.
getVRDevices
)
{
cameraLeft
.
translateX
(
leftEyeTranslation
.
x
);
cameraRight
.
translateX
(
rightEyeTranslation
.
x
);
navigator
.
getVRDevices
().
then
(
gotVRDevices
);
// render left eye
renderer
.
setViewport
(
0
,
0
,
rendererSize
.
width
,
rendererSize
.
height
);
renderer
.
setScissor
(
0
,
0
,
rendererSize
.
width
,
rendererSize
.
height
);
renderer
.
render
(
sceneLeft
,
cameraLeft
);
}
else
if
(
navigator
.
mozGetVRDevices
)
{
// render right eye
renderer
.
setViewport
(
rendererSize
.
width
,
0
,
rendererSize
.
width
,
rendererSize
.
height
);
renderer
.
setScissor
(
rendererSize
.
width
,
0
,
rendererSize
.
width
,
rendererSize
.
height
);
renderer
.
render
(
sceneRight
,
cameraRight
);
navigator
.
mozGetVRDevices
(
gotVRDevices
);
renderer
.
enableScissorTest
(
false
);
}
};
//
this
.
setSize
=
function
(
width
,
height
)
{
renderer
.
setSize
(
width
,
height
);
};
this
.
setFullScreen
=
function
(
enable
)
{
var
renderer
=
this
.
_renderer
;
var
vrHMD
=
this
.
_vrHMD
;
var
canvasOriginalSize
=
this
.
_canvasOriginalSize
;
if
(
!
vrHMD
)
{
return
;
}
// If state doesn't change we do nothing
if
(
enable
===
this
.
_fullScreen
)
{
return
;
}
this
.
_fullScreen
=
!!
enable
;
// fullscreen
// VR Mode disabled
if
(
!
enable
)
{
// Restores canvas original size
renderer
.
setSize
(
canvasOriginalSize
.
width
,
canvasOriginalSize
.
height
);
return
;
}
// VR Mode enabled
this
.
_canvasOriginalSize
=
renderer
.
getSize
();
this
.
startFullscreen
();
};
var
isFullscreen
=
false
;
var
canvas
=
renderer
.
domElement
;
var
fullscreenchange
=
canvas
.
mozRequestFullScreen
?
'
mozfullscreenchange
'
:
'
webkitfullscreenchange
'
;
document
.
addEventListener
(
fullscreenchange
,
function
(
event
)
{
isFullscreen
=
document
.
mozFullScreenElement
||
document
.
webkitFullscreenElement
;
},
false
);
this
.
setFullScreen
=
function
(
boolean
)
{
if
(
vrHMD
===
undefined
)
return
;
if
(
isFullscreen
===
boolean
)
return
;
this
.
startFullscreen
=
function
()
{
var
self
=
this
;
var
renderer
=
this
.
_renderer
;
var
vrHMD
=
this
.
_vrHMD
;
var
canvas
=
renderer
.
domElement
;
var
fullScreenChange
=
canvas
.
mozRequestFullScreen
?
'
mozfullscreenchange
'
:
'
webkitfullscreenchange
'
;
document
.
addEventListener
(
fullScreenChange
,
onFullScreenChanged
,
false
);
function
onFullScreenChanged
()
{
if
(
!
document
.
mozFullScreenElement
&&
!
document
.
webkitFullscreenElement
)
{
self
.
setFullScreen
(
false
);
}
}
if
(
canvas
.
mozRequestFullScreen
)
{
canvas
.
mozRequestFullScreen
(
{
vrDisplay
:
vrHMD
}
);
}
else
if
(
canvas
.
webkitRequestFullscreen
)
{
canvas
.
webkitRequestFullscreen
(
{
vrDisplay
:
vrHMD
}
);
}
};
// render
var
cameraLeft
=
new
THREE
.
PerspectiveCamera
();
var
cameraRight
=
new
THREE
.
PerspectiveCamera
();
this
.
render
=
function
(
scene
,
camera
)
{
if
(
vrHMD
)
{
var
sceneLeft
,
sceneRight
;
if
(
scene
instanceof
Array
)
{
sceneLeft
=
scene
[
0
];
sceneRight
=
scene
[
1
];
}
else
{
sceneLeft
=
scene
;
sceneRight
=
scene
;
}
var
size
=
renderer
.
getSize
();
size
.
width
/=
2
;
renderer
.
enableScissorTest
(
true
);
renderer
.
clear
();
if
(
camera
.
parent
===
undefined
)
{
camera
.
updateMatrixWorld
();
}
cameraLeft
.
projectionMatrix
=
fovToProjection
(
leftEyeFOV
,
true
,
camera
.
near
,
camera
.
far
);
cameraRight
.
projectionMatrix
=
fovToProjection
(
rightEyeFOV
,
true
,
camera
.
near
,
camera
.
far
);
camera
.
matrixWorld
.
decompose
(
cameraLeft
.
position
,
cameraLeft
.
quaternion
,
cameraLeft
.
scale
);
camera
.
matrixWorld
.
decompose
(
cameraRight
.
position
,
cameraRight
.
quaternion
,
cameraRight
.
scale
);
cameraLeft
.
translateX
(
leftEyeTranslation
.
x
);
cameraRight
.
translateX
(
rightEyeTranslation
.
x
);
// render left eye
renderer
.
setViewport
(
0
,
0
,
size
.
width
,
size
.
height
);
renderer
.
setScissor
(
0
,
0
,
size
.
width
,
size
.
height
);
renderer
.
render
(
sceneLeft
,
cameraLeft
);
// render right eye
renderer
.
setViewport
(
size
.
width
,
0
,
size
.
width
,
size
.
height
);
renderer
.
setScissor
(
size
.
width
,
0
,
size
.
width
,
size
.
height
);
renderer
.
render
(
sceneRight
,
cameraRight
);
renderer
.
enableScissorTest
(
false
);
return
;
}
// Regular render mode if not HMD
if
(
scene
instanceof
Array
)
scene
=
scene
[
0
];
renderer
.
render
(
scene
,
camera
);
};
this
.
FovToNDCScaleOffset
=
function
(
fov
)
{
//
function
fovToNDCScaleOffset
(
fov
)
{
var
pxscale
=
2.0
/
(
fov
.
leftTan
+
fov
.
rightTan
);
var
pxoffset
=
(
fov
.
leftTan
-
fov
.
rightTan
)
*
pxscale
*
0.5
;
var
pyscale
=
2.0
/
(
fov
.
upTan
+
fov
.
downTan
);
var
pyoffset
=
(
fov
.
upTan
-
fov
.
downTan
)
*
pyscale
*
0.5
;
return
{
scale
:
[
pxscale
,
pyscale
],
offset
:
[
pxoffset
,
pyoffset
]
};
};
this
.
FovPortToProjection
=
function
(
fov
,
rightHanded
/* = true */
,
zNear
/* = 0.01 */
,
zFar
/* = 10000.0 */
)
{
}
function
fovPortToProjection
(
fov
,
rightHanded
,
zNear
,
zFar
)
{
rightHanded
=
rightHanded
===
undefined
?
true
:
rightHanded
;
zNear
=
zNear
===
undefined
?
0.01
:
zNear
;
zFar
=
zFar
===
undefined
?
10000.0
:
zFar
;
...
...
@@ -211,7 +217,7 @@ THREE.VREffect = function ( renderer, done ) {
var
m
=
mobj
.
elements
;
// and with scale/offset info for normalized device coords
var
scaleAndOffset
=
this
.
F
ovToNDCScaleOffset
(
fov
);
var
scaleAndOffset
=
f
ovToNDCScaleOffset
(
fov
);
// X result, map clip edges to [-w,+w]
m
[
0
*
4
+
0
]
=
scaleAndOffset
.
scale
[
0
];
...
...
@@ -242,17 +248,21 @@ THREE.VREffect = function ( renderer, done ) {
mobj
.
transpose
();
return
mobj
;
};
}
function
fovToProjection
(
fov
,
rightHanded
,
zNear
,
zFar
)
{
var
DEG2RAD
=
Math
.
PI
/
180.0
;
this
.
FovToProjection
=
function
(
fov
,
rightHanded
/* = true */
,
zNear
/* = 0.01 */
,
zFar
/* = 10000.0 */
)
{
var
fovPort
=
{
upTan
:
Math
.
tan
(
fov
.
upDegrees
*
Math
.
PI
/
180.0
),
downTan
:
Math
.
tan
(
fov
.
downDegrees
*
Math
.
PI
/
180.0
),
leftTan
:
Math
.
tan
(
fov
.
leftDegrees
*
Math
.
PI
/
180.0
),
rightTan
:
Math
.
tan
(
fov
.
rightDegrees
*
Math
.
PI
/
180.0
)
upTan
:
Math
.
tan
(
fov
.
upDegrees
*
DEG2RAD
),
downTan
:
Math
.
tan
(
fov
.
downDegrees
*
DEG2RAD
),
leftTan
:
Math
.
tan
(
fov
.
leftDegrees
*
DEG2RAD
),
rightTan
:
Math
.
tan
(
fov
.
rightDegrees
*
DEG2RAD
)
};
return
this
.
FovPortToProjection
(
fovPort
,
rightHanded
,
zNear
,
zFar
);
};
return
fovPortToProjection
(
fovPort
,
rightHanded
,
zNear
,
zFar
);
}
};
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录