Commit dedc7812 authored by Ruben Rodriguez's avatar Ruben Rodriguez
Browse files

Initial commit

parents
addons/godot-openxr
addons/godot-videodecoder/bin
addons/godot-videodecoder/src
.import/
Cinema.*
export_presets.cfg
This diff is collapsed.
# A stereoscopic 3D movie player for Godot-OpenXR, for half side-by-side or over-under video formats.
## Features:
* Drag-and-drop a video file onto the program window to play it.
* Press enter to reset the HMD position
* Press space to pause/play, arrow keys to seek through the video, and PgUp PgDown to move the screen back/forward.
* This program includes an advanced view mode in where the parallax of eye projection can be customized, as well as the inter-pupillar distance and the brightness of each eye screen. This is hidden by default and can be enabled by pressing backspace. Use WASD to set the parallax, keys Q and E to set the IPD, keys Z and X to set the brightness, and P to print current values.
## DISCLAIMER:
The advanced display mode is intended for the research of behavioral optometry. Do not use for therapeutic applications without the supervision of an optometrist. The author declines all responsibility for the use of this program as a therapeutic tool.
## Dependencies:
* Godot Videodecoder
Adds support for playing any video format supported by ffmpeg. Instructions to integrate with the system's ffmpeg on GNU/Linux:
git clone https://github.com/kidrigger/godot-videodecoder.git
cd godot-videodecoder
scons -c platform=x11
scons platform=x11 prefix=/tmp
ldd /tmp/x11/libgdnative_videodecoder.so
Copy the libgdnative_videodecoder.so file into addons/godot-videodecoder/bin/x11/libgdnative_videodecoder.so
* Godot OpenXR
Download using AssetLib or from https://github.com/GodotVR/godot_openxr/releases
[gd_scene load_steps=10 format=2]
[sub_resource type="GDScript" id=45]
script/source = "extends Spatial
onready var lvisor = $LVisor
onready var rvisor = $RVisor
onready var lscreen = $LVisor/LScreen
onready var rscreen = $RVisor/RScreen
onready var lviewport = $LVisor/LViewport
onready var rviewport = $LVisor/LViewport
onready var lcam = $LVisor/LViewport/LCamera
onready var rcam = $RVisor/RViewport/RCamera
var hmd = Camera
var hipd = 0.0315 #half ipd of device. TODO: get from compositor
var brightness = 0.0 #gets substracted from base value
var resolution = 3000
var x_rot = 0.0
var y_rot = 0.0
var t = Transform.IDENTITY
var config = ConfigFile.new()
# Rotate the visors outwards to cover the field of view, compensated in _process
var offset = 0.1
func saveconf():
config.set_value(\"customeyes\", \"x_rot\", x_rot)
config.set_value(\"customeyes\", \"y_rot\", y_rot)
config.set_value(\"customeyes\", \"brightness\", brightness)
config.set_value(\"customeyes\", \"hpid\", hipd)
config.save(\"user://config.cfg\")
func _ready():
hmd = get_parent()
var err = config.load(\"user://config.cfg\")
if err == OK:
x_rot = config.get_value(\"customeyes\", \"x_rot\", 0.0)
y_rot = config.get_value(\"customeyes\", \"y_rot\", 0.0)
brightness = config.get_value(\"customeyes\", \"brightness\", 0.0)
hipd = config.get_value(\"customeyes\", \"hipd\", 0.0315)
lviewport.size = Vector2(resolution, resolution)
rviewport.size = Vector2(resolution, resolution)
lcam.h_offset=-hipd
rcam.h_offset=hipd
lvisor.translation=Vector3( -hipd, 0, 0)
rvisor.translation=Vector3( hipd, 0, 0)
lvisor.rotation=Vector3(0, offset, 0)
rvisor.rotation=Vector3(0, -offset, 0)
applybrightness(false)
func applybrightness(save=true):
if brightness <= 0:
lscreen.get_active_material(0).set_shader_param(\"brightness_l\", 1.0)
rscreen.get_active_material(0).set_shader_param(\"brightness_r\", 1.0 + brightness)
else:
lscreen.get_active_material(0).set_shader_param(\"brightness_l\", 1.0 - brightness)
rscreen.get_active_material(0).set_shader_param(\"brightness_r\", 1.0)
if save:
saveconf()
func _input(event):
if event is InputEventKey:
if event.pressed and event.scancode == KEY_Q:
hipd -= 0.001
lcam.h_offset = -hipd
rcam.h_offset = hipd
saveconf()
if event.pressed and event.scancode == KEY_E:
hipd += 0.001
lcam.h_offset = -hipd
rcam.h_offset = hipd
saveconf()
if event.pressed and event.scancode == KEY_Z:
if brightness < 1.0:
brightness += 0.01
applybrightness()
if event.pressed and event.scancode == KEY_X:
if brightness > -1.0:
brightness -= 0.01
applybrightness()
if event.pressed and event.scancode == KEY_W:
y_rot += 0.01
saveconf()
if event.pressed and event.scancode == KEY_S:
y_rot -= 0.01
saveconf()
if event.pressed and event.scancode == KEY_D:
x_rot -= 0.01
saveconf()
if event.pressed and event.scancode == KEY_A:
x_rot += 0.01
saveconf()
if event.pressed and event.scancode == KEY_ENTER:
ARVRServer.center_on_hmd(ARVRServer.RESET_FULL_ROTATION, false)
if event.pressed and event.scancode == KEY_BACKSPACE:
visible = !visible
if event.pressed and event.scancode == KEY_P:
#print(\"LCam fov %s\" % lcam.fov)
#print(\"Lcam Transform %s\" % lcam.get_global_transform())
#print(\"Lvisor Transform %s\" % lvisor.get_global_transform())
#print(\"Lcam h-offset %s\" % lcam.h_offset)
#print(\"rcam h-offset %s\" % rcam.h_offset)
print(\"hipd %s\" % hipd)
print(\"y_rot %s\" % y_rot)
print(\"x_rot %s\" % x_rot)
print(\"brightness %s\" % brightness)
func _process(delta):
t = hmd.get_global_transform()
lcam.set_global_transform(t * Transform.IDENTITY \\
.rotated(Vector3.UP, -x_rot + offset) \\
.rotated(Vector3.LEFT, y_rot))
rcam.set_global_transform(t * Transform.IDENTITY \\
.rotated(Vector3.UP, x_rot - offset) \\
.rotated(Vector3.RIGHT, y_rot))
"
[sub_resource type="QuadMesh" id=50]
size = Vector2( 4, 4 )
[sub_resource type="Shader" id=35]
resource_local_to_scene = true
code = "// NOTE: Shader automatically converted from Godot Engine 3.4.2.stable's SpatialMaterial.
shader_type spatial;
render_mode unshaded;
uniform sampler2D texture_albedo_l;
uniform float brightness_l;
/*
uniform float radius = 15.0;
void fragment() {
vec4 col = texture(texture_albedo_l, UV);
//textureLod()
//vec2 ps = vec2(1.0/2000.0,1.0/2000.0);
vec2 ps = 1.0 / VIEWPORT_SIZE;
col += texture(texture_albedo_l, UV + vec2(0.0, -radius) * ps);
col += texture(texture_albedo_l, UV + vec2(0.0, radius) * ps);
col += texture(texture_albedo_l, UV + vec2(-radius, 0.0) * ps);
col += texture(texture_albedo_l, UV + vec2(radius, 0.0) * ps);
col /= 5.0;
//vec4 albedo_tex = texture(texture_albedo_l, UV);
//ALBEDO = albedo_tex.rgb * brightness_l;
ALBEDO = col.rgb;
}
*/
uniform vec2 blur_scale = vec2(2, 2);
const float SAMPLES = 20.0;
const float TAU = 6.283185307179586476925286766559;
float gaussian(float x) {
float x_squared = x * x;
float width = 1.0 / sqrt(TAU * SAMPLES);
return width * exp((x_squared / (2.0 * SAMPLES)) * -1.0);
}
void fragment() {
vec2 scale = (1.0/VIEWPORT_SIZE) * blur_scale;
float total_weight = 0.0;
vec4 color = vec4(0.0);
for (int i = -int(SAMPLES) / 2; i < int(SAMPLES) / 2; ++i) {
float weight = gaussian(float(i));
color += texture(texture_albedo_l, UV + scale * vec2(float(i))) * weight;
total_weight += weight;
}
ALBEDO = color.rgb / total_weight * brightness_l;
}"
[sub_resource type="ViewportTexture" id=36]
viewport_path = NodePath("LVisor/LViewport")
[sub_resource type="ShaderMaterial" id=37]
resource_local_to_scene = true
shader = SubResource( 35 )
shader_param/brightness_l = 0.5
shader_param/blur_scale = Vector2( 0, 0 )
shader_param/texture_albedo_l = SubResource( 36 )
[sub_resource type="QuadMesh" id=27]
size = Vector2( 4, 4 )
[sub_resource type="Shader" id=28]
code = "// NOTE: Shader automatically converted from Godot Engine 3.4.2.stable's SpatialMaterial.
shader_type spatial;
render_mode unshaded;
uniform sampler2D texture_albedo_r;
uniform float brightness_r;
/*
uniform float radius = 15.0;
void fragment() {
vec4 col = texture(texture_albedo_l, UV);
//textureLod()
//vec2 ps = vec2(1.0/2000.0,1.0/2000.0);
vec2 ps = 1.0 / VIEWPORT_SIZE;
col += texture(texture_albedo_l, UV + vec2(0.0, -radius) * ps);
col += texture(texture_albedo_l, UV + vec2(0.0, radius) * ps);
col += texture(texture_albedo_l, UV + vec2(-radius, 0.0) * ps);
col += texture(texture_albedo_l, UV + vec2(radius, 0.0) * ps);
col /= 5.0;
//vec4 albedo_tex = texture(texture_albedo_l, UV);
//ALBEDO = albedo_tex.rgb * brightness_l;
ALBEDO = col.rgb;
}
*/
uniform vec2 blur_scale = vec2(2, 2);
const float SAMPLES = 20.0;
const float TAU = 6.283185307179586476925286766559;
float gaussian(float x) {
float x_squared = x * x;
float width = 1.0 / sqrt(TAU * SAMPLES);
return width * exp((x_squared / (2.0 * SAMPLES)) * -1.0);
}
void fragment() {
vec2 scale = (1.0/VIEWPORT_SIZE) * blur_scale;
float total_weight = 0.0;
vec4 color = vec4(0.0);
for (int i = -int(SAMPLES) / 2; i < int(SAMPLES) / 2; ++i) {
float weight = gaussian(float(i));
color += texture(texture_albedo_r, UV + scale * vec2(float(i))) * weight;
total_weight += weight;
}
ALBEDO = color.rgb / total_weight * brightness_r;
}"
[sub_resource type="ViewportTexture" id=39]
viewport_path = NodePath("RVisor/RViewport")
[sub_resource type="ShaderMaterial" id=40]
resource_local_to_scene = true
shader = SubResource( 28 )
shader_param/brightness_r = 0.5
shader_param/blur_scale = Vector2( 0, 0 )
shader_param/texture_albedo_r = SubResource( 39 )
[node name="Visor" type="Spatial"]
visible = false
script = SubResource( 45 )
[node name="LVisor" type="MeshInstance" parent="."]
layers = 512
[node name="LScreen" type="MeshInstance" parent="LVisor"]
transform = Transform( 0.01, 0, 0, 0, 0.01, 0, 0, 0, 0.01, 0, 0, -0.02 )
layers = 512
cast_shadow = 0
generate_lightmap = false
mesh = SubResource( 50 )
skeleton = NodePath("")
software_skinning_transform_normals = false
material/0 = SubResource( 37 )
[node name="LViewport" type="Viewport" parent="LVisor"]
size = Vector2( 3000, 3000 )
handle_input_locally = false
msaa = 1
hdr = false
keep_3d_linear = true
usage = 3
render_target_v_flip = true
[node name="LCamera" type="Camera" parent="LVisor/LViewport"]
cull_mask = 1048059
fov = 90.0
far = 300.0
[node name="RVisor" type="MeshInstance" parent="."]
layers = 512
[node name="RScreen" type="MeshInstance" parent="RVisor"]
transform = Transform( 0.01, 0, 0, 0, 0.01, 0, 0, 0, 0.001, 0, 0, -0.02 )
layers = 512
cast_shadow = 0
mesh = SubResource( 27 )
skeleton = NodePath("")
software_skinning_transform_normals = false
material/0 = SubResource( 40 )
[node name="RViewport" type="Viewport" parent="RVisor"]
size = Vector2( 3000, 3000 )
handle_input_locally = false
msaa = 1
hdr = false
keep_3d_linear = true
usage = 3
render_target_v_flip = true
[node name="RCamera" type="Camera" parent="RVisor/RViewport"]
cull_mask = 1048061
fov = 90.0
far = 300.0
[general]
singleton=true
load_once=true
symbol_prefix="godot_"
reloadable=false
[entry]
OSX.64="res://addons/bin/osx/libgdnative_videodecoder.dylib"
Windows.64="res://addons/bin/win64/libgdnative_videodecoder.dll"
Windows.32="res://addons/bin/win32/libgdnative_videodecoder.dll"
X11.64="res://addons/godot-videodecoder/bin/x11/libgdnative_videodecoder.so"
[dependencies]
OSX.64=[ "res://addons/bin/osx/libavformat.58.dylib", "res://addons/bin/osx/libavutil.56.dylib", "res://addons/bin/osx/libavcodec.58.dylib", "res://addons/bin/osx/libswscale.5.dylib", "res://addons/bin/osx/libswresample.3.dylib" ]
Windows.64=[ "res://addons/bin/win64/avformat-58.dll", "res://addons/bin/win64/avutil-56.dll", "res://addons/bin/win64/avcodec-58.dll", "res://addons/bin/win64/swscale-5.dll", "res://addons/bin/win64/swresample-3.dll", "res://addons/bin/win64/libwinpthread-1.dll" ]
Windows.32=[ "res://addons/bin/win32/avformat-58.dll", "res://addons/bin/win32/avutil-56.dll", "res://addons/bin/win32/avcodec-58.dll", "res://addons/bin/win64/swscale-5.dll", "res://addons/bin/win32/swresample-3.dll", "res://addons/bin/win32/libwinpthread-1.dll" ]
X11.64=[ ]
[plugin]
name="Godot Videodecoder"
description="Godot video decoder https://github.com/kidrigger/godot-videodecoder"
author="Anish Bhobe"
version="0.0.2"
script="plugin.gd"
tool
extends EditorPlugin
func _enter_tree():
pass
func _exit_tree():
pass
icon.png

3.23 KB

[remap]
importer="texture"
type="StreamTexture"
path="res://.import/icon.png-487276ed1e3a0c39cad0279d744ee560.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://icon.png"
dest_files=[ "res://.import/icon.png-487276ed1e3a0c39cad0279d744ee560.stex" ]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=true
flags/mipmaps=false
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
process/normal_map_invert_y=false
stream=false
size_limit=0
detect_3d=true
svg/scale=1.0
; Engine configuration file.
; It's best edited using the editor UI and not directly,
; since the parameters that go here are not all obvious.
;
; Format:
; [section] ; section goes between []
; param=value ; assign values to parameters
config_version=4
[application]
config/name="Godot 3D movie player"
run/main_scene="res://world.tscn"
config/icon="res://icon.png"
[debug]
settings/stdout/print_fps=true
[editor_plugins]
enabled=PoolStringArray( "res://addons/godot-openxr/plugin.cfg", "res://addons/godot-videodecoder/plugin.cfg" )
[gdnative]
singletons=[ "res://addons/godot-openxr/config/godot_openxr.gdnlib", "res://addons/godot-videodecoder/config/godot_videodecoder.gdnlib" ]
[physics]
common/enable_pause_aware_picking=true
[rendering]
quality/intended_usage/framebuffer_allocation=3
threads/thread_safe_bvh=true
quality/depth/hdr=false
extends Spatial
onready var videoplayer = $Screens/Viewport/VideoPlayer
var zoom = 0.0
func _ready():
get_tree().connect("files_dropped", self, "_on_file_dropped")
var VR = ARVRServer.find_interface("OpenXR")
if VR and VR.initialize():
get_viewport().arvr = true
get_viewport().hdr = false
get_viewport().keep_3d_linear = false
get_viewport().usage=Viewport.USAGE_3D_NO_EFFECTS
OS.vsync_enabled = false
Engine.iterations_per_second = 90
load_file("/home/ruben/Videos/testSBS.mp4")
func load_file(file):
var stream = videoplayer.stream
stream = VideoStreamGDNative.new()
var resource = load(file)
if not "SBS" in file:
print("Disabling SBS")
$Screens/ScreenL.get_active_material(0).set_shader_param("side_by_side", false)
$Screens/ScreenR.get_active_material(0).set_shader_param("side_by_side", false)
videoplayer.set_stream(resource)
videoplayer.play()
print("Playing ", file)
func _on_file_dropped(files, screen):
print(files)
load_file(files[0])
var pos = 0
func _input(event):
if event.is_action_pressed("ui_left"):
if videoplayer.is_playing():
pos = videoplayer.stream_position
videoplayer.stream_position = 0 if pos < 5 else pos-5
else:
videoplayer.play()
videoplayer.stream_position = pos
if event.is_action_pressed("ui_right"):
if videoplayer.is_playing():
pos = videoplayer.stream_position
videoplayer.stream_position = pos + 5
else:
videoplayer.play()
videoplayer.stream_position = pos
if event.is_action_pressed("ui_down"):
if videoplayer.is_playing():
pos = videoplayer.stream_position
videoplayer.stream_position = 0 if pos < 20 else pos - 60
else:
videoplayer.play()
videoplayer.stream_position = pos
if event.is_action_pressed("ui_up"):
if videoplayer.is_playing():
pos = videoplayer.stream_position
videoplayer.stream_position = pos + 60
else:
videoplayer.play()
videoplayer.stream_position = pos
if event.is_action_pressed("ui_select"):
if videoplayer.is_playing():
pos = videoplayer.stream_position
videoplayer.stop()
else:
videoplayer.play()
videoplayer.stream_position = pos
if event.is_action_pressed("ui_page_up"):
zoom += 0.1
$Screens.translation[2] = -zoom
if event.is_action_pressed("ui_page_down"):
if zoom >= 0.2:
zoom -= 0.1
$Screens.translation[2] = -zoom
[gd_scene load_steps=14 format=2]
[ext_resource path="res://Visor.tscn" type="PackedScene" id=1]
[ext_resource path="res://world.gd" type="Script" id=2]
[sub_resource type="PlaneMesh" id=1]
size = Vector2( 1.92, 1.08 )
subdivide_width = 40
subdivide_depth = 40
[sub_resource type="Shader" id=2]
code = "shader_type spatial;
render_mode unshaded;
uniform sampler2D texture_albedo_ScreenL;
uniform bool side_by_side = true;
void vertex() {
VERTEX.y += -cos(VERTEX.x);// * cos(VERTEX.z);
}
void fragment() {
vec2 scale = vec2(1.0,2.0);
vec2 shift = vec2(0.0,0.5);
if (side_by_side){
scale = vec2(2.0,1.0);
shift = vec2(0.5,0.0);
}
vec4 tex;
if (VIEW_INDEX == VIEW_MONO_LEFT){
tex = texture(texture_albedo_ScreenL, (UV / scale));
}else{
tex = texture(texture_albedo_ScreenL, (UV / scale) + shift);
}
//tex = texture(texture_albedo_ScreenL, (UV / scale));
ALBEDO = tex.rgb;
}
"
[sub_resource type="ViewportTexture" id=12]
viewport_path = NodePath("Screens/Viewport")
[sub_resource type="ShaderMaterial" id=4]
resource_local_to_scene = true
shader = SubResource( 2 )
shader_param/side_by_side = true
shader_param/texture_albedo_ScreenL = SubResource( 12 )
[sub_resource type="PlaneMesh" id=10]
size = Vector2( 1.92, 1.08 )
subdivide_width = 40
subdivide_depth = 40
[sub_resource type="Shader" id=6]
code = "shader_type spatial;
render_mode unshaded;
uniform sampler2D texture_albedo_ScreenR;
uniform bool side_by_side = true;
void vertex() {
VERTEX.y += -cos(VERTEX.x) ;//* cos(VERTEX.z);
}
void fragment() {
vec2 scale = vec2(1.0,2.0);
vec2 shift = vec2(0.0,0.5);
if (side_by_side){
scale = vec2(2.0,1.0);
shift = vec2(0.5,0.0);
}