added webvr support
This commit is contained in:
parent
777df7c274
commit
0a93a37cd0
|
|
@ -0,0 +1,6 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="JavaScriptLibraryMappings">
|
||||||
|
<includedPredefinedLibrary name="ECMAScript 6" />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="JavaScriptSettings">
|
||||||
|
<option name="languageLevel" value="ES6" />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectModuleManager">
|
||||||
|
<modules>
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/.idea/noVNC2.iml" filepath="$PROJECT_DIR$/.idea/noVNC2.iml" />
|
||||||
|
</modules>
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module type="WEB_MODULE" version="4">
|
||||||
|
<component name="NewModuleRootManager">
|
||||||
|
<content url="file://$MODULE_DIR$">
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/.tmp" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/temp" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/tmp" />
|
||||||
|
</content>
|
||||||
|
<orderEntry type="inheritedJdk" />
|
||||||
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
</component>
|
||||||
|
</module>
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="VcsDirectoryMappings">
|
||||||
|
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
|
|
@ -0,0 +1,314 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ChangeListManager">
|
||||||
|
<list default="true" id="1d3b8a90-39a8-4e12-bf3c-191ba9fee294" name="Default" comment="">
|
||||||
|
<change type="NEW" beforePath="" afterPath="$PROJECT_DIR$/.idea/vcs.xml" />
|
||||||
|
<change type="NEW" beforePath="" afterPath="$PROJECT_DIR$/vnc_lite_vr.html" />
|
||||||
|
<change type="MODIFICATION" beforePath="$PROJECT_DIR$/README.md" afterPath="$PROJECT_DIR$/README.md" />
|
||||||
|
</list>
|
||||||
|
<ignored path="$PROJECT_DIR$/.tmp/" />
|
||||||
|
<ignored path="$PROJECT_DIR$/temp/" />
|
||||||
|
<ignored path="$PROJECT_DIR$/tmp/" />
|
||||||
|
<option name="EXCLUDED_CONVERTED_TO_IGNORED" value="true" />
|
||||||
|
<option name="TRACKING_ENABLED" value="true" />
|
||||||
|
<option name="SHOW_DIALOG" value="false" />
|
||||||
|
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
||||||
|
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
|
||||||
|
<option name="LAST_RESOLUTION" value="IGNORE" />
|
||||||
|
</component>
|
||||||
|
<component name="CreatePatchCommitExecutor">
|
||||||
|
<option name="PATCH_PATH" value="" />
|
||||||
|
</component>
|
||||||
|
<component name="ExecutionTargetManager" SELECTED_TARGET="default_target" />
|
||||||
|
<component name="FileEditorManager">
|
||||||
|
<leaf>
|
||||||
|
<file leaf-file-name="vnc_lite.html" pinned="false" current-in-tab="false">
|
||||||
|
<entry file="file://$PROJECT_DIR$/vnc_lite.html">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state relative-caret-position="332">
|
||||||
|
<caret line="62" column="92" lean-forward="true" selection-start-line="62" selection-start-column="92" selection-end-line="62" selection-end-column="92" />
|
||||||
|
<folding />
|
||||||
|
</state>
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
|
</file>
|
||||||
|
<file leaf-file-name="vnc_lite_vr.html" pinned="false" current-in-tab="false">
|
||||||
|
<entry file="file://$PROJECT_DIR$/vnc_lite_vr.html">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state relative-caret-position="209">
|
||||||
|
<caret line="87" column="12" lean-forward="false" selection-start-line="87" selection-start-column="12" selection-end-line="87" selection-end-column="12" />
|
||||||
|
<folding>
|
||||||
|
<element signature="e#4343#4387#0" expanded="true" />
|
||||||
|
<element signature="n#style#0;n#body#0;n#html#0;n#!!top" expanded="true" />
|
||||||
|
<element signature="n#style#0;n#canvas#0;n#div#1;n#body#0;n#html#0;n#!!top" expanded="true" />
|
||||||
|
</folding>
|
||||||
|
</state>
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
|
</file>
|
||||||
|
<file leaf-file-name="README.md" pinned="false" current-in-tab="true">
|
||||||
|
<entry file="file://$PROJECT_DIR$/README.md">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state relative-caret-position="140">
|
||||||
|
<caret line="7" column="7" lean-forward="false" selection-start-line="7" selection-start-column="7" selection-end-line="7" selection-end-column="7" />
|
||||||
|
<folding />
|
||||||
|
</state>
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
|
</file>
|
||||||
|
<file leaf-file-name="webutil.js" pinned="false" current-in-tab="false">
|
||||||
|
<entry file="file://$PROJECT_DIR$/app/webutil.js">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state relative-caret-position="162">
|
||||||
|
<caret line="26" column="27" lean-forward="false" selection-start-line="26" selection-start-column="16" selection-end-line="26" selection-end-column="27" />
|
||||||
|
<folding>
|
||||||
|
<element signature="n#!!doc" expanded="true" />
|
||||||
|
</folding>
|
||||||
|
</state>
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
|
</file>
|
||||||
|
</leaf>
|
||||||
|
</component>
|
||||||
|
<component name="FileTemplateManagerImpl">
|
||||||
|
<option name="RECENT_TEMPLATES">
|
||||||
|
<list>
|
||||||
|
<option value="HTML File" />
|
||||||
|
</list>
|
||||||
|
</option>
|
||||||
|
</component>
|
||||||
|
<component name="FindInProjectRecents">
|
||||||
|
<findStrings>
|
||||||
|
<find>getConfigVar</find>
|
||||||
|
<find>getQueryVar</find>
|
||||||
|
<find>20</find>
|
||||||
|
</findStrings>
|
||||||
|
</component>
|
||||||
|
<component name="Git.Settings">
|
||||||
|
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
|
||||||
|
</component>
|
||||||
|
<component name="IdeDocumentHistory">
|
||||||
|
<option name="CHANGED_PATHS">
|
||||||
|
<list>
|
||||||
|
<option value="$PROJECT_DIR$/vnc_vr.html" />
|
||||||
|
<option value="$PROJECT_DIR$/vnc_lite_vr.html" />
|
||||||
|
<option value="$PROJECT_DIR$/README.md" />
|
||||||
|
</list>
|
||||||
|
</option>
|
||||||
|
</component>
|
||||||
|
<component name="JsBuildToolGruntFileManager" detection-done="true" sorting="DEFINITION_ORDER" />
|
||||||
|
<component name="JsBuildToolPackageJson" detection-done="true" sorting="DEFINITION_ORDER">
|
||||||
|
<package-json value="$PROJECT_DIR$/package.json" />
|
||||||
|
</component>
|
||||||
|
<component name="JsGulpfileManager">
|
||||||
|
<detection-done>true</detection-done>
|
||||||
|
<sorting>DEFINITION_ORDER</sorting>
|
||||||
|
</component>
|
||||||
|
<component name="ProjectFrameBounds">
|
||||||
|
<option name="x" value="-8" />
|
||||||
|
<option name="y" value="-8" />
|
||||||
|
<option name="width" value="1936" />
|
||||||
|
<option name="height" value="1056" />
|
||||||
|
</component>
|
||||||
|
<component name="ProjectView">
|
||||||
|
<navigator currentView="ProjectPane" proportions="" version="1">
|
||||||
|
<flattenPackages />
|
||||||
|
<showMembers />
|
||||||
|
<showModules />
|
||||||
|
<showLibraryContents />
|
||||||
|
<hideEmptyPackages />
|
||||||
|
<abbreviatePackageNames />
|
||||||
|
<autoscrollToSource />
|
||||||
|
<autoscrollFromSource />
|
||||||
|
<sortByType />
|
||||||
|
<manualOrder />
|
||||||
|
<foldersAlwaysOnTop value="true" />
|
||||||
|
</navigator>
|
||||||
|
<panes>
|
||||||
|
<pane id="Scope" />
|
||||||
|
<pane id="ProjectPane">
|
||||||
|
<subPane>
|
||||||
|
<PATH>
|
||||||
|
<PATH_ELEMENT>
|
||||||
|
<option name="myItemId" value="noVNC2" />
|
||||||
|
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode" />
|
||||||
|
</PATH_ELEMENT>
|
||||||
|
<PATH_ELEMENT>
|
||||||
|
<option name="myItemId" value="noVNC2" />
|
||||||
|
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
|
||||||
|
</PATH_ELEMENT>
|
||||||
|
</PATH>
|
||||||
|
<PATH>
|
||||||
|
<PATH_ELEMENT>
|
||||||
|
<option name="myItemId" value="noVNC2" />
|
||||||
|
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode" />
|
||||||
|
</PATH_ELEMENT>
|
||||||
|
<PATH_ELEMENT>
|
||||||
|
<option name="myItemId" value="noVNC2" />
|
||||||
|
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
|
||||||
|
</PATH_ELEMENT>
|
||||||
|
<PATH_ELEMENT>
|
||||||
|
<option name="myItemId" value="app" />
|
||||||
|
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
|
||||||
|
</PATH_ELEMENT>
|
||||||
|
</PATH>
|
||||||
|
</subPane>
|
||||||
|
</pane>
|
||||||
|
<pane id="Scratches" />
|
||||||
|
</panes>
|
||||||
|
</component>
|
||||||
|
<component name="PropertiesComponent">
|
||||||
|
<property name="WebServerToolWindowFactoryState" value="false" />
|
||||||
|
<property name="last_opened_file_path" value="$PROJECT_DIR$" />
|
||||||
|
<property name="HbShouldOpenHtmlAsHb" value="" />
|
||||||
|
<property name="nodejs_interpreter_path" value="C:/Program Files/nodejs/node" />
|
||||||
|
<property name="js.eslint.eslintPackage" value="" />
|
||||||
|
<property name="DefaultHtmlFileTemplate" value="HTML File" />
|
||||||
|
<property name="js-jscs-nodeInterpreter" value="C:\Program Files\nodejs\node.exe" />
|
||||||
|
</component>
|
||||||
|
<component name="RunManager">
|
||||||
|
<configuration default="true" type="DartCommandLineRunConfigurationType" factoryName="Dart Command Line Application">
|
||||||
|
<method />
|
||||||
|
</configuration>
|
||||||
|
<configuration default="true" type="DartTestRunConfigurationType" factoryName="Dart Test">
|
||||||
|
<method />
|
||||||
|
</configuration>
|
||||||
|
<configuration default="true" type="JavaScriptTestRunnerKarma" factoryName="Karma">
|
||||||
|
<config-file value="" />
|
||||||
|
<node-interpreter value="project" />
|
||||||
|
<envs />
|
||||||
|
<method />
|
||||||
|
</configuration>
|
||||||
|
<configuration default="true" type="JavaScriptTestRunnerProtractor" factoryName="Protractor">
|
||||||
|
<config-file value="" />
|
||||||
|
<node-interpreter value="project" />
|
||||||
|
<envs />
|
||||||
|
<method />
|
||||||
|
</configuration>
|
||||||
|
<configuration default="true" type="JavascriptDebugType" factoryName="JavaScript Debug">
|
||||||
|
<method />
|
||||||
|
</configuration>
|
||||||
|
<configuration default="true" type="NodeJSConfigurationType" factoryName="Node.js" path-to-node="project" working-dir="">
|
||||||
|
<method />
|
||||||
|
</configuration>
|
||||||
|
<configuration default="true" type="cucumber.js" factoryName="Cucumber.js">
|
||||||
|
<option name="cucumberJsArguments" value="" />
|
||||||
|
<option name="executablePath" />
|
||||||
|
<option name="filePath" />
|
||||||
|
<method />
|
||||||
|
</configuration>
|
||||||
|
<configuration default="true" type="js.build_tools.gulp" factoryName="Gulp.js">
|
||||||
|
<method />
|
||||||
|
</configuration>
|
||||||
|
<configuration default="true" type="js.build_tools.npm" factoryName="npm">
|
||||||
|
<command value="run" />
|
||||||
|
<scripts />
|
||||||
|
<node-interpreter value="project" />
|
||||||
|
<envs />
|
||||||
|
<method />
|
||||||
|
</configuration>
|
||||||
|
<configuration default="true" type="mocha-javascript-test-runner" factoryName="Mocha">
|
||||||
|
<node-interpreter>project</node-interpreter>
|
||||||
|
<node-options />
|
||||||
|
<working-directory />
|
||||||
|
<pass-parent-env>true</pass-parent-env>
|
||||||
|
<envs />
|
||||||
|
<ui />
|
||||||
|
<extra-mocha-options />
|
||||||
|
<test-kind>DIRECTORY</test-kind>
|
||||||
|
<test-directory />
|
||||||
|
<recursive>false</recursive>
|
||||||
|
<method />
|
||||||
|
</configuration>
|
||||||
|
</component>
|
||||||
|
<component name="ShelveChangesManager" show_recycled="false">
|
||||||
|
<option name="remove_strategy" value="false" />
|
||||||
|
</component>
|
||||||
|
<component name="TaskManager">
|
||||||
|
<task active="true" id="Default" summary="Default task">
|
||||||
|
<changelist id="1d3b8a90-39a8-4e12-bf3c-191ba9fee294" name="Default" comment="" />
|
||||||
|
<created>1495215905470</created>
|
||||||
|
<option name="number" value="Default" />
|
||||||
|
<option name="presentableId" value="Default" />
|
||||||
|
<updated>1495215905470</updated>
|
||||||
|
<workItem from="1495215906702" duration="3143000" />
|
||||||
|
</task>
|
||||||
|
<servers />
|
||||||
|
</component>
|
||||||
|
<component name="TimeTrackingManager">
|
||||||
|
<option name="totallyTimeSpent" value="3143000" />
|
||||||
|
</component>
|
||||||
|
<component name="ToolWindowManager">
|
||||||
|
<frame x="-8" y="-8" width="1936" height="1056" extended-state="6" />
|
||||||
|
<editor active="true" />
|
||||||
|
<layout>
|
||||||
|
<window_info id="Project" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="true" show_stripe_button="true" weight="0.25" sideWeight="0.5" order="0" side_tool="false" content_ui="combo" />
|
||||||
|
<window_info id="TODO" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="6" side_tool="false" content_ui="tabs" />
|
||||||
|
<window_info id="Event Log" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="-1" side_tool="true" content_ui="tabs" />
|
||||||
|
<window_info id="Version Control" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="-1" side_tool="false" content_ui="tabs" />
|
||||||
|
<window_info id="npm" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="-1" side_tool="true" content_ui="tabs" />
|
||||||
|
<window_info id="Run" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="2" side_tool="false" content_ui="tabs" />
|
||||||
|
<window_info id="Structure" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.25" sideWeight="0.5" order="1" side_tool="false" content_ui="tabs" />
|
||||||
|
<window_info id="Terminal" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="-1" side_tool="false" content_ui="tabs" />
|
||||||
|
<window_info id="Favorites" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="-1" side_tool="true" content_ui="tabs" />
|
||||||
|
<window_info id="Debug" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.4" sideWeight="0.5" order="3" side_tool="false" content_ui="tabs" />
|
||||||
|
<window_info id="Cvs" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.25" sideWeight="0.5" order="4" side_tool="false" content_ui="tabs" />
|
||||||
|
<window_info id="Hierarchy" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.25" sideWeight="0.5" order="2" side_tool="false" content_ui="combo" />
|
||||||
|
<window_info id="Message" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="0" side_tool="false" content_ui="tabs" />
|
||||||
|
<window_info id="Commander" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.4" sideWeight="0.5" order="0" side_tool="false" content_ui="tabs" />
|
||||||
|
<window_info id="Find" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="1" side_tool="false" content_ui="tabs" />
|
||||||
|
<window_info id="Inspection" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.4" sideWeight="0.5" order="5" side_tool="false" content_ui="tabs" />
|
||||||
|
<window_info id="Ant Build" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.25" sideWeight="0.5" order="1" side_tool="false" content_ui="tabs" />
|
||||||
|
</layout>
|
||||||
|
</component>
|
||||||
|
<component name="TypeScriptGeneratedFilesManager">
|
||||||
|
<option name="processedProjectFiles" value="true" />
|
||||||
|
</component>
|
||||||
|
<component name="VcsContentAnnotationSettings">
|
||||||
|
<option name="myLimit" value="2678400000" />
|
||||||
|
</component>
|
||||||
|
<component name="XDebuggerManager">
|
||||||
|
<breakpoint-manager />
|
||||||
|
<watches-manager />
|
||||||
|
</component>
|
||||||
|
<component name="editorHistoryManager">
|
||||||
|
<entry file="file://$PROJECT_DIR$/app/webutil.js">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state relative-caret-position="162">
|
||||||
|
<caret line="26" column="27" lean-forward="false" selection-start-line="26" selection-start-column="16" selection-end-line="26" selection-end-column="27" />
|
||||||
|
<folding>
|
||||||
|
<element signature="n#!!doc" expanded="true" />
|
||||||
|
</folding>
|
||||||
|
</state>
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
|
<entry file="file://$PROJECT_DIR$/vnc_lite.html">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state relative-caret-position="332">
|
||||||
|
<caret line="62" column="92" lean-forward="true" selection-start-line="62" selection-start-column="92" selection-end-line="62" selection-end-column="92" />
|
||||||
|
<folding />
|
||||||
|
</state>
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
|
<entry file="file://$PROJECT_DIR$/vnc_lite_vr.html">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state relative-caret-position="209">
|
||||||
|
<caret line="87" column="12" lean-forward="false" selection-start-line="87" selection-start-column="12" selection-end-line="87" selection-end-column="12" />
|
||||||
|
<folding>
|
||||||
|
<element signature="e#4343#4387#0" expanded="true" />
|
||||||
|
<element signature="n#style#0;n#body#0;n#html#0;n#!!top" expanded="true" />
|
||||||
|
<element signature="n#style#0;n#canvas#0;n#div#1;n#body#0;n#html#0;n#!!top" expanded="true" />
|
||||||
|
</folding>
|
||||||
|
</state>
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
|
<entry file="file://$PROJECT_DIR$/README.md">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state relative-caret-position="140">
|
||||||
|
<caret line="7" column="7" lean-forward="false" selection-start-line="7" selection-start-column="7" selection-end-line="7" selection-end-column="7" />
|
||||||
|
<folding />
|
||||||
|
</state>
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
15
README.md
15
README.md
|
|
@ -1,4 +1,17 @@
|
||||||
## noVNC: HTML5 VNC Client
|
## noVNC: HTML5 VNC Client - now works in VR
|
||||||
|
|
||||||
|
I have adapted the WebVR boilerplate with a basic Three.js scene to make this VNC client work in VR on a mobile device.
|
||||||
|
|
||||||
|
|
||||||
|
I Used tightvnc on linux to host a display on vnc. I ran these commands on the terminal inside the root folder.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo apt-get install tightvncserver.
|
||||||
|
vncserver :2 -geometry 4096x1024
|
||||||
|
./utils/launch.sh --vnc localhost:5902 # 590X port number maps to display number on tight vnc.
|
||||||
|
```
|
||||||
|
|
||||||
|
Below here is original Readme file.
|
||||||
|
|
||||||
[](https://travis-ci.org/novnc/noVNC)
|
[](https://travis-ci.org/novnc/noVNC)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,173 @@
|
||||||
|
/**
|
||||||
|
* @author dmarcos / https://github.com/dmarcos
|
||||||
|
* @author mrdoob / http://mrdoob.com
|
||||||
|
*/
|
||||||
|
|
||||||
|
THREE.VRControls = function ( object, onError ) {
|
||||||
|
|
||||||
|
var scope = this;
|
||||||
|
|
||||||
|
var vrDisplay, vrDisplays;
|
||||||
|
|
||||||
|
var standingMatrix = new THREE.Matrix4();
|
||||||
|
|
||||||
|
var frameData = null;
|
||||||
|
|
||||||
|
if ( 'VRFrameData' in window ) {
|
||||||
|
|
||||||
|
frameData = new VRFrameData();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function gotVRDisplays( displays ) {
|
||||||
|
|
||||||
|
vrDisplays = displays;
|
||||||
|
|
||||||
|
if ( displays.length > 0 ) {
|
||||||
|
|
||||||
|
vrDisplay = displays[ 0 ];
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
if ( onError ) onError( 'VR input not available.' );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( navigator.getVRDisplays ) {
|
||||||
|
|
||||||
|
navigator.getVRDisplays().then( gotVRDisplays ).catch ( function () {
|
||||||
|
|
||||||
|
console.warn( 'THREE.VRControls: Unable to get VR Displays' );
|
||||||
|
|
||||||
|
} );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// the Rift SDK returns the position in meters
|
||||||
|
// this scale factor allows the user to define how meters
|
||||||
|
// are converted to scene units.
|
||||||
|
|
||||||
|
this.scale = 1;
|
||||||
|
|
||||||
|
// If true will use "standing space" coordinate system where y=0 is the
|
||||||
|
// floor and x=0, z=0 is the center of the room.
|
||||||
|
this.standing = false;
|
||||||
|
|
||||||
|
// Distance from the users eyes to the floor in meters. Used when
|
||||||
|
// standing=true but the VRDisplay doesn't provide stageParameters.
|
||||||
|
this.userHeight = 1.6;
|
||||||
|
|
||||||
|
this.getVRDisplay = function () {
|
||||||
|
|
||||||
|
return vrDisplay;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
this.setVRDisplay = function ( value ) {
|
||||||
|
|
||||||
|
vrDisplay = value;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
this.getVRDisplays = function () {
|
||||||
|
|
||||||
|
console.warn( 'THREE.VRControls: getVRDisplays() is being deprecated.' );
|
||||||
|
return vrDisplays;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
this.getStandingMatrix = function () {
|
||||||
|
|
||||||
|
return standingMatrix;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
this.update = function () {
|
||||||
|
|
||||||
|
if ( vrDisplay ) {
|
||||||
|
|
||||||
|
var pose;
|
||||||
|
|
||||||
|
if ( vrDisplay.getFrameData ) {
|
||||||
|
|
||||||
|
vrDisplay.getFrameData( frameData );
|
||||||
|
pose = frameData.pose;
|
||||||
|
|
||||||
|
} else if ( vrDisplay.getPose ) {
|
||||||
|
|
||||||
|
pose = vrDisplay.getPose();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( pose.orientation !== null ) {
|
||||||
|
|
||||||
|
object.quaternion.fromArray( pose.orientation );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( pose.position !== null ) {
|
||||||
|
|
||||||
|
object.position.fromArray( pose.position );
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
object.position.set( 0, 0, 0 );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( this.standing ) {
|
||||||
|
|
||||||
|
if ( vrDisplay.stageParameters ) {
|
||||||
|
|
||||||
|
object.updateMatrix();
|
||||||
|
|
||||||
|
standingMatrix.fromArray( vrDisplay.stageParameters.sittingToStandingTransform );
|
||||||
|
object.applyMatrix( standingMatrix );
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
object.position.setY( object.position.y + this.userHeight );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
object.position.multiplyScalar( scope.scale );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
this.resetPose = function () {
|
||||||
|
|
||||||
|
if ( vrDisplay ) {
|
||||||
|
|
||||||
|
vrDisplay.resetPose();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
this.resetSensor = function () {
|
||||||
|
|
||||||
|
console.warn( 'THREE.VRControls: .resetSensor() is now .resetPose().' );
|
||||||
|
this.resetPose();
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
this.zeroSensor = function () {
|
||||||
|
|
||||||
|
console.warn( 'THREE.VRControls: .zeroSensor() is now .resetPose().' );
|
||||||
|
this.resetPose();
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
this.dispose = function () {
|
||||||
|
|
||||||
|
vrDisplay = null;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,477 @@
|
||||||
|
/**
|
||||||
|
* @author dmarcos / https://github.com/dmarcos
|
||||||
|
* @author mrdoob / http://mrdoob.com
|
||||||
|
*
|
||||||
|
* WebVR Spec: http://mozvr.github.io/webvr-spec/webvr.html
|
||||||
|
*
|
||||||
|
* Firefox: http://mozvr.com/downloads/
|
||||||
|
* Chromium: https://webvr.info/get-chrome
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
THREE.VREffect = function( renderer, onError ) {
|
||||||
|
|
||||||
|
var vrDisplay, vrDisplays;
|
||||||
|
var eyeTranslationL = new THREE.Vector3();
|
||||||
|
var eyeTranslationR = new THREE.Vector3();
|
||||||
|
var renderRectL, renderRectR;
|
||||||
|
|
||||||
|
var frameData = null;
|
||||||
|
|
||||||
|
if ( 'VRFrameData' in window ) {
|
||||||
|
|
||||||
|
frameData = new window.VRFrameData();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function gotVRDisplays( displays ) {
|
||||||
|
|
||||||
|
vrDisplays = displays;
|
||||||
|
|
||||||
|
if ( displays.length > 0 ) {
|
||||||
|
|
||||||
|
vrDisplay = displays[ 0 ];
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
if ( onError ) onError( 'HMD not available' );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( navigator.getVRDisplays ) {
|
||||||
|
|
||||||
|
navigator.getVRDisplays().then( gotVRDisplays ).catch( function() {
|
||||||
|
|
||||||
|
console.warn( 'THREE.VREffect: Unable to get VR Displays' );
|
||||||
|
|
||||||
|
} );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
this.isPresenting = false;
|
||||||
|
this.scale = 1;
|
||||||
|
|
||||||
|
var scope = this;
|
||||||
|
|
||||||
|
var rendererSize = renderer.getSize();
|
||||||
|
var rendererUpdateStyle = false;
|
||||||
|
var rendererPixelRatio = renderer.getPixelRatio();
|
||||||
|
|
||||||
|
this.getVRDisplay = function() {
|
||||||
|
|
||||||
|
return vrDisplay;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
this.setVRDisplay = function( value ) {
|
||||||
|
|
||||||
|
vrDisplay = value;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
this.getVRDisplays = function() {
|
||||||
|
|
||||||
|
console.warn( 'THREE.VREffect: getVRDisplays() is being deprecated.' );
|
||||||
|
return vrDisplays;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
this.setSize = function( width, height, updateStyle ) {
|
||||||
|
|
||||||
|
rendererSize = { width: width, height: height };
|
||||||
|
rendererUpdateStyle = updateStyle;
|
||||||
|
|
||||||
|
if ( scope.isPresenting ) {
|
||||||
|
|
||||||
|
var eyeParamsL = vrDisplay.getEyeParameters( 'left' );
|
||||||
|
renderer.setPixelRatio( 1 );
|
||||||
|
renderer.setSize( eyeParamsL.renderWidth * 2, eyeParamsL.renderHeight, false );
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
renderer.setPixelRatio( rendererPixelRatio );
|
||||||
|
renderer.setSize( width, height, updateStyle );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
// VR presentation
|
||||||
|
|
||||||
|
var canvas = renderer.domElement;
|
||||||
|
var defaultLeftBounds = [ 0.0, 0.0, 0.5, 1.0 ];
|
||||||
|
var defaultRightBounds = [ 0.5, 0.0, 0.5, 1.0 ];
|
||||||
|
|
||||||
|
function onVRDisplayPresentChange() {
|
||||||
|
|
||||||
|
var wasPresenting = scope.isPresenting;
|
||||||
|
scope.isPresenting = vrDisplay !== undefined && vrDisplay.isPresenting;
|
||||||
|
|
||||||
|
if ( scope.isPresenting ) {
|
||||||
|
|
||||||
|
var eyeParamsL = vrDisplay.getEyeParameters( 'left' );
|
||||||
|
var eyeWidth = eyeParamsL.renderWidth;
|
||||||
|
var eyeHeight = eyeParamsL.renderHeight;
|
||||||
|
|
||||||
|
if ( ! wasPresenting ) {
|
||||||
|
|
||||||
|
rendererPixelRatio = renderer.getPixelRatio();
|
||||||
|
rendererSize = renderer.getSize();
|
||||||
|
|
||||||
|
renderer.setPixelRatio( 1 );
|
||||||
|
renderer.setSize( eyeWidth * 2, eyeHeight, false );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if ( wasPresenting ) {
|
||||||
|
|
||||||
|
renderer.setPixelRatio( rendererPixelRatio );
|
||||||
|
renderer.setSize( rendererSize.width, rendererSize.height, rendererUpdateStyle );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
window.addEventListener( 'vrdisplaypresentchange', onVRDisplayPresentChange, false );
|
||||||
|
|
||||||
|
this.setFullScreen = function( boolean ) {
|
||||||
|
|
||||||
|
return new Promise( function( resolve, reject ) {
|
||||||
|
|
||||||
|
if ( vrDisplay === undefined ) {
|
||||||
|
|
||||||
|
reject( new Error( 'No VR hardware found.' ) );
|
||||||
|
return;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( scope.isPresenting === boolean ) {
|
||||||
|
|
||||||
|
resolve();
|
||||||
|
return;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( boolean ) {
|
||||||
|
|
||||||
|
resolve( vrDisplay.requestPresent( [ { source: canvas } ] ) );
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
resolve( vrDisplay.exitPresent() );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
} );
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
this.requestPresent = function() {
|
||||||
|
|
||||||
|
return this.setFullScreen( true );
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
this.exitPresent = function() {
|
||||||
|
|
||||||
|
return this.setFullScreen( false );
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
this.requestAnimationFrame = function( f ) {
|
||||||
|
|
||||||
|
if ( vrDisplay !== undefined ) {
|
||||||
|
|
||||||
|
return vrDisplay.requestAnimationFrame( f );
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
return window.requestAnimationFrame( f );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
this.cancelAnimationFrame = function( h ) {
|
||||||
|
|
||||||
|
if ( vrDisplay !== undefined ) {
|
||||||
|
|
||||||
|
vrDisplay.cancelAnimationFrame( h );
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
window.cancelAnimationFrame( h );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
this.submitFrame = function() {
|
||||||
|
|
||||||
|
if ( vrDisplay !== undefined && scope.isPresenting ) {
|
||||||
|
|
||||||
|
vrDisplay.submitFrame();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
this.autoSubmitFrame = true;
|
||||||
|
|
||||||
|
// render
|
||||||
|
|
||||||
|
var cameraL = new THREE.PerspectiveCamera();
|
||||||
|
cameraL.layers.enable( 1 );
|
||||||
|
|
||||||
|
var cameraR = new THREE.PerspectiveCamera();
|
||||||
|
cameraR.layers.enable( 2 );
|
||||||
|
|
||||||
|
this.render = function( scene, camera, renderTarget, forceClear ) {
|
||||||
|
|
||||||
|
if ( vrDisplay && scope.isPresenting ) {
|
||||||
|
|
||||||
|
var autoUpdate = scene.autoUpdate;
|
||||||
|
|
||||||
|
if ( autoUpdate ) {
|
||||||
|
|
||||||
|
scene.updateMatrixWorld();
|
||||||
|
scene.autoUpdate = false;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
var eyeParamsL = vrDisplay.getEyeParameters( 'left' );
|
||||||
|
var eyeParamsR = vrDisplay.getEyeParameters( 'right' );
|
||||||
|
|
||||||
|
eyeTranslationL.fromArray( eyeParamsL.offset );
|
||||||
|
eyeTranslationR.fromArray( eyeParamsR.offset );
|
||||||
|
|
||||||
|
if ( Array.isArray( scene ) ) {
|
||||||
|
|
||||||
|
console.warn( 'THREE.VREffect.render() no longer supports arrays. Use object.layers instead.' );
|
||||||
|
scene = scene[ 0 ];
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// When rendering we don't care what the recommended size is, only what the actual size
|
||||||
|
// of the backbuffer is.
|
||||||
|
var size = renderer.getSize();
|
||||||
|
var layers = vrDisplay.getLayers();
|
||||||
|
var leftBounds;
|
||||||
|
var rightBounds;
|
||||||
|
|
||||||
|
if ( layers.length ) {
|
||||||
|
|
||||||
|
var layer = layers[ 0 ];
|
||||||
|
|
||||||
|
leftBounds = layer.leftBounds !== null && layer.leftBounds.length === 4 ? layer.leftBounds : defaultLeftBounds;
|
||||||
|
rightBounds = layer.rightBounds !== null && layer.rightBounds.length === 4 ? layer.rightBounds : defaultRightBounds;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
leftBounds = defaultLeftBounds;
|
||||||
|
rightBounds = defaultRightBounds;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
renderRectL = {
|
||||||
|
x: Math.round( size.width * leftBounds[ 0 ] ),
|
||||||
|
y: Math.round( size.height * leftBounds[ 1 ] ),
|
||||||
|
width: Math.round( size.width * leftBounds[ 2 ] ),
|
||||||
|
height: Math.round( size.height * leftBounds[ 3 ] )
|
||||||
|
};
|
||||||
|
renderRectR = {
|
||||||
|
x: Math.round( size.width * rightBounds[ 0 ] ),
|
||||||
|
y: Math.round( size.height * rightBounds[ 1 ] ),
|
||||||
|
width: Math.round( size.width * rightBounds[ 2 ] ),
|
||||||
|
height: Math.round( size.height * rightBounds[ 3 ] )
|
||||||
|
};
|
||||||
|
|
||||||
|
if ( renderTarget ) {
|
||||||
|
|
||||||
|
renderer.setRenderTarget( renderTarget );
|
||||||
|
renderTarget.scissorTest = true;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
renderer.setRenderTarget( null );
|
||||||
|
renderer.setScissorTest( true );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( renderer.autoClear || forceClear ) renderer.clear();
|
||||||
|
|
||||||
|
if ( camera.parent === null ) camera.updateMatrixWorld();
|
||||||
|
|
||||||
|
camera.matrixWorld.decompose( cameraL.position, cameraL.quaternion, cameraL.scale );
|
||||||
|
camera.matrixWorld.decompose( cameraR.position, cameraR.quaternion, cameraR.scale );
|
||||||
|
|
||||||
|
var scale = this.scale;
|
||||||
|
cameraL.translateOnAxis( eyeTranslationL, scale );
|
||||||
|
cameraR.translateOnAxis( eyeTranslationR, scale );
|
||||||
|
|
||||||
|
if ( vrDisplay.getFrameData ) {
|
||||||
|
|
||||||
|
vrDisplay.depthNear = camera.near;
|
||||||
|
vrDisplay.depthFar = camera.far;
|
||||||
|
|
||||||
|
vrDisplay.getFrameData( frameData );
|
||||||
|
|
||||||
|
cameraL.projectionMatrix.elements = frameData.leftProjectionMatrix;
|
||||||
|
cameraR.projectionMatrix.elements = frameData.rightProjectionMatrix;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
cameraL.projectionMatrix = fovToProjection( eyeParamsL.fieldOfView, true, camera.near, camera.far );
|
||||||
|
cameraR.projectionMatrix = fovToProjection( eyeParamsR.fieldOfView, true, camera.near, camera.far );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// render left eye
|
||||||
|
if ( renderTarget ) {
|
||||||
|
|
||||||
|
renderTarget.viewport.set( renderRectL.x, renderRectL.y, renderRectL.width, renderRectL.height );
|
||||||
|
renderTarget.scissor.set( renderRectL.x, renderRectL.y, renderRectL.width, renderRectL.height );
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
renderer.setViewport( renderRectL.x, renderRectL.y, renderRectL.width, renderRectL.height );
|
||||||
|
renderer.setScissor( renderRectL.x, renderRectL.y, renderRectL.width, renderRectL.height );
|
||||||
|
|
||||||
|
}
|
||||||
|
renderer.render( scene, cameraL, renderTarget, forceClear );
|
||||||
|
|
||||||
|
// render right eye
|
||||||
|
if ( renderTarget ) {
|
||||||
|
|
||||||
|
renderTarget.viewport.set( renderRectR.x, renderRectR.y, renderRectR.width, renderRectR.height );
|
||||||
|
renderTarget.scissor.set( renderRectR.x, renderRectR.y, renderRectR.width, renderRectR.height );
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
renderer.setViewport( renderRectR.x, renderRectR.y, renderRectR.width, renderRectR.height );
|
||||||
|
renderer.setScissor( renderRectR.x, renderRectR.y, renderRectR.width, renderRectR.height );
|
||||||
|
|
||||||
|
}
|
||||||
|
renderer.render( scene, cameraR, renderTarget, forceClear );
|
||||||
|
|
||||||
|
if ( renderTarget ) {
|
||||||
|
|
||||||
|
renderTarget.viewport.set( 0, 0, size.width, size.height );
|
||||||
|
renderTarget.scissor.set( 0, 0, size.width, size.height );
|
||||||
|
renderTarget.scissorTest = false;
|
||||||
|
renderer.setRenderTarget( null );
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
renderer.setViewport( 0, 0, size.width, size.height );
|
||||||
|
renderer.setScissorTest( false );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( autoUpdate ) {
|
||||||
|
|
||||||
|
scene.autoUpdate = true;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( scope.autoSubmitFrame ) {
|
||||||
|
|
||||||
|
scope.submitFrame();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Regular render mode if not HMD
|
||||||
|
|
||||||
|
renderer.render( scene, camera, renderTarget, forceClear );
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
this.dispose = function() {
|
||||||
|
|
||||||
|
window.removeEventListener( 'vrdisplaypresentchange', onVRDisplayPresentChange, false );
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
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 ] };
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function fovPortToProjection( fov, rightHanded, zNear, zFar ) {
|
||||||
|
|
||||||
|
rightHanded = rightHanded === undefined ? true : rightHanded;
|
||||||
|
zNear = zNear === undefined ? 0.01 : zNear;
|
||||||
|
zFar = zFar === undefined ? 10000.0 : zFar;
|
||||||
|
|
||||||
|
var handednessScale = rightHanded ? - 1.0 : 1.0;
|
||||||
|
|
||||||
|
// start with an identity matrix
|
||||||
|
var mobj = new THREE.Matrix4();
|
||||||
|
var m = mobj.elements;
|
||||||
|
|
||||||
|
// and with scale/offset info for normalized device coords
|
||||||
|
var scaleAndOffset = fovToNDCScaleOffset( fov );
|
||||||
|
|
||||||
|
// X result, map clip edges to [-w,+w]
|
||||||
|
m[ 0 * 4 + 0 ] = scaleAndOffset.scale[ 0 ];
|
||||||
|
m[ 0 * 4 + 1 ] = 0.0;
|
||||||
|
m[ 0 * 4 + 2 ] = scaleAndOffset.offset[ 0 ] * handednessScale;
|
||||||
|
m[ 0 * 4 + 3 ] = 0.0;
|
||||||
|
|
||||||
|
// Y result, map clip edges to [-w,+w]
|
||||||
|
// Y offset is negated because this proj matrix transforms from world coords with Y=up,
|
||||||
|
// but the NDC scaling has Y=down (thanks D3D?)
|
||||||
|
m[ 1 * 4 + 0 ] = 0.0;
|
||||||
|
m[ 1 * 4 + 1 ] = scaleAndOffset.scale[ 1 ];
|
||||||
|
m[ 1 * 4 + 2 ] = - scaleAndOffset.offset[ 1 ] * handednessScale;
|
||||||
|
m[ 1 * 4 + 3 ] = 0.0;
|
||||||
|
|
||||||
|
// Z result (up to the app)
|
||||||
|
m[ 2 * 4 + 0 ] = 0.0;
|
||||||
|
m[ 2 * 4 + 1 ] = 0.0;
|
||||||
|
m[ 2 * 4 + 2 ] = zFar / ( zNear - zFar ) * - handednessScale;
|
||||||
|
m[ 2 * 4 + 3 ] = ( zFar * zNear ) / ( zNear - zFar );
|
||||||
|
|
||||||
|
// W result (= Z in)
|
||||||
|
m[ 3 * 4 + 0 ] = 0.0;
|
||||||
|
m[ 3 * 4 + 1 ] = 0.0;
|
||||||
|
m[ 3 * 4 + 2 ] = handednessScale;
|
||||||
|
m[ 3 * 4 + 3 ] = 0.0;
|
||||||
|
|
||||||
|
mobj.transpose();
|
||||||
|
|
||||||
|
return mobj;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function fovToProjection( fov, rightHanded, zNear, zFar ) {
|
||||||
|
|
||||||
|
var DEG2RAD = Math.PI / 180.0;
|
||||||
|
|
||||||
|
var fovPort = {
|
||||||
|
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 fovPortToProjection( fovPort, rightHanded, zNear, zFar );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -0,0 +1,468 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
noVNC example: lightweight example using minimal UI and features
|
||||||
|
Copyright (C) 2012 Joel Martin
|
||||||
|
Copyright (C) 2013 Samuel Mannehed for Cendio AB
|
||||||
|
noVNC is licensed under the MPL 2.0 (see LICENSE.txt)
|
||||||
|
This file is licensed under the 2-Clause BSD license (see LICENSE.txt).
|
||||||
|
|
||||||
|
Connect parameters are provided in query string:
|
||||||
|
http://example.com/?host=HOST&port=PORT&encrypt=1
|
||||||
|
or the fragment:
|
||||||
|
http://example.com/#host=HOST&port=PORT&encrypt=1
|
||||||
|
-->
|
||||||
|
<title>noVNC</title>
|
||||||
|
|
||||||
|
<meta charset="utf-8">
|
||||||
|
|
||||||
|
<!-- Always force latest IE rendering engine (even in intranet) & Chrome Frame
|
||||||
|
Remove this if you use the .htaccess -->
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
|
||||||
|
|
||||||
|
<!-- Icons (see Makefile for what the sizes are for) -->
|
||||||
|
<link rel="icon" sizes="16x16" type="image/png" href="app/images/icons/novnc-16x16.png">
|
||||||
|
<link rel="icon" sizes="24x24" type="image/png" href="app/images/icons/novnc-24x24.png">
|
||||||
|
<link rel="icon" sizes="32x32" type="image/png" href="app/images/icons/novnc-32x32.png">
|
||||||
|
<link rel="icon" sizes="48x48" type="image/png" href="app/images/icons/novnc-48x48.png">
|
||||||
|
<link rel="icon" sizes="60x60" type="image/png" href="app/images/icons/novnc-60x60.png">
|
||||||
|
<link rel="icon" sizes="64x64" type="image/png" href="app/images/icons/novnc-64x64.png">
|
||||||
|
<link rel="icon" sizes="72x72" type="image/png" href="app/images/icons/novnc-72x72.png">
|
||||||
|
<link rel="icon" sizes="76x76" type="image/png" href="app/images/icons/novnc-76x76.png">
|
||||||
|
<link rel="icon" sizes="96x96" type="image/png" href="app/images/icons/novnc-96x96.png">
|
||||||
|
<link rel="icon" sizes="120x120" type="image/png" href="app/images/icons/novnc-120x120.png">
|
||||||
|
<link rel="icon" sizes="144x144" type="image/png" href="app/images/icons/novnc-144x144.png">
|
||||||
|
<link rel="icon" sizes="152x152" type="image/png" href="app/images/icons/novnc-152x152.png">
|
||||||
|
<link rel="icon" sizes="192x192" type="image/png" href="app/images/icons/novnc-192x192.png">
|
||||||
|
<link rel="icon" sizes="any" type="image/svg+xml" href="app/images/icons/novnc-icon.svg">
|
||||||
|
<!-- Repeated last so that legacy handling will pick this -->
|
||||||
|
<link rel="icon" sizes="16x16" type="image/png" href="app/images/icons/novnc-16x16.png">
|
||||||
|
|
||||||
|
<!-- Apple iOS Safari settings -->
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
|
||||||
|
<meta name="apple-mobile-web-app-capable" content="yes" />
|
||||||
|
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
|
||||||
|
<!-- Home Screen Icons (favourites and bookmarks use the normal icons) -->
|
||||||
|
<link rel="apple-touch-icon" sizes="60x60" type="image/png" href="app/images/icons/novnc-60x60.png">
|
||||||
|
<link rel="apple-touch-icon" sizes="76x76" type="image/png" href="app/images/icons/novnc-76x76.png">
|
||||||
|
<link rel="apple-touch-icon" sizes="120x120" type="image/png" href="app/images/icons/novnc-120x120.png">
|
||||||
|
<link rel="apple-touch-icon" sizes="152x152" type="image/png" href="app/images/icons/novnc-152x152.png">
|
||||||
|
|
||||||
|
<!-- Stylesheets -->
|
||||||
|
<link rel="stylesheet" href="app/styles/lite.css">
|
||||||
|
|
||||||
|
<!--
|
||||||
|
<script type='text/javascript'
|
||||||
|
src='http://getfirebug.com/releases/lite/1.2/firebug-lite-compressed.js'></script>
|
||||||
|
-->
|
||||||
|
|
||||||
|
<!-- <Web VR styles> -->
|
||||||
|
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background-color: #000;
|
||||||
|
color: #fff;
|
||||||
|
margin: 0px;
|
||||||
|
padding: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
/* Position the button on the bottom of the page. */
|
||||||
|
#ui {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 10px;
|
||||||
|
left: 50%;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
text-align: center;
|
||||||
|
font-family: 'Karla', sans-serif;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
a#magic-window {
|
||||||
|
display: block;
|
||||||
|
color: white;
|
||||||
|
margin-top: 1em;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<!-- </Web VR styles> -->
|
||||||
|
|
||||||
|
<!-- promise polyfills promises for IE11 -->
|
||||||
|
<script src="vendor/promise.js"></script>
|
||||||
|
<script src="vendor/browser-es-module-loader/dist/browser-es-module-loader.js"></script>
|
||||||
|
<script type="module">
|
||||||
|
// Load supporting scripts
|
||||||
|
import * as WebUtil from './app/webutil.js';
|
||||||
|
import RFB from './core/rfb.js';
|
||||||
|
var rfb;
|
||||||
|
var resizeTimeout;
|
||||||
|
var desktopName;
|
||||||
|
|
||||||
|
function UIresize() {
|
||||||
|
if (WebUtil.getConfigVar('resize', false)) {
|
||||||
|
var innerW = window.innerWidth;
|
||||||
|
var innerH = window.innerHeight;
|
||||||
|
var controlbarH = document.getElementById('noVNC_status_bar').offsetHeight;
|
||||||
|
if (innerW !== undefined && innerH !== undefined)
|
||||||
|
rfb.requestDesktopSize(innerW, innerH - controlbarH);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function FBUComplete(rfb, fbu) {
|
||||||
|
UIresize();
|
||||||
|
rfb.set_onFBUComplete(function() { });
|
||||||
|
}
|
||||||
|
function updateDesktopName(rfb, name) {
|
||||||
|
desktopName = name;
|
||||||
|
}
|
||||||
|
function passwordRequired(rfb, msg) {
|
||||||
|
if (typeof msg === 'undefined') {
|
||||||
|
msg = 'Password Required: ';
|
||||||
|
}
|
||||||
|
var html;
|
||||||
|
|
||||||
|
var form = document.createElement('form');
|
||||||
|
form.style = 'margin-bottom: 0px';
|
||||||
|
form.innerHTML = '<label></label>'
|
||||||
|
form.innerHTML += '<input type=password size=10 id="password_input" class="noVNC_status">';
|
||||||
|
form.onsubmit = setPassword;
|
||||||
|
|
||||||
|
// bypass status() because it sets text content
|
||||||
|
document.getElementById('noVNC_status_bar').setAttribute("class", "noVNC_status_warn");
|
||||||
|
document.getElementById('noVNC_status').innerHTML = '';
|
||||||
|
document.getElementById('noVNC_status').appendChild(form);
|
||||||
|
document.getElementById('noVNC_status').querySelector('label').textContent = msg;
|
||||||
|
}
|
||||||
|
function setPassword() {
|
||||||
|
rfb.sendPassword(document.getElementById('password_input').value);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
function sendCtrlAltDel() {
|
||||||
|
rfb.sendCtrlAltDel();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
function xvpShutdown() {
|
||||||
|
rfb.xvpShutdown();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
function xvpReboot() {
|
||||||
|
rfb.xvpReboot();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
function xvpReset() {
|
||||||
|
rfb.xvpReset();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
function status(text, level) {
|
||||||
|
switch (level) {
|
||||||
|
case 'normal':
|
||||||
|
case 'warn':
|
||||||
|
case 'error':
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
level = "warn";
|
||||||
|
}
|
||||||
|
document.getElementById('noVNC_status_bar').setAttribute("class", "noVNC_status_" + level);
|
||||||
|
document.getElementById('noVNC_status').textContent = text;
|
||||||
|
}
|
||||||
|
function updateState(rfb, state, oldstate) {
|
||||||
|
var cad = document.getElementById('sendCtrlAltDelButton');
|
||||||
|
switch (state) {
|
||||||
|
case 'connecting':
|
||||||
|
status("Connecting", "normal");
|
||||||
|
break;
|
||||||
|
case 'connected':
|
||||||
|
if (rfb && rfb.get_encrypt()) {
|
||||||
|
status("Connected (encrypted) to " +
|
||||||
|
desktopName, "normal");
|
||||||
|
} else {
|
||||||
|
status("Connected (unencrypted) to " +
|
||||||
|
desktopName, "normal");
|
||||||
|
}
|
||||||
|
document.body.className = 'is_running';
|
||||||
|
break;
|
||||||
|
case 'disconnecting':
|
||||||
|
status("Disconnecting", "normal");
|
||||||
|
break;
|
||||||
|
case 'disconnected':
|
||||||
|
status("Disconnected", "normal");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
status(state, "warn");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (state === 'connected') {
|
||||||
|
cad.disabled = false;
|
||||||
|
} else {
|
||||||
|
cad.disabled = true;
|
||||||
|
xvpInit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
function disconnected(rfb, reason) {
|
||||||
|
if (typeof(reason) !== 'undefined') {
|
||||||
|
status(reason, "error");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function notification(rfb, msg, level, options) {
|
||||||
|
status(msg, level);
|
||||||
|
}
|
||||||
|
|
||||||
|
window.onresize = function () {
|
||||||
|
// When the window has been resized, wait until the size remains
|
||||||
|
// the same for 0.5 seconds before sending the request for changing
|
||||||
|
// the resolution of the session
|
||||||
|
clearTimeout(resizeTimeout);
|
||||||
|
resizeTimeout = setTimeout(function(){
|
||||||
|
UIresize();
|
||||||
|
}, 500);
|
||||||
|
};
|
||||||
|
|
||||||
|
function xvpInit(ver) {
|
||||||
|
var xvpbuttons;
|
||||||
|
xvpbuttons = document.getElementById('noVNC_xvp_buttons');
|
||||||
|
if (ver >= 1) {
|
||||||
|
xvpbuttons.style.display = 'inline';
|
||||||
|
} else {
|
||||||
|
xvpbuttons.style.display = 'none';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
document.getElementById('sendCtrlAltDelButton').style.display = "inline";
|
||||||
|
document.getElementById('sendCtrlAltDelButton').onclick = sendCtrlAltDel;
|
||||||
|
document.getElementById('xvpShutdownButton').onclick = xvpShutdown;
|
||||||
|
document.getElementById('xvpRebootButton').onclick = xvpReboot;
|
||||||
|
document.getElementById('xvpResetButton').onclick = xvpReset;
|
||||||
|
|
||||||
|
WebUtil.init_logging(WebUtil.getConfigVar('logging', 'warn'));
|
||||||
|
document.title = WebUtil.getConfigVar('title', 'noVNC');
|
||||||
|
// By default, use the host and port of server that served this file
|
||||||
|
var host = WebUtil.getConfigVar('host', window.location.hostname);
|
||||||
|
var port = WebUtil.getConfigVar('port', window.location.port);
|
||||||
|
|
||||||
|
// if port == 80 (or 443) then it won't be present and should be
|
||||||
|
// set manually
|
||||||
|
if (!port) {
|
||||||
|
if (window.location.protocol.substring(0,5) == 'https') {
|
||||||
|
port = 443;
|
||||||
|
}
|
||||||
|
else if (window.location.protocol.substring(0,4) == 'http') {
|
||||||
|
port = 80;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var password = WebUtil.getConfigVar('password', '');
|
||||||
|
var path = WebUtil.getConfigVar('path', 'websockify');
|
||||||
|
|
||||||
|
// If a token variable is passed in, set the parameter in a cookie.
|
||||||
|
// This is used by nova-novncproxy.
|
||||||
|
var token = WebUtil.getConfigVar('token', null);
|
||||||
|
if (token) {
|
||||||
|
// if token is already present in the path we should use it
|
||||||
|
path = WebUtil.injectParamIfMissing(path, "token", token);
|
||||||
|
|
||||||
|
WebUtil.createCookie('token', token, 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
(function() {
|
||||||
|
|
||||||
|
if ((!host) || (!port)) {
|
||||||
|
status('Must specify host and port in URL', 'error');
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
rfb = new RFB({'target': document.getElementById('noVNC_canvas'),
|
||||||
|
'encrypt': WebUtil.getConfigVar('encrypt',
|
||||||
|
(window.location.protocol === "https:")),
|
||||||
|
'repeaterID': WebUtil.getConfigVar('repeaterID', ''),
|
||||||
|
'local_cursor': WebUtil.getConfigVar('cursor', true),
|
||||||
|
'shared': WebUtil.getConfigVar('shared', true),
|
||||||
|
'view_only': WebUtil.getConfigVar('view_only', false),
|
||||||
|
'onNotification': notification,
|
||||||
|
'onUpdateState': updateState,
|
||||||
|
'onDisconnected': disconnected,
|
||||||
|
'onXvpInit': xvpInit,
|
||||||
|
'onPasswordRequired': passwordRequired,
|
||||||
|
'onFBUComplete': FBUComplete,
|
||||||
|
'onDesktopName': updateDesktopName});
|
||||||
|
} catch (exc) {
|
||||||
|
status('Unable to create RFB client -- ' + exc, 'error');
|
||||||
|
return; // don't continue trying to connect
|
||||||
|
}
|
||||||
|
|
||||||
|
rfb.connect(host, port, password, path);
|
||||||
|
})();
|
||||||
|
</script>
|
||||||
|
<!-- <Body&header tags moved up - content above scripts> -->
|
||||||
|
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body style="margin: 0px;">
|
||||||
|
|
||||||
|
<div id="ui">
|
||||||
|
<div id="vr-button"></div>
|
||||||
|
<a id="magic-window" href="#">Try it without a headset</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- hide container around canvas and hide canvas. -->
|
||||||
|
<div id="noVNC_container">
|
||||||
|
<div id="noVNC_status_bar" class="noVNC_status_bar" style="margin-top: 0px;">
|
||||||
|
<table border=0 width="100%"><tr>
|
||||||
|
<td><div id="noVNC_status" style="position: relative; height: auto;">
|
||||||
|
Loading
|
||||||
|
</div></td>
|
||||||
|
<td width="1%"><div id="noVNC_buttons">
|
||||||
|
<input type=button value="Send CtrlAltDel"
|
||||||
|
id="sendCtrlAltDelButton">
|
||||||
|
<span id="noVNC_xvp_buttons">
|
||||||
|
<input type=button value="Shutdown"
|
||||||
|
id="xvpShutdownButton">
|
||||||
|
<input type=button value="Reboot"
|
||||||
|
id="xvpRebootButton">
|
||||||
|
<input type=button value="Reset"
|
||||||
|
id="xvpResetButton">
|
||||||
|
</span>
|
||||||
|
</div></td>
|
||||||
|
</tr></table>
|
||||||
|
</div>
|
||||||
|
<canvas id="noVNC_canvas" width="512px" height="512px" style="display:none;"><!-- set default size to power of 2 -->
|
||||||
|
Canvas not supported.
|
||||||
|
</canvas>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- </Body&header tags moved up - content above scripts> -->
|
||||||
|
|
||||||
|
|
||||||
|
<!-- <Three.js and webvr boilerplate scripts & scene.> -->
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/85/three.min.js"></script>
|
||||||
|
|
||||||
|
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>
|
||||||
|
<script>
|
||||||
|
/*
|
||||||
|
* Debug parameters.
|
||||||
|
*/
|
||||||
|
WebVRConfig = {
|
||||||
|
BUFFER_SCALE: 0.5,
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
A polyfill for Promises. Needed for IE and Edge.
|
||||||
|
-->
|
||||||
|
<script src="vendor/es6-promise.min.js"></script>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
VRControls.js acquires positional information from connected VR devices and applies the transformations to a three.js camera object.
|
||||||
|
-->
|
||||||
|
<script src="vendor/VRControls.js"></script>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
VREffect.js handles stereo camera setup and rendering.
|
||||||
|
-->
|
||||||
|
<script src="vendor/VREffect.js"></script>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
A polyfill for WebVR using the Device{Motion,Orientation}Event API.
|
||||||
|
-->
|
||||||
|
<script src="vendor/webvr-polyfill.min.js"></script>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
A set of UI controls for entering VR mode.
|
||||||
|
-->
|
||||||
|
<script src="vendor/webvr-ui.min.js"></script>
|
||||||
|
|
||||||
|
<!-- </Three.js and webvr boilerplate scripts & scene.> -->
|
||||||
|
|
||||||
|
<script>
|
||||||
|
var streamCanvas = document.getElementById('noVNC_canvas');
|
||||||
|
if(streamCanvas){
|
||||||
|
var context = streamCanvas.getContext("2d");
|
||||||
|
context.fillStyle="#000000";
|
||||||
|
context.fillRect(0,0,512,512);
|
||||||
|
var scene = new THREE.Scene();
|
||||||
|
// create a camera, which defines where we're looking at.
|
||||||
|
var camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000);
|
||||||
|
scene.add(camera);
|
||||||
|
|
||||||
|
|
||||||
|
// plane
|
||||||
|
var texture = texture = new THREE.Texture(streamCanvas);
|
||||||
|
texture.wrapS = THREE.RepeatWrapping;
|
||||||
|
texture.repeat.x = - 1;
|
||||||
|
var geometry = new THREE.SphereGeometry(50, 24, 24, 0, 3, .75, 1.75);//new THREE.PlaneGeometry( 80, 20 );
|
||||||
|
geometry.applyMatrix( new THREE.Matrix4().makeScale( 3.0, 2.0, 3.0 ) );
|
||||||
|
|
||||||
|
|
||||||
|
var material = new THREE.MeshBasicMaterial( { map: texture, side: THREE.DoubleSide } );
|
||||||
|
var mesh = new THREE.Mesh( geometry, material );
|
||||||
|
|
||||||
|
camera.position.z = 300;
|
||||||
|
scene.add( mesh );
|
||||||
|
|
||||||
|
var renderer = new THREE.WebGLRenderer();
|
||||||
|
renderer.setSize(window.innerWidth, window.innerHeight);
|
||||||
|
|
||||||
|
document.body.appendChild( renderer.domElement );
|
||||||
|
|
||||||
|
var controls = new THREE.VRControls(camera);
|
||||||
|
controls.standing = true;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
var nonVRcontrols = new THREE.OrbitControls( camera, renderer.domElement );
|
||||||
|
camera.position.y = controls.userHeight;
|
||||||
|
|
||||||
|
var effect = new THREE.VREffect(renderer);
|
||||||
|
effect.setSize(window.innerWidth, window.innerHeight);
|
||||||
|
mesh.rotation.y += Math.PI;
|
||||||
|
var vrButton = new webvrui.EnterVRButton(renderer.domElement, {
|
||||||
|
color: 'black',
|
||||||
|
background: 'white',
|
||||||
|
corners: 'square'
|
||||||
|
});
|
||||||
|
vrButton.on('exit', function() {
|
||||||
|
camera.quaternion.set(0, 0, 0, 1);
|
||||||
|
camera.position.set(0, controls.userHeight, 0);
|
||||||
|
});
|
||||||
|
vrButton.on('hide', function() {
|
||||||
|
document.getElementById('ui').style.display = 'none';
|
||||||
|
});
|
||||||
|
vrButton.on('show', function() {
|
||||||
|
document.getElementById('ui').style.display = 'inherit';
|
||||||
|
});
|
||||||
|
document.getElementById('vr-button').appendChild(vrButton.domElement);
|
||||||
|
document.getElementById('magic-window').addEventListener('click', function() {
|
||||||
|
vrButton.requestEnterFullscreen();
|
||||||
|
});
|
||||||
|
function animate() {
|
||||||
|
|
||||||
|
mesh.rotation.y += 0.0005;
|
||||||
|
if(document.body.className == 'is_running'){
|
||||||
|
texture.needsUpdate = true;
|
||||||
|
}
|
||||||
|
if (vrButton.isPresenting()) {
|
||||||
|
controls.update();
|
||||||
|
}else{
|
||||||
|
nonVRcontrols.update();
|
||||||
|
}
|
||||||
|
effect.render(scene, camera);
|
||||||
|
vrDisplay.requestAnimationFrame(animate);
|
||||||
|
|
||||||
|
}
|
||||||
|
navigator.getVRDisplays().then(function(displays) {
|
||||||
|
if (displays.length > 0) {
|
||||||
|
vrDisplay = displays[0];
|
||||||
|
vrDisplay.requestAnimationFrame(animate);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
Loading…
Reference in New Issue