master
Zachary Epps 5 years ago
commit 2715a69eb3

1
.gitignore vendored

@ -0,0 +1 @@
.import/*

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2017 Ξ0xB48C3B718a1FF3a280f574Ad36F04068d7EAf498
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

@ -0,0 +1,55 @@
TrackballCamera for Godot
-------------------------
[![MIT](https://img.shields.io/github/license/Goutte/godot-trackball-camera.svg)](https://github.com/Goutte/godot-trackball-camera)
[![Release](https://img.shields.io/github/release/Goutte/godot-trackball-camera.svg)](https://github.com/Goutte/godot-trackball-camera/releases)
[![Donate](https://img.shields.io/badge/%CE%9E-%E2%99%A5-blue.svg)](https://etherscan.io/address/0xB48C3B718a1FF3a280f574Ad36F04068d7EAf498)
A simple [Godot](https://godotengine.org/) `3.x` addon that adds a `TrackballCamera` without gimbal lock.
The `TrackballCamera` responds to input from mouse, keyboard, joystick and touch, in order to rotate around its parent node while facing it.
A version for Godot `2.x` [is available as well](https://github.com/Goutte/godot-trackball-camera/releases/tag/v1.0).
Features
--------
- stays around its parent node, even if it moves
- no gimbal lock (quaternions FTW)
- camera inertia for a smoother experience
- the parent node does not have to be centered in the camera's view
- a bunch of parameters to configure everything as you want it
Install
-------
The installation is as usual, through the Assets Lib.
Then, enable the plugin in `Scene > Project Settings > Plugins`.
You can also simply copy the files of this project into yours, it should work.
Usage
-----
Make the `TrackballCamera` a child of the node to trackball around.
Make sure your camera initially faces said node, and is at a proper distance from it.
The initial position of your camera matters. The node does not need to be in the center.
You can also use this camera to look around you if you place it atop its parent node, spatially.
It's going to rotate around itself, and that amounts to looking around.
You'll probably want to set `mouseInvert` and `keyboardInvert` to true in that case.
Todo
----
- [ ] Test if touch works on android and html5, try `SCREEN_DRAG` otherwise.
Feedback and contributions are welcome!

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

@ -0,0 +1,29 @@
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/icon.png-d8104086c24314fbd510b502e5d9423c.stex"
[deps]
source_file="res://addons/goutte.camera.trackball/icon.png"
dest_files=[ "res://.import/icon.png-d8104086c24314fbd510b502e5d9423c.stex" ]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=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
stream=false
size_limit=0
detect_3d=true
svg/scale=1.0

Binary file not shown.

After

Width:  |  Height:  |  Size: 415 B

@ -0,0 +1,29 @@
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/icon_trackball_camera.png-1f67d96a7a375568005a510700dba68a.stex"
[deps]
source_file="res://addons/goutte.camera.trackball/icon_trackball_camera.png"
dest_files=[ "res://.import/icon_trackball_camera.png-1f67d96a7a375568005a510700dba68a.stex" ]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=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
stream=false
size_limit=0
detect_3d=true
svg/scale=1.0

@ -0,0 +1,126 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="16"
height="16"
version="1.1"
viewBox="0 0 16 16"
id="svg4493"
sodipodi:docname="icon_trackball_camera.svg"
inkscape:export-filename="/home/goutte/code/cyx-godot/addons/TrackballCamera/icon_trackball_camera.png"
inkscape:export-xdpi="96"
inkscape:export-ydpi="96"
inkscape:version="0.92.1 r15371">
<metadata
id="metadata4499">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs4497" />
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1920"
inkscape:window-height="1107"
id="namedview4495"
showgrid="false"
inkscape:zoom="29.5"
inkscape:cx="13.200433"
inkscape:cy="6.6601584"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="svg4493" />
<g
transform="translate(0 -1036.4)"
id="g4491">
<path
d="m9 1038.4a3 3 0 0 0 -2.9883 2.7774 3 3 0 0 0 -2.0117 -0.7774 3 3 0 0 0 -3 3 3 3 0 0 0 2 2.8243v2.1757c0 0.554 0.44599 1 1 1h6c0.55401 0 1-0.446 1-1v-1l3 2v-6l-3 2v-1.7695a3 3 0 0 0 1 -2.2305 3 3 0 0 0 -3 -3z"
id="path4489"
fill="#fc9c9c" />
</g>
<g
id="g5308"
transform="matrix(0.00720063,0,0,0.00720063,5.1086782,7.4877507)"
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-opacity:1"
inkscape:export-xdpi="418.2641"
inkscape:export-ydpi="418.2641">
<g
id="g5251"
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-opacity:1">
<g
id="language"
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-opacity:1">
<path
id="path5248"
d="M 255,0 C 114.75,0 0,114.75 0,255 0,395.25 114.75,510 255,510 395.25,510 510,395.25 510,255 510,114.75 395.25,0 255,0 Z M 430.95,153 H 357 C 349.35,119.85 336.6,91.8 321.3,61.2 367.2,79.05 408,109.65 430.95,153 Z M 255,51 c 20.4,30.6 38.25,63.75 48.45,102 h -96.9 C 216.75,117.3 234.6,81.6 255,51 Z M 58.65,306 C 53.55,290.7 51,272.85 51,255 c 0,-17.85 2.55,-35.7 7.65,-51 h 86.7 c -2.55,17.85 -2.55,33.15 -2.55,51 0,17.85 2.55,33.15 2.55,51 z m 20.4,51 H 153 c 7.65,33.15 20.4,61.2 35.7,91.8 C 142.8,430.95 102,400.35 79.05,357 Z M 153,153 H 79.05 C 104.55,109.65 142.8,79.05 188.7,61.2 173.4,91.8 160.65,119.85 153,153 Z M 255,459 C 234.6,428.4 216.75,395.25 206.55,357 h 96.9 C 293.25,392.7 275.4,428.4 255,459 Z m 58.65,-153 h -117.3 c -2.55,-17.85 -5.1,-33.15 -5.1,-51 0,-17.85 2.55,-33.15 5.1,-51 H 316.2 c 2.55,17.85 5.1,33.15 5.1,51 0,17.85 -5.1,33.15 -7.65,51 z m 7.65,142.8 C 336.6,420.75 349.35,390.151 357,357 h 73.95 C 408,400.35 367.2,430.95 321.3,448.8 Z M 367.2,306 c 2.55,-17.85 2.55,-33.15 2.55,-51 0,-17.85 -2.55,-33.15 -2.55,-51 h 86.7 c 5.1,15.3 7.649,33.15 7.649,51 0,17.85 -2.55,35.7 -7.649,51 z"
inkscape:connector-curvature="0"
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-opacity:1" />
</g>
</g>
<g
id="g5253"
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-opacity:1" />
<g
id="g5255"
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-opacity:1" />
<g
id="g5257"
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-opacity:1" />
<g
id="g5259"
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-opacity:1" />
<g
id="g5261"
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-opacity:1" />
<g
id="g5263"
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-opacity:1" />
<g
id="g5265"
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-opacity:1" />
<g
id="g5267"
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-opacity:1" />
<g
id="g5269"
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-opacity:1" />
<g
id="g5271"
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-opacity:1" />
<g
id="g5273"
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-opacity:1" />
<g
id="g5275"
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-opacity:1" />
<g
id="g5277"
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-opacity:1" />
<g
id="g5279"
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-opacity:1" />
<g
id="g5281"
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-opacity:1" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 5.1 KiB

@ -0,0 +1,29 @@
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/icon_trackball_camera.svg-87202336c371094f2871b6de2f8005f0.stex"
[deps]
source_file="res://addons/goutte.camera.trackball/icon_trackball_camera.svg"
dest_files=[ "res://.import/icon_trackball_camera.svg-87202336c371094f2871b6de2f8005f0.stex" ]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=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
stream=false
size_limit=0
detect_3d=true
svg/scale=1.0

@ -0,0 +1,7 @@
[plugin]
name="TrackballCamera"
description="A simple trackball camera that responds to input from mouse, keyboard, joystick and touch, in order to rotate around its parent node while continuously facing it. Has inertia, no gimbal lock, and can be used to look around when rotating around itself."
author="Goutte"
version="4.0"
script="trackball_camera_plugin.gd"

@ -0,0 +1,135 @@
extends Camera
# Makes this Camera respond to input from mouse, keyboard, joystick and touch,
# in order to rotate around its parent node while facing it.
# We're using quaternions, so no infamous gimbal lock.
# The camera has inertia for a smoother experience.
# todo: test if touch works on android and html5, try SCREEN_DRAG otherwise
# Requirements
# ------------
# Godot 3.x
# Usage
# -----
# Attach as script to a Camera, and make the camera a child of the node to trackball around.
# Make sure your camera initially faces said node, and is at a proper distance from it.
# The initial position of your camera matters. The node does not need to be in the center.
# You can also use this camera to look around you if you place it atop its parent node, spatially.
# It's going to rotate around itself, and that amounts to looking around.
# You'll probably want to set mouseInvert and keyboardInvert to true in that case.
# License
# -------
# Same as Godot, ie. permissive MIT. (https://godotengine.org/license)
# If you feel generous and want to feed me so I can math more of those,
# I enjoy the taste of ETH Ξ 0xB48C3B718a1FF3a280f574Ad36F04068d7EAf498
# You can blame antoine@goutenoir.com for the bugs, crashes and burns.
# Seriously, useful feedback is always appreciated we can't test everything.
export var mouseEnabled = true
export var mouseInvert = false
export var mouseStrength = 1.111
export var keyboardEnabled = true
export var keyboardInvert = false
export var keyboardStrength = 1.111
export var joystickEnabled = true
export var joystickInvert = false
export var joystickStrength = 1.111
export var joystickThreshold = 0.09 # the resting state of my joystick's x-axis is -0.05 T.T
export var joystickDevice = 0
export var inertiaStrength = 1.0 # multiplier applied to all strengths
export(float, 0, 1, 0.005) var friction = 0.07
var _iKnowWhatIAmDoing = false # should we skip assertions?
var _cameraUp = Vector3(0, 1, 0)
var _cameraRight = Vector3(1, 0, 0)
var _epsilon = 0.0001
var _mouseDragStart
var _mouseDragPosition
var _dragInertia = Vector2(0, 0)
func _ready():
set_process_input(true)
set_process(true)
# It's best to catch future divisions by 0 before they happen.
# Note that we don't need this check if the mouse support is disabled.
# In case you know what you're doing, there's a property you can change.
assert _iKnowWhatIAmDoing or get_viewport().get_visible_rect().get_area()
#print("Trackball Camera around %s is ready. ♥" % get_parent().get_name())
func _input(ev):
if mouseEnabled and ev is InputEventMouseButton:
if ev.pressed:
_mouseDragStart = getNormalizedMousePosition()
else:
_mouseDragStart = null
_mouseDragPosition = _mouseDragStart
func _process(delta):
if mouseEnabled and _mouseDragPosition != null:
var _currentDragPosition = getNormalizedMousePosition()
_dragInertia += (_currentDragPosition - _mouseDragPosition) \
* mouseStrength * (-0.1 if mouseInvert else 0.1)
_mouseDragPosition = _currentDragPosition
if keyboardEnabled:
var key_i = -1 if keyboardInvert else 1
var key_s = keyboardStrength / 1000.0 # exported floats get truncated
if Input.is_key_pressed(KEY_LEFT):
_dragInertia += Vector2(key_i * key_s, 0)
if Input.is_key_pressed(KEY_RIGHT):
_dragInertia += Vector2(-1 * key_i * key_s, 0)
if Input.is_key_pressed(KEY_UP):
_dragInertia += Vector2(0, key_i * key_s)
if Input.is_key_pressed(KEY_DOWN):
_dragInertia += Vector2(0, -1 * key_i * key_s)
if joystickEnabled:
var joy_h = Input.get_joy_axis(joystickDevice, 0) # left stick horizontal
var joy_v = Input.get_joy_axis(joystickDevice, 1) # left stick vertical
var joy_i = -1 if joystickInvert else 1
var joy_s = joystickStrength / 1000.0 # exported floats get truncated
if abs(joy_h) > joystickThreshold:
_dragInertia += Vector2(joy_i * joy_h * joy_h * sign(joy_h) * joy_s, 0)
if abs(joy_v) > joystickThreshold:
_dragInertia += Vector2(0, joy_i * joy_v * joy_v * sign(joy_v) * joy_s)
var inertia = _dragInertia.length()
if inertia > _epsilon:
applyRotationFromTangent(_dragInertia * inertiaStrength)
_dragInertia = _dragInertia * (1 - friction)
elif inertia > 0:
_dragInertia.x = 0
_dragInertia.y = 0
# Convenience method for you to move the camera around.
# inertia is a Vector2 in the normalized right-handed x/y of the screen.
func addInertia(inertia):
_dragInertia += inertia
func getNormalizedMousePosition():
return get_viewport().get_mouse_position() / get_viewport().get_visible_rect().size
func applyRotationFromTangent(tangent):
var tr = get_transform() # not get_camera_transform, unsure why
var up = tr.basis.xform(_cameraUp)
var rg = tr.basis.xform(_cameraRight)
var upQuat = Quat(up, -1 * tangent.x * TAU)
var rgQuat = Quat(rg, -1 * tangent.y * TAU)
set_transform(Transform(upQuat * rgQuat) * tr) # money shot!

@ -0,0 +1,12 @@
tool
extends EditorPlugin
func _enter_tree():
add_custom_type(
"TrackballCamera", "Camera",
preload("res://addons/goutte.camera.trackball/trackball_camera.gd"),
preload("res://addons/goutte.camera.trackball/icon_trackball_camera.png")
)
func _exit_tree():
remove_custom_type("TrackballCamera")

@ -0,0 +1,101 @@
[gd_resource type="Environment" load_steps=2 format=2]
[sub_resource type="ProceduralSky" id=1]
radiance_size = 4
sky_top_color = Color( 0.0470588, 0.454902, 0.976471, 1 )
sky_horizon_color = Color( 0.556863, 0.823529, 0.909804, 1 )
sky_curve = 0.25
sky_energy = 1.0
ground_bottom_color = Color( 0.101961, 0.145098, 0.188235, 1 )
ground_horizon_color = Color( 0.482353, 0.788235, 0.952941, 1 )
ground_curve = 0.01
ground_energy = 1.0
sun_color = Color( 1, 1, 1, 1 )
sun_latitude = 35.0
sun_longitude = 0.0
sun_angle_min = 1.0
sun_angle_max = 100.0
sun_curve = 0.05
sun_energy = 16.0
texture_size = 2
[resource]
background_mode = 2
background_sky = SubResource( 1 )
background_sky_custom_fov = 0.0
background_color = Color( 0, 0, 0, 1 )
background_energy = 1.0
background_canvas_max_layer = 0
ambient_light_color = Color( 0, 0, 0, 1 )
ambient_light_energy = 1.0
ambient_light_sky_contribution = 1.0
fog_enabled = false
fog_color = Color( 0.5, 0.6, 0.7, 1 )
fog_sun_color = Color( 1, 0.9, 0.7, 1 )
fog_sun_amount = 0.0
fog_depth_enabled = true
fog_depth_begin = 10.0
fog_depth_curve = 1.0
fog_transmit_enabled = false
fog_transmit_curve = 1.0
fog_height_enabled = false
fog_height_min = 0.0
fog_height_max = 100.0
fog_height_curve = 1.0
tonemap_mode = 0
tonemap_exposure = 1.0
tonemap_white = 1.0
auto_exposure_enabled = false
auto_exposure_scale = 0.4
auto_exposure_min_luma = 0.05
auto_exposure_max_luma = 8.0
auto_exposure_speed = 0.5
ss_reflections_enabled = false
ss_reflections_max_steps = 64
ss_reflections_fade_in = 0.15
ss_reflections_fade_out = 2.0
ss_reflections_depth_tolerance = 0.2
ss_reflections_roughness = true
ssao_enabled = false
ssao_radius = 1.0
ssao_intensity = 1.0
ssao_radius2 = 0.0
ssao_intensity2 = 1.0
ssao_bias = 0.01
ssao_light_affect = 0.0
ssao_color = Color( 0, 0, 0, 1 )
ssao_quality = 0
ssao_blur = 3
ssao_edge_sharpness = 4.0
dof_blur_far_enabled = false
dof_blur_far_distance = 10.0
dof_blur_far_transition = 5.0
dof_blur_far_amount = 0.1
dof_blur_far_quality = 1
dof_blur_near_enabled = false
dof_blur_near_distance = 2.0
dof_blur_near_transition = 1.0
dof_blur_near_amount = 0.1
dof_blur_near_quality = 1
glow_enabled = false
glow_levels/1 = false
glow_levels/2 = false
glow_levels/3 = true
glow_levels/4 = false
glow_levels/5 = true
glow_levels/6 = false
glow_levels/7 = false
glow_intensity = 0.8
glow_strength = 1.0
glow_bloom = 0.0
glow_blend_mode = 2
glow_hdr_threshold = 1.0
glow_hdr_scale = 2.0
glow_bicubic_upscale = false
adjustment_enabled = false
adjustment_brightness = 1.0
adjustment_contrast = 1.0
adjustment_saturation = 1.0

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

@ -0,0 +1,29 @@
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/icon.png-487276ed1e3a0c39cad0279d744ee560.stex"
[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/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
stream=false
size_limit=0
detect_3d=true
svg/scale=1.0

@ -0,0 +1,22 @@
; 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=3
[application]
config/name="RE_Multi"
config/icon="res://icon.png"
[editor_plugins]
enabled=PoolStringArray( "goutte.camera.trackball" )
[rendering]
environment/default_environment="res://default_env.tres"

File diff suppressed because one or more lines are too long
Loading…
Cancel
Save