Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 23 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,31 @@ Godot Camera Plugin (For 3.2 and and above)

A plugin for displaying native camera preview in @godotengine (currently Android only)

## How to build:
You can follow these steps to build a new release of the plugin.

Prerequisites:
- Android SDK (platform version 29)
- the Godot Android library (`godot-lib.***.release.aar`) for your version of Godot from the [downloads page](https://godotengine.org/download).

Plugin build steps:
1. Clone this Git repository
2. Put `godot-lib.***.release.aar` in `./android/godot-camera-plugin/libs`
3. Run `gradlew build` in `./android`
4. Output `.aar` files are located in `./android/godot-camera-plugin/build/outputs/aar`

## How to use:
Make sure you are running godotengine version 3.2 or above and that your project have been setup for exporting with [custom Android template](https://docs.godotengine.org/en/latest/getting_started/workflow/export/android_custom_build.html).
Make sure you are running godotengine version 3.2 or above and that your project have been setup for exporting with [Android custom builds](https://docs.godotengine.org/en/stable/getting_started/workflow/export/android_custom_build.html#doc-android-custom-build).

Editor add-on installation:
1. Copy `./addons` folder into the project root
2. Open `Project Settings > Plugins` and enable the camera plugin

Download and incude the plugin in your project, then enable it from the Plugin tab in your project settings.
Android plugin installation:
1. Copy `FunababCameraPlugin.gdap` to `android/plugins` in the project folder
2. Copy `FunababCameraPlugin.***.aar` files to `android/plugins` in the project folder
3. In the Android preset, enable `Plugins > Funabab Camera Plugin`
4. In the Android preset, enable `Permissions > Camera`

A custom godot control (**CameraView**) is provided which serve as a dummy view for communicating with the *real native camera preview*.

Expand Down
65 changes: 34 additions & 31 deletions addons/godot-camera-plugin.funabab/camera_view.gd
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ extends Control

const CameraViewNativeBridge = preload("camera_view_native_bridge.gd").CameraViewNativeBridge;
const ERROR_FATAL = 1;
const ICON_CAMERA = preload("icon_camera.png");
const COLOR_BG = Color.black;

enum ERROR {
Expand All @@ -28,9 +27,11 @@ export(int, "Auto", "HDR", "Portrait", "Landscape", "Night", "Sunset") var scene
export(int, "Auto", "Incandesent", "Flourescent", "Daylight", "Twilight", "Shade") var white_balanace := 0 setget set_white_balanace;
export(int, "None", "Mono", "Negative", "Solarize", "Sepia") var color_effect := 0 setget set_color_effect;

var cameraViewBridge setget __set_blank__, __get_blank__;
var is_initialized : bool = false setget __set_blank__;
var camera_permission_granted = false setget __set_blank__, __get_blank__;
var cameraViewBridge
var is_initialized : bool = false
var camera_permission_granted = false

var camera_icon = load("res://addons/godot-camera-plugin.funabab/icon_camera.png");

signal picture_taken; # @parameters: error_code, image_texture, extra
signal initialized;
Expand Down Expand Up @@ -70,17 +71,38 @@ func take_picture(minimum_number_of_face = 0):
cameraViewBridge.take_picture(minimum_number_of_face);
pass

func _ready():
get_tree().connect("on_request_permissions_result", self, "_on_permission_result");
pass

func _on_permission_result(permission, granted):
print("permission '%s' result: %s" % [permission, granted]);
if (permission.ends_with("CAMERA")):
camera_permission_granted = granted;
if !is_initialized && camera_permission_granted:
_initialize_camera();
pass

func _initialize_camera():
print("initialize camera");
var CameraViewNativeBridge = preload("camera_view_native_bridge.gd");
cameraViewBridge = CameraViewNativeBridge.initialize(self);
is_initialized = true;
pass

func _draw():
if !draw_camera_splash: return;

var rect = get_rect();
rect.position = Vector2.ZERO;

var icon_size = rect.size.x * .3;
var size = Vector2(icon_size / ICON_CAMERA.get_width(),
icon_size / ICON_CAMERA.get_width());
var size = Vector2(icon_size / camera_icon.get_width(),
icon_size / camera_icon.get_width());

draw_rect(rect, COLOR_BG);
draw_set_transform((rect.size - (size * ICON_CAMERA.get_width())) / 2, 0, size);
draw_texture(ICON_CAMERA, Vector2(0, 0),
draw_set_transform((rect.size - (size * camera_icon.get_width())) / 2, 0, size);
draw_texture(camera_icon, Vector2.ZERO,
Color.red if is_initialized else Color.white);
pass

Expand All @@ -92,24 +114,13 @@ func _notification(what):

if what == NOTIFICATION_ENTER_TREE:
if OS.get_name() == "Android":
print("requesting camera permission...");
camera_permission_granted = OS.request_permission("CAMERA");
if camera_permission_granted == false:
# Camera will proberly not start due to permission not granted

# give users some time to grant permission
yield(get_tree().create_timer(2), "timeout");
prints("Godot: restart?");
get_tree().reload_current_scene(); # lets reload and try again
elif what == NOTIFICATION_RESIZED:
if !is_initialized && camera_permission_granted:
# yield(get_tree(), "idle_frame");
var CameraViewNativeBridge = preload("camera_view_native_bridge.gd");
cameraViewBridge = CameraViewNativeBridge.initialize(self);
is_initialized = true;
else:
if cameraViewBridge != null:
cameraViewBridge.resize_view(get_global_rect());

_initialize_camera();
elif cameraViewBridge != null:
cameraViewBridge.resize_view(get_global_rect());
update();
elif what == NOTIFICATION_VISIBILITY_CHANGED:
if cameraViewBridge != null:
Expand All @@ -136,14 +147,6 @@ func __get_parameters__()->Dictionary:
}
pass

func __set_blank__(value):
# do nothing...
pass

func __get_blank__():
# do nothing...
pass

func set_camera_facing(value):
camera_facing = value;
if cameraViewBridge != null:
Expand Down
12 changes: 10 additions & 2 deletions addons/godot-camera-plugin.funabab/camera_view_native_bridge.gd
Original file line number Diff line number Diff line change
Expand Up @@ -111,13 +111,21 @@ static func initialize(node: Control)->CameraViewNativeBridge:
var instanse_id = node.get_instance_id();
if Engine.has_singleton(SINGLETON_NAME):
var plugin = Engine.get_singleton(SINGLETON_NAME);
var r : Rect2= node.get_global_rect();
var r : Rect2 = node.get_global_rect();
var s : Vector2 = Vector2.ONE;

var parent = node.get_parent_control();
if parent:
var parent_r = parent.get_global_rect()
s = r.size / parent_r.size
r.size = parent_r.size
r.position -= r.size * 0.5

var cameraViewNativeBridge = CameraViewNativeBridge.new(plugin, node);
var result = plugin.initializeView(cameraViewNativeBridge.get_instance_id(),
node.get_camera_facing(), ParameterSerializer.serialize(node.__get_parameters__()),
int(r.position.x), int(r.position.y),
int(r.size.x), int(r.size.y), node.visible);
int(r.size.x), int(r.size.y), s.x, s.y, node.visible);

if result == true:
return cameraViewNativeBridge;
Expand Down
34 changes: 34 additions & 0 deletions addons/godot-camera-plugin.funabab/icon_camera.png.import
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
[remap]

importer="texture"
type="StreamTexture"
path="res://.import/icon_camera.png-b2668087f7e7255e71cd8888d15ae040.stex"
metadata={
"vram_texture": false
}

[deps]

source_file="res://addons/godot-camera-plugin.funabab/icon_camera.png"
dest_files=[ "res://.import/icon_camera.png-b2668087f7e7255e71cd8888d15ae040.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
stream=false
size_limit=0
detect_3d=true
svg/scale=1.0
34 changes: 34 additions & 0 deletions addons/godot-camera-plugin.funabab/icon_node.png.import
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
[remap]

importer="texture"
type="StreamTexture"
path="res://.import/icon_node.png-30f8f9efd25c6739f8122fe2bfd0aae8.stex"
metadata={
"vram_texture": false
}

[deps]

source_file="res://addons/godot-camera-plugin.funabab/icon_node.png"
dest_files=[ "res://.import/icon_node.png-30f8f9efd25c6739f8122fe2bfd0aae8.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
stream=false
size_limit=0
detect_3d=true
svg/scale=1.0
2 changes: 1 addition & 1 deletion addons/godot-camera-plugin.funabab/plugin.gd
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ const ANDROID_MODULE = "org/godotengine/godot/funabab/camera/FunababCameraPlugin
const CUSTOM_NODE_NAME = "CameraView";

func _enter_tree():
add_custom_type(CUSTOM_NODE_NAME, "Control", preload("camera_view.gd"), preload("icon_node.png"));
add_custom_type(CUSTOM_NODE_NAME, "Control", preload("camera_view.gd"), load("res://addons/godot-camera-plugin.funabab/icon_node.png"));
pass

func _exit_tree():
Expand Down
75 changes: 75 additions & 0 deletions android/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
# Built application files
*.apk
*.aar
*.ap_
*.aab

# Files for the ART/Dalvik VM
*.dex

# Java class files
*.class

# Generated files
bin/
gen/
out/
# Uncomment the following line in case you need and you don't have the release build type files in your app
# release/

# Gradle files
.gradle/
build/

# Local configuration file (sdk path, etc)
local.properties

# Proguard folder generated by Eclipse
proguard/

# Log Files
*.log

# Android Studio Navigation editor temp files
.navigation/

# Android Studio captures folder
captures/

# IntelliJ
*.iml
.idea

# Keystore files
# Uncomment the following lines if you do not want to check your keystore files in.
#*.jks
#*.keystore

# External native build folder generated in Android Studio 2.2 and later
.externalNativeBuild
.cxx/

# Google Services (e.g. APIs or Firebase)
# google-services.json

# Freeline
freeline.py
freeline/
freeline_project_description.json

# fastlane
fastlane/report.xml
fastlane/Preview.html
fastlane/screenshots
fastlane/test_output
fastlane/readme.md

# Version control
vcs.xml

# lint
lint/intermediates/
lint/generated/
lint/outputs/
lint/tmp/
# lint/reports/
5 changes: 5 additions & 0 deletions android/FunababCameraPlugin.gdap
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[config]

name="FunababCameraPlugin"
binary_type="local"
binary="FunababCameraPlugin.1.0.0.release.aar"
24 changes: 24 additions & 0 deletions android/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
google()
jcenter()
}
dependencies {
classpath "com.android.tools.build:gradle:4.0.0"

// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}

allprojects {
repositories {
google()
jcenter()
}
}

task clean(type: Delete) {
delete rootProject.buildDir
}
2 changes: 0 additions & 2 deletions android/godot-camera-plugin.funabab/AndroidManifest.conf

This file was deleted.

29 changes: 29 additions & 0 deletions android/godot-camera-plugin/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
plugins {
id 'com.android.library'
}

ext.pluginVersionCode = 1
ext.pluginVersionName = "1.0.0"

android {
compileSdkVersion 29
buildToolsVersion "29.0.3"

defaultConfig {
minSdkVersion 18
targetSdkVersion 29
versionCode pluginVersionCode
versionName pluginVersionName
}

libraryVariants.all { variant ->
variant.outputs.all { output ->
output.outputFileName = "FunababCameraPlugin.$pluginVersionName.${variant.name}.aar"
}
}
}

dependencies {
implementation "androidx.legacy:legacy-support-v4:1.0.0"
compileOnly fileTree(dir: 'libs', include: ['godot-lib*.aar'])
}
11 changes: 11 additions & 0 deletions android/godot-camera-plugin/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.godotengine.godot.plugin.godotcameraplugin">

<application>

<meta-data
android:name="org.godotengine.plugin.v1.FunababCameraPlugin"
android:value="org.godotengine.godot.plugin.godotcameraplugin.FunababCameraPlugin" />

</application>
</manifest>
Loading