├── .gitignore
├── .gitmodules
├── .idea
└── runConfigurations
│ ├── assembleDebug.xml
│ └── assembleRelease.xml
├── README.md
├── app
├── .gitignore
├── build.gradle
└── src
│ └── main
│ ├── AndroidManifest.xml
│ └── cpp
│ ├── CMakeLists.txt
│ ├── Engine
│ ├── API
│ │ ├── API.cpp
│ │ ├── API.h
│ │ ├── Color.hpp
│ │ ├── Matrix4x4.hpp
│ │ ├── Quaternion.hpp
│ │ ├── Rect.hpp
│ │ ├── Unity.h
│ │ ├── Vector2.hpp
│ │ └── Vector3.hpp
│ ├── Includes.hpp
│ └── Structure
│ │ ├── CBaseEntry.cpp
│ │ ├── CBaseEntry.hpp
│ │ ├── ExampleEntry.cpp
│ │ └── ExampleEntry.hpp
│ ├── Utils
│ └── Logger.h
│ └── native-lib.cpp
├── build.gradle
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
└── settings.gradle
/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .gradle
3 | /local.properties
4 | /.idea/caches
5 | /.idea/libraries
6 | /.idea/modules.xml
7 | /.idea/workspace.xml
8 | /.idea/navEditor.xml
9 | /.idea/assetWizardSettings.xml
10 | /.idea/.gitignore
11 | /.idea/.name
12 | /.idea/compiler.xml
13 | /.idea/discord.xml
14 | /.idea/gradle.xml
15 | /.idea/misc.xml
16 | .DS_Store
17 | /build
18 | /captures
19 | .externalNativeBuild
20 | .cxx
21 | local.properties
22 | /.idea/vcs.xml
23 |
--------------------------------------------------------------------------------
/.gitmodules:
--------------------------------------------------------------------------------
1 | [submodule "app/src/main/cpp/External/Dobby"]
2 | path = app/src/main/cpp/External/Dobby
3 | url = https://github.com/LSPosed/Dobby
4 | [submodule "app/src/main/cpp/External/KittyMemory"]
5 | path = app/src/main/cpp/External/KittyMemory
6 | url = https://github.com/MJx0/KittyMemory
7 |
--------------------------------------------------------------------------------
/.idea/runConfigurations/assembleDebug.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
11 |
16 |
17 |
18 | true
19 | true
20 | false
21 |
22 |
23 |
--------------------------------------------------------------------------------
/.idea/runConfigurations/assembleRelease.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 | true
19 | true
20 | false
21 |
22 |
23 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ## Android Native Mod Template
2 |
3 | A minimal native only template for Android modding.
4 |
5 | ### Background
6 |
7 | Recently i wanted to begin doing again some Android modding, but i didn't want to use any of the
8 | existing frameworks, since it messy and i don't like it.
9 | So i created this template to make it easier for me to start a new project.
10 |
11 | ### How To Use
12 |
13 | 1. Clone the repo
14 | 2. Open the project in Android Studio / Visual Studio Code
15 | 3. Change the package name in `app/build.gradle` and library name
16 | in `app/src/main/cpp/CMakeLists.txt`
17 | 4. Start coding
18 | 5. Build the project
19 | 6. Copy the generated .so from `app/build/outputs/native/{debug/release}/lib{template}.so`
20 | 7. Load the library in your modded app
21 | You can use many various methods to load the library, see [Injecting the library](#injecting-the-library)
22 |
23 | ### Injecting the library
24 | This project is merely a template, so you can use any method you want to load the library.
25 | Here are some examples:
26 | Note: Modify "**template**" to your library name
27 |
28 | - #### [Android-Ptrace-Injector - reveny](https://github.com/reveny/Android-Ptrace-Injector)
29 | ```bash
30 | ./Injector -p "com.target.package" -l "template"
31 | ```
32 |
33 | - #### [System.loadLibrary](https://docs.oracle.com/javase/8/docs/api/java/lang/System.html#loadLibrary-java.lang.String)
34 | ```java
35 | const-string v0, "template"
36 |
37 | invoke-static {v0}, Ljava/lang/System;->loadLibrary(Ljava/lang/String;)V
38 | ```
39 |
40 | - #### [xDL - hexhacking](https://github.com/hexhacking/xDL)
41 | ```c
42 | void* handle = xdl_open("template", RTLD_NOW);
43 | ```
44 |
45 | - #### Other methods
46 | As long as you can load the library into the target process, you can use any method you want.
47 |
48 | ### To-Do
49 | - [x] Polymorphism design pattern
50 | - [x] Unity API (Vector2, Vector3, Quaternion, etc)
51 | - [x] Doc: How to use
52 | - [ ] Doc: What need to be changed
53 | - [ ] Doc: What each file does
54 | - [ ] Doc: How to add new functions
55 | - [ ] Doc: How to add new classes
56 |
57 | ### Credit
58 |
59 | - [Dobby](https://github.com/jmpews/Dobby) - Hooking library
60 | - [KittyMemory](https://github.com/MJx0/KittyMemory) - Android, IOS runtime code patching library
61 |
--------------------------------------------------------------------------------
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | plugins {
2 | id 'com.android.library'
3 | }
4 |
5 | android {
6 | namespace 'com.cheat.template'
7 | compileSdk 34
8 |
9 | defaultConfig {
10 | minSdk 24
11 | targetSdk 34
12 | versionCode 1
13 | versionName "1.0"
14 | }
15 |
16 | compileOptions {
17 | sourceCompatibility JavaVersion.VERSION_1_8
18 | targetCompatibility JavaVersion.VERSION_1_8
19 | }
20 |
21 | externalNativeBuild {
22 | cmake {
23 | path file('src/main/cpp/CMakeLists.txt')
24 | version '3.22.1'
25 | }
26 | }
27 |
28 | buildFeatures {
29 | aidl false
30 | viewBinding false
31 | buildConfig false
32 | }
33 | }
34 |
35 | afterEvaluate {
36 | android.libraryVariants.forEach { variant ->
37 | def variantCapped = variant.name.capitalize()
38 | def variantLowered = variant.name.toLowerCase()
39 |
40 | // Windows
41 | def strippedLibs = file("$buildDir/intermediates/stripped_native_libs/$variantLowered/out/lib")
42 | if (!strippedLibs.exists() || !strippedLibs.directory) {
43 | // Linux
44 | strippedLibs = file("$buildDir/intermediates/stripped_native_libs/${variant.name}/out/lib")
45 | }
46 |
47 | tasks.register("copyOutputNative${variantCapped}", Sync) {
48 | dependsOn("assemble$variantCapped")
49 | from(strippedLibs) {
50 | include "**/*.so"
51 | }
52 | into file("$buildDir/outputs/native/${variant.name}")
53 | }
54 |
55 | variant.assembleProvider.get().finalizedBy("copyOutputNative${variantCapped}")
56 | }
57 | }
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/src/main/cpp/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 3.22.1)
2 |
3 | # set the project name
4 | project("template")
5 |
6 | # Dobby setup
7 | macro(SET_OPTION option value)
8 | set(${option} ${value} CACHE INTERNAL "" FORCE)
9 | endmacro()
10 |
11 | SET_OPTION(DOBBY_GENERATE_SHARED OFF)
12 | SET_OPTION(Plugin.SymbolResolver OFF)
13 | add_subdirectory(External/Dobby)
14 |
15 | # KittyMemory setup
16 | add_compile_definitions(kNO_KEYSTONE)
17 | file(GLOB_RECURSE KITTY_MEMORY_SOURCES External/KittyMemory/KittyMemory/*.cpp)
18 |
19 | # Engine setup
20 | file(GLOB_RECURSE ENGINE_SOURCES Engine/Structure/*.cpp)
21 | file(GLOB_RECURSE ENGINE_HEADER_SOURCES Engine/Structure/*.hpp)
22 |
23 | add_library(${CMAKE_PROJECT_NAME} SHARED
24 | native-lib.cpp
25 | Engine/API/API.cpp
26 | ${ENGINE_SOURCES}
27 | ${KITTY_MEMORY_SOURCES})
28 |
29 | target_include_directories(${CMAKE_PROJECT_NAME} PUBLIC
30 | External/Dobby/include
31 | External/KittyMemory
32 | Utils)
33 |
34 | target_link_libraries(${CMAKE_PROJECT_NAME} log dobby)
35 |
--------------------------------------------------------------------------------
/app/src/main/cpp/Engine/API/API.cpp:
--------------------------------------------------------------------------------
1 | //
2 | // Created by aimar on 12/28/2019.
3 | //
4 |
5 | #include "API.h"
6 | #include
7 | #include
8 | #include
9 |
10 | namespace {
11 | const void *(*il2cpp_assembly_get_image)(const void *assembly);
12 |
13 | void *(*il2cpp_domain_get)();
14 |
15 | void **(*il2cpp_domain_get_assemblies)(const void *domain, size_t *size);
16 |
17 | const char *(*il2cpp_image_get_name)(void *image);
18 |
19 | void *(*il2cpp_class_from_name)(const void *image, const char *namespaze, const char *name);
20 |
21 | void *(*il2cpp_class_get_property_from_name)(void *klass, const char *name);
22 |
23 | void *(*il2cpp_class_get_field_from_name)(void *klass, const char *name);
24 |
25 | void *(*il2cpp_class_get_method_from_name)(void *klass, const char *name, int argsCount);
26 |
27 | void *(*il2cpp_runtime_invoke)(void* method, void* obj, void** params, void* exec);
28 |
29 | void *(*il2cpp_property_get_get_method)(void *prop);
30 |
31 | void *(*il2cpp_property_get_set_method)(void *prop);
32 |
33 | size_t (*il2cpp_field_get_offset)(void *field);
34 |
35 | void (*il2cpp_field_static_get_value)(void *field, void *value);
36 |
37 | void (*il2cpp_field_static_set_value)(void *field, void *value);
38 |
39 | void *(*il2cpp_array_new)(void *elementTypeInfo, size_t length);
40 |
41 | int32_t (*il2cpp_string_length)(void *str);
42 |
43 | char16_t *(*il2cpp_string_chars)(void *str);
44 |
45 | void* (*il2cpp_string_new)(const char* str);
46 |
47 | char *(*il2cpp_type_get_name)(void *type);
48 |
49 | void* (*il2cpp_method_get_param)(void *method, uint32_t index);
50 |
51 | void* (*il2cpp_class_get_methods)(void *klass, void* *iter);
52 |
53 | const char* (*il2cpp_method_get_name)(void *method);
54 |
55 | void *(*il2cpp_class_get_interfaces)(void *klass, void **iter);
56 |
57 | const char *(*il2cpp_class_get_name)(void *klass);
58 |
59 | void *(*il2cpp_class_from_type)(int);
60 |
61 | int (*il2cpp_class_get_type)(void *);
62 |
63 | void *(*il2cpp_class_get_parent)(void *);
64 |
65 | void *(*il2cpp_class_get_declaring_type)(void *);
66 |
67 | void *(*il2cpp_class_get_nested_types)(void *, void **);
68 |
69 | void *(*il2cpp_object_new)(void *);
70 | }
71 | // ================================================================================================================ //
72 | void *getExportFunction(void *handle, const char *name)
73 | {
74 | void *fn = dlsym(handle, name);
75 | if (fn) {
76 | return fn;
77 | }
78 |
79 | LOGI("%s: %p %s", __FUNCTION__, handle, name);
80 | return nullptr;
81 | }
82 |
83 | int init(void *handle)
84 | {
85 | il2cpp_assembly_get_image = (const void *(*)(const void *)) getExportFunction(handle, "il2cpp_assembly_get_image");
86 |
87 | il2cpp_domain_get = (void *(*)()) getExportFunction(handle, "il2cpp_domain_get");
88 |
89 | il2cpp_domain_get_assemblies = (void **(*)(const void* , size_t*)) getExportFunction(handle, "il2cpp_domain_get_assemblies");
90 |
91 | il2cpp_image_get_name = (const char *(*)(void *)) getExportFunction(handle, "il2cpp_image_get_name");
92 |
93 | il2cpp_class_from_name = (void* (*)(const void*, const char*, const char *)) getExportFunction(handle, "il2cpp_class_from_name");
94 |
95 | il2cpp_class_get_property_from_name = (void* (*)(void *, const char *)) getExportFunction(handle, "il2cpp_class_get_property_from_name");;
96 |
97 | il2cpp_class_get_field_from_name = (void* (*)(void*, const char *)) getExportFunction(handle, "il2cpp_class_get_field_from_name");;
98 |
99 | il2cpp_class_get_method_from_name = (void* (*)(void *, const char*, int)) getExportFunction(handle, "il2cpp_class_get_method_from_name");
100 |
101 | il2cpp_runtime_invoke = (void *(*)(void* , void* , void** , void*)) getExportFunction(handle, "il2cpp_runtime_invoke");
102 |
103 | il2cpp_property_get_get_method = (void* (*)(void *)) getExportFunction(handle, "il2cpp_property_get_get_method");;
104 |
105 | il2cpp_property_get_set_method = (void* (*)(void *)) getExportFunction(handle, "il2cpp_property_get_set_method");;
106 |
107 | il2cpp_field_get_offset = (size_t (*)(void *)) getExportFunction(handle, "il2cpp_field_get_offset");;
108 |
109 | il2cpp_field_static_get_value = (void (*)(void*, void *)) getExportFunction(handle, "il2cpp_field_static_get_value");;
110 |
111 | il2cpp_field_static_set_value = (void (*)(void*, void *)) getExportFunction(handle, "il2cpp_field_static_set_value");;
112 |
113 | il2cpp_array_new = (void *(*)(void*, size_t)) getExportFunction(handle, "il2cpp_array_new");;
114 |
115 | il2cpp_string_chars = (char16_t *(*)(void*)) getExportFunction(handle, "il2cpp_string_chars");;
116 |
117 | il2cpp_string_length = (int32_t (*)(void*)) getExportFunction(handle, "il2cpp_string_length");;
118 |
119 | il2cpp_string_new = (void *(*)(const char *)) getExportFunction(handle, "il2cpp_string_new");;
120 |
121 | il2cpp_type_get_name = (char *(*)(void *)) getExportFunction(handle, "il2cpp_type_get_name");;
122 |
123 | il2cpp_method_get_param = (void *(*)(void *, uint32_t)) getExportFunction(handle, "il2cpp_method_get_param");;
124 |
125 | il2cpp_class_get_methods = (void *(*)(void *, void **)) getExportFunction(handle, "il2cpp_class_get_methods");;
126 |
127 | il2cpp_method_get_name = (const char *(*)(void *)) getExportFunction(handle, "il2cpp_method_get_name");;
128 |
129 | il2cpp_class_get_interfaces = (void *(*)(void *, void **)) getExportFunction(handle, "il2cpp_class_get_interfaces");;
130 |
131 | il2cpp_class_get_name = (const char *(*)(void *)) getExportFunction(handle, "il2cpp_class_get_name");
132 |
133 | il2cpp_class_from_type = (void *(*)(int)) getExportFunction(handle, "il2cpp_class_from_type");
134 |
135 | il2cpp_class_get_type = (int (*)(void *)) getExportFunction(handle, "il2cpp_class_get_type");
136 |
137 | il2cpp_class_get_parent = (void *(*)(void *)) getExportFunction(handle, "il2cpp_class_get_parent");
138 |
139 | il2cpp_class_get_declaring_type = (void *(*)(void *)) getExportFunction(handle, "il2cpp_class_get_declaring_type");
140 |
141 | il2cpp_class_get_nested_types = (void *(*)(void *, void **)) getExportFunction(handle, "il2cpp_class_get_nested_types");
142 |
143 | il2cpp_object_new = (void *(*)(void *)) getExportFunction(handle, "il2cpp_object_new");
144 |
145 | return 0;
146 | }
147 | // ================================================================================================================ //
148 | int Il2Cpp::Init(const char *lib) {
149 | if(!lib) return -1;
150 |
151 | return init(dlopen(lib, 4));
152 |
153 | }
154 | // ================================================================================================================ //
155 | int Il2Cpp::Init(void *handle) {
156 | if(!handle) return -1;
157 |
158 | return init(handle);
159 |
160 | }
161 | // ================================================================================================================ //
162 | void *Il2Cpp::GetImageByName(const char *image) {
163 | size_t size;
164 | void **assemblies = il2cpp_domain_get_assemblies(il2cpp_domain_get(), &size);
165 | for(int i = 0; i < size; ++i)
166 | {
167 | void *img = (void *)il2cpp_assembly_get_image(assemblies[i]);
168 |
169 | const char *img_name = il2cpp_image_get_name(img);
170 |
171 | if(strcmp(img_name, image) == 0)
172 | {
173 | return img;
174 | }
175 | }
176 | return nullptr;
177 | }
178 | // ================================================================================================================ //
179 | void Il2Cpp::GetStaticFieldValue(const char *image, const char *namespaze, const char *clazz, const char *name, void *output) {
180 | void *img = GetImageByName(image);
181 | if(!img) {
182 | LOGI("Can't find image %s!", image);
183 | return;
184 | }
185 | void *klass = GetClassType(image, namespaze, clazz);
186 | if(!klass) {
187 | LOGI("Can't find class %s for field %s!", clazz, name);
188 | return;
189 | }
190 |
191 | void *field = il2cpp_class_get_field_from_name(klass, name);
192 | if(!field) {
193 | LOGI("Can't find field %s in class %s!", name, clazz);
194 | return;
195 | }
196 |
197 | il2cpp_field_static_get_value(field, output);
198 | }
199 | // ================================================================================================================ //
200 | void Il2Cpp::SetStaticFieldValue(const char *image, const char *namespaze, const char *clazz, const char *name, void* value) {
201 | void *img = GetImageByName(image);
202 | if(!img) {
203 | LOGI("Can't find image %s!", image);
204 | return;
205 | }
206 | void *klass = GetClassType(image, namespaze, clazz);
207 | if(!klass) {
208 | LOGI("Can't find class %s for field %s!", clazz, name);
209 | return;
210 | }
211 |
212 | void *field = il2cpp_class_get_field_from_name(klass, name);
213 | if(!field) {
214 | LOGI("Can't find field %s in class %s!", name, clazz);
215 | return;
216 | }
217 |
218 | il2cpp_field_static_set_value(field, value);
219 | }
220 | // ================================================================================================================ //
221 | void *Il2Cpp::GetClassType(const char *image, const char *namespaze, const char *clazz) {
222 | void *img = GetImageByName(image);
223 | if(!img) {
224 | LOGI("Can't find image %s!", image);
225 | return nullptr;
226 | }
227 |
228 | void *klass = il2cpp_class_from_name(img, namespaze, clazz);
229 | if(!klass) {
230 | LOGI("Can't find class %s!", clazz);
231 | return nullptr;
232 | }
233 | return klass;
234 | }
235 | // ================================================================================================================ //
236 | void *Il2Cpp::CreateClassInstance(const char *image, const char *namespaze, const char *clazz) {
237 | void *img = GetImageByName(image);
238 | if(!img) {
239 | LOGI("Can't find image %s!", image);
240 | return nullptr;
241 | }
242 |
243 | void *klass = GetClassType(image, namespaze, clazz);
244 | if(!klass) {
245 | LOGI("Can't find class %s!", clazz);
246 | return nullptr;
247 | }
248 |
249 | void *obj = il2cpp_object_new(klass);
250 | if(!obj)
251 | {
252 | LOGI("Can't create object for %s", clazz);
253 | return nullptr;
254 | }
255 |
256 | return obj;
257 | }
258 | // ================================================================================================================ //
259 | void *Il2Cpp::GetMethodOffset(const char *image, const char *namespaze, const char *clazz, const char *name, int argsCount) {
260 | void *img = GetImageByName(image);
261 | if(!img) {
262 | LOGI("Can't find image %s!", image);
263 | return nullptr;
264 | }
265 |
266 | void *klass = GetClassType(image, namespaze, clazz);
267 | if(!klass) {
268 | LOGI("Can't find class %s for method %s!", clazz, name);
269 | return nullptr;
270 | }
271 |
272 | void **method = (void**)il2cpp_class_get_method_from_name(klass, name, argsCount);
273 | if(!method) {
274 | LOGI("Can't find method %s in class %s!", name, clazz);
275 | return nullptr;
276 | }
277 |
278 | return *method;
279 | }
280 | // ================================================================================================================ //
281 | void *Il2Cpp::GetMethodOffset(const char *image, const char *namespaze, const char *clazz, const char *name, char** args, int argsCount) {
282 | void *img = GetImageByName(image);
283 | if(!img) {
284 | LOGI("Can't find image %s!", image);
285 | return nullptr;
286 | }
287 |
288 | void *klass = GetClassType(image, namespaze, clazz);
289 | if(!klass) {
290 | LOGI("Can't find class %s for method %s!", clazz, name);
291 | return nullptr;
292 | }
293 |
294 | void *iter = nullptr;
295 |
296 | int score = 0;
297 |
298 | void **method = (void**) il2cpp_class_get_methods(klass, &iter);
299 | while(method) {
300 | const char *fname = il2cpp_method_get_name(method);
301 | if(strcmp(fname, name) == 0) {
302 | for (int i = 0; i < argsCount; i++) {
303 | void *arg = il2cpp_method_get_param(method, i);
304 | if (arg) {
305 | const char *tname = il2cpp_type_get_name(arg);
306 | if (strcmp(tname, args[i]) == 0) {
307 | score++;
308 | } else {
309 | LOGI("Argument at index %d didn't matched requested argument!\r\n\tRequested: %s\r\n\tActual: %s\r\nSkipping function...", i, args[i], tname);
310 | score = 0;
311 | goto skip;
312 | }
313 | }
314 | }
315 | }
316 | skip:
317 |
318 | if(score == argsCount)
319 | {
320 | LOGI("Found matched function!");
321 | return *method;
322 | }
323 |
324 | method = (void **) il2cpp_class_get_methods(klass, &iter);
325 | }
326 | LOGI("Cannot find function %s in class %s!", name, clazz);
327 | return nullptr;
328 | }
329 |
330 | const char *Il2Cpp::GetMethodName(void* method){
331 | return il2cpp_method_get_name(method);
332 | }
333 |
334 | uintptr_t Il2Cpp::GetFieldOffset(void *clazz, const char *name){
335 | void *field = il2cpp_class_get_field_from_name(clazz, name);
336 | if(!field) {
337 | LOGI("Can't find field %s!", name);
338 | return -1;
339 | }
340 | return il2cpp_field_get_offset(field);
341 | }
342 | // ================================================================================================================ //
343 | size_t Il2Cpp::GetFieldOffset(const char *image, const char *namespaze, const char *clazz, const char *name) {
344 | void *img = GetImageByName(image);
345 | if(!img) {
346 | LOGI("Can't find image %s!", image);
347 | return -1;
348 | }
349 | void *klass = GetClassType(image, namespaze, clazz);
350 | if(!klass) {
351 | LOGI("Can't find class %s for field %s!", clazz, name);
352 | return -1;
353 | }
354 |
355 | void *field = il2cpp_class_get_field_from_name(klass, name);
356 | if(!field) {
357 | LOGI("Can't find field %s in class %s!", name, clazz);
358 | return -1;
359 | }
360 | return il2cpp_field_get_offset(field);
361 | }
362 | // ================================================================================================================ //
363 | bool Il2Cpp::IsAssembliesLoaded() {
364 | size_t size;
365 | void **assemblies = il2cpp_domain_get_assemblies(il2cpp_domain_get(), &size);
366 |
367 | return size != 0 && assemblies != nullptr;
368 | }
369 | // ================================================================================================================ //
370 | void* Il2Cpp::CreateArray(const char *image, const char *namespaze, const char *clazz, size_t length) {
371 | void *img = GetImageByName(image);
372 | if(!img) {
373 | LOGI("Can't find image %s!", image);
374 | return nullptr;
375 | }
376 | void *klass = GetClassType(image, namespaze, clazz);
377 | if(!klass) {
378 | LOGI("Can't find class %s!", clazz);
379 | return nullptr;
380 | }
381 |
382 | return il2cpp_array_new(klass, length);
383 | }
384 | // ================================================================================================================ //
385 |
386 | std::string Il2Cpp::GetString(void *string) {
387 | if (string) {
388 | std::u16string str = il2cpp_string_chars(string);
389 | std::wstring wide_string(str.begin(), str.end());
390 | std::wstring_convert> convert;
391 | return convert.to_bytes(wide_string);
392 | }
393 | return "Object NULL!";
394 | }
--------------------------------------------------------------------------------
/app/src/main/cpp/Engine/API/API.h:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | #include
6 | #include
7 |
8 | using namespace std;
9 |
10 | #ifndef API_H
11 | #define API_H
12 |
13 | namespace Il2Cpp {
14 |
15 | int Init(const char *lib);
16 |
17 | int Init(void *handle);
18 |
19 | void *GetImageByName(const char *image);
20 |
21 | void *GetClassType(const char *image, const char *namespaze, const char *clazz);
22 |
23 | void *CreateArray(const char *image, const char *namespaze, const char *clazz, size_t length);
24 |
25 | void *GetMethodOffset(const char *image, const char *namespaze, const char *clazz, const char *name, int argsCount = 0);
26 |
27 | void *GetMethodOffset(const char *image, const char *namespaze, const char *clazz, const char *name, char **args, int argsCount = 0);
28 |
29 | const char *GetMethodName(void* method);
30 |
31 | size_t GetFieldOffset(const char *image, const char *namespaze, const char *clazz, const char *name);
32 |
33 | void GetStaticFieldValue(const char *image, const char *namespaze, const char *clazz, const char *name, void *output);
34 |
35 | void SetStaticFieldValue(const char *image, const char *namespaze, const char *clazz, const char *name, void* value);
36 |
37 | void *CreateClassInstance(const char *image, const char *namespaze, const char *clazz);
38 |
39 | bool IsAssembliesLoaded();
40 |
41 | void *CreateString(const char *str);
42 |
43 | template
44 | inline T GetMethod(uintptr_t realOffset) {
45 | return (T) (realOffset);
46 | }
47 |
48 | template
49 | inline T GetMethod(const char *image, const char *namespaze, const char *clazz, const char *name, int argsCount) {
50 | auto realOffset = Il2Cpp::GetMethodOffset(image, namespaze, clazz, name, argsCount);
51 | return (T) (realOffset);
52 | }
53 |
54 | template
55 | inline T GetField(void* obj, std::ptrdiff_t Offset) {
56 | if (Offset == 0)
57 | __android_log_print(ANDROID_LOG_INFO, "Rewtio", "GetField: Offset is 0");
58 | return *(T *) ((std::uint8_t *) obj + Offset);
59 | }
60 |
61 | template
62 | void SetField(void* obj, std::ptrdiff_t Offset, T val)
63 | {
64 | *(T*)((std::uint8_t*)obj + Offset) = val;
65 | }
66 |
67 | std::string GetString(void *string);
68 |
69 | uintptr_t GetFieldOffset(void *clazz, const char *name);
70 | };
71 |
72 |
73 | #endif //API_H
74 |
--------------------------------------------------------------------------------
/app/src/main/cpp/Engine/API/Color.hpp:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #define _USE_MATH_DEFINES
4 | #include
5 | #include
6 |
7 | struct Color
8 | {
9 | union
10 | {
11 | struct
12 | {
13 | float R;
14 | float G;
15 | float B;
16 | float A;
17 | };
18 | float data[4];
19 | };
20 |
21 | inline Color();
22 | inline Color(float r, float g, float b, float a);
23 |
24 | static inline Color red();
25 | static inline Color green();
26 | static inline Color blue();
27 | static inline Color white();
28 | static inline Color black();
29 | static inline Color purpleSense();
30 | static inline Color yellow();
31 | static inline Color magenta();
32 | static inline Color gray();
33 | static inline Color grey();
34 | static inline Color clear();
35 | };
36 |
37 | Color::Color() : R(0), G(0), B(0), A(0) {}
38 | Color::Color(float r, float g, float b, float a) : R(r), G(g), B(b), A(a) {}
39 |
40 | Color Color::red() { return Color(1,0,0,1); }
41 | Color Color::green() { return Color(0,1,0,1); }
42 | Color Color::blue() { return Color(0,0,1,1); }
43 | Color Color::white() { return Color(1,1,1,1); }
44 | Color Color::black() { return Color(0,0,0,1); }
45 | Color Color::purpleSense() { return Color(0.6039215, 0.0705882, 0.7019607, 1); }
46 | Color Color::yellow() { return Color(1,0.921569,0.0156863,1); }
47 | Color Color::magenta() { return Color(1,0,1,1); }
48 | Color Color::gray() { return Color(0.5,0.5,0.5,1); }
49 | Color Color::grey() { return Color(0.5,0.5,0.5,1); }
50 | Color Color::clear() { return Color(0,0,0,0.5); }
--------------------------------------------------------------------------------
/app/src/main/cpp/Engine/API/Matrix4x4.hpp:
--------------------------------------------------------------------------------
1 | #ifndef MATRIX4_HPP
2 | #define MATRIX4_HPP
3 |
4 | struct Matrix4x4 {
5 |
6 |
7 | union {
8 | struct {
9 | float m00;
10 | float m10;
11 | float m20;
12 | float m30;
13 | float m01;
14 | float m11;
15 | float m21;
16 | float m31;
17 | float m02;
18 | float m12;
19 | float m22;
20 | float m32;
21 | float m03;
22 | float m13;
23 | float m23;
24 | float m33;
25 | };
26 | float m[16];
27 | };
28 |
29 | inline Matrix4x4();
30 |
31 | inline Matrix4x4 operator*(const Matrix4x4 &m2) const;
32 |
33 | inline Matrix4x4(float entry00, float entry01, float entry02, float entry03, float entry10,
34 | float entry11, float entry12, float entry13, float entry20, float entry21,
35 | float entry22, float entry23, float entry30, float entry31, float entry32,
36 | float entry33);
37 |
38 | inline Vector3 MultiplyPoint(Vector3 point);
39 | };
40 |
41 | Matrix4x4::Matrix4x4() : m00(1.0f), m10(0.0f), m20(0.0f), m30(0.0f),
42 | m01(0.0f), m11(1.0f), m21(0.0f), m31(0.0f),
43 | m02(0.0f), m12(0.0f), m22(1.0f), m32(0.0f),
44 | m03(0.0f), m13(0.0f), m23(0.0f), m33(1.0f) {}
45 |
46 | Matrix4x4::Matrix4x4(float entry00, float entry01, float entry02, float entry03,
47 | float entry10, float entry11, float entry12, float entry13,
48 | float entry20, float entry21, float entry22, float entry23,
49 | float entry30, float entry31, float entry32, float entry33)
50 | : m{entry00, entry01, entry02, entry03,
51 | entry10, entry11, entry12, entry13,
52 | entry20, entry21, entry22, entry23,
53 | entry30, entry31, entry32, entry33} {}
54 |
55 | Matrix4x4 Matrix4x4::operator*(const Matrix4x4 &rhs) const {
56 | Matrix4x4 res;
57 | res.m00 = this->m00 * rhs.m00 + this->m01 * rhs.m10 + this->m02 * rhs.m20 + this->m03 * rhs.m30;
58 | res.m01 = this->m00 * rhs.m01 + this->m01 * rhs.m11 + this->m02 * rhs.m21 + this->m03 * rhs.m31;
59 | res.m02 = this->m00 * rhs.m02 + this->m01 * rhs.m12 + this->m02 * rhs.m22 + this->m03 * rhs.m32;
60 | res.m03 = this->m00 * rhs.m03 + this->m01 * rhs.m13 + this->m02 * rhs.m23 + this->m03 * rhs.m33;
61 |
62 | res.m10 = this->m10 * rhs.m00 + this->m11 * rhs.m10 + this->m12 * rhs.m20 + this->m13 * rhs.m30;
63 | res.m11 = this->m10 * rhs.m01 + this->m11 * rhs.m11 + this->m12 * rhs.m21 + this->m13 * rhs.m31;
64 | res.m12 = this->m10 * rhs.m02 + this->m11 * rhs.m12 + this->m12 * rhs.m22 + this->m13 * rhs.m32;
65 | res.m13 = this->m10 * rhs.m03 + this->m11 * rhs.m13 + this->m12 * rhs.m23 + this->m13 * rhs.m33;
66 |
67 | res.m20 = this->m20 * rhs.m00 + this->m21 * rhs.m10 + this->m22 * rhs.m20 + this->m23 * rhs.m30;
68 | res.m21 = this->m20 * rhs.m01 + this->m21 * rhs.m11 + this->m22 * rhs.m21 + this->m23 * rhs.m31;
69 | res.m22 = this->m20 * rhs.m02 + this->m21 * rhs.m12 + this->m22 * rhs.m22 + this->m23 * rhs.m32;
70 | res.m23 = this->m20 * rhs.m03 + this->m21 * rhs.m13 + this->m22 * rhs.m23 + this->m23 * rhs.m33;
71 |
72 | res.m30 = this->m30 * rhs.m00 + this->m31 * rhs.m10 + this->m32 * rhs.m20 + this->m33 * rhs.m30;
73 | res.m31 = this->m30 * rhs.m01 + this->m31 * rhs.m11 + this->m32 * rhs.m21 + this->m33 * rhs.m31;
74 | res.m32 = this->m30 * rhs.m02 + this->m31 * rhs.m12 + this->m32 * rhs.m22 + this->m33 * rhs.m32;
75 | res.m33 = this->m30 * rhs.m03 + this->m31 * rhs.m13 + this->m32 * rhs.m23 + this->m33 * rhs.m33;
76 |
77 | return res;
78 | }
79 |
80 | Vector3 Matrix4x4::MultiplyPoint(Vector3 point) {
81 | Vector3 res;
82 | float w;
83 | res.X = this->m00 * point.X + this->m01 * point.Y + this->m02 * point.Z + this->m03;
84 | res.Y = this->m10 * point.X + this->m11 * point.Y + this->m12 * point.Z + this->m13;
85 | res.Z = this->m20 * point.X + this->m21 * point.Y + this->m22 * point.Z + this->m23;
86 | w = this->m30 * point.X + this->m31 * point.Y + this->m32 * point.Z + this->m33;
87 | if (w > 0.01f) {
88 | w = 1.0F / w;
89 | res.X *= w;
90 | res.Y *= w;
91 | res.Z *= w;
92 | return res;
93 | } else {
94 | return Vector3::Zero();
95 | }
96 | }
97 |
98 | #endif
99 |
--------------------------------------------------------------------------------
/app/src/main/cpp/Engine/API/Quaternion.hpp:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #define _USE_MATH_DEFINES
4 | #include
5 | #include
6 |
7 | #define SMALL_float 0.0000000001
8 |
9 |
10 | /**
11 | * Attempt to include a header file if the file exists.
12 | * If the file does not exist, create a dummy data structure for that type.
13 | * If it cannot be determined if it exists, just attempt to include it.
14 | */
15 | #ifdef __has_include
16 | # if __has_include("Vector3.hpp")
17 | # include "Vector3.hpp"
18 | # elif !defined(GMATH_VECTOR3)
19 | #define GMATH_VECTOR3
20 | struct Vector3
21 | {
22 | union
23 | {
24 | struct
25 | {
26 | float X;
27 | float Y;
28 | float Z;
29 | };
30 | float data[3];
31 | };
32 |
33 | inline Vector3() : X(0), Y(0), Z(0) {}
34 | inline Vector3(float data[]) : X(data[0]), Y(data[1]), Z(data[2])
35 | {}
36 | inline Vector3(float value) : X(value), Y(value), Z(value) {}
37 | inline Vector3(float x, float y) : X(x), Y(y), Z(0) {}
38 | inline Vector3(float x, float y, float z) : X(x), Y(y), Z(z) {}
39 |
40 | static inline Vector3 Cross(Vector3 lhs, Vector3 rhs)
41 | {
42 | float x = lhs.Y * rhs.Z - lhs.Z * rhs.Y;
43 | float y = lhs.Z * rhs.X - lhs.X * rhs.Z;
44 | float z = lhs.X * rhs.Y - lhs.Y * rhs.X;
45 | return Vector3(x, y, z);
46 | }
47 |
48 | static inline float Dot(Vector3 lhs, Vector3 rhs)
49 | {
50 | return lhs.X * rhs.X + lhs.Y * rhs.Y + lhs.Z * rhs.Z;
51 | }
52 |
53 | static inline Vector3 Normalized(Vector3 v)
54 | {
55 | float mag = sqrt(v.X * v.X + v.Y * v.Y + v.Z * v.Z);
56 | if (mag == 0)
57 | return Vector3::Zero();
58 | return v / mag;
59 | }
60 |
61 | static inline Vector3 Orthogonal(Vector3 v)
62 | {
63 | return v.Z < v.X ?
64 | Vector3(v.Y, -v.X, 0) : Vector3(0, -v.Z, v.Y);
65 | }
66 |
67 | static inline float SqrMagnitude(Vector3 v)
68 | {
69 | return v.X * v.X + v.Y * v.Y + v.Z * v.Z;
70 | }
71 | };
72 |
73 |
74 | inline Vector3 operator+(Vector3 lhs, const Vector3 rhs)
75 | {
76 | return Vector3(lhs.X + rhs.X, lhs.Y + rhs.Y, lhs.Z + rhs.Z);
77 | }
78 |
79 | inline Vector3 operator*(Vector3 lhs, const float rhs)
80 | {
81 | return Vector3(lhs.X * rhs, lhs.Y * rhs, lhs.Z * rhs);
82 | }
83 | # endif
84 | #else
85 | # include "Vector3.hpp"
86 | #endif
87 |
88 |
89 | struct Quaternion
90 | {
91 | union
92 | {
93 | struct
94 | {
95 | float X;
96 | float Y;
97 | float Z;
98 | float W;
99 | };
100 | float data[4];
101 | };
102 |
103 |
104 | /**
105 | * Constructors.
106 | */
107 | inline Quaternion();
108 | inline Quaternion(float data[]);
109 | inline Quaternion(Vector3 vector, float scalar);
110 | inline Quaternion(float x, float y, float z, float w);
111 |
112 |
113 | /**
114 | * Constants for common quaternions.
115 | */
116 | static inline Quaternion Identity();
117 |
118 |
119 | /**
120 | * Returns the angle between two quaternions.
121 | * The quaternions must be normalized.
122 | * @param a: The first quaternion.
123 | * @param b: The second quaternion.
124 | * @return: A scalar value.
125 | */
126 | static inline float Angle(Quaternion a, Quaternion b);
127 |
128 | /**
129 | * Returns the conjugate of a quaternion.
130 | * @param rotation: The quaternion in question.
131 | * @return: A new quaternion.
132 | */
133 | static inline Quaternion Conjugate(Quaternion rotation);
134 |
135 | /**
136 | * Returns the dot product of two quaternions.
137 | * @param lhs: The left side of the multiplication.
138 | * @param rhs: The right side of the multiplication.
139 | * @return: A scalar value.
140 | */
141 | static inline float Dot(Quaternion lhs, Quaternion rhs);
142 |
143 | /**
144 | * Creates a new quaternion from the angle-axis representation of
145 | * a rotation.
146 | * @param angle: The rotation angle in radians.
147 | * @param axis: The vector about which the rotation occurs.
148 | * @return: A new quaternion.
149 | */
150 | static inline Quaternion FromAngleAxis(float angle, Vector3 axis);
151 |
152 | /**
153 | * Create a new quaternion from the euler angle representation of
154 | * a rotation. The z, x and y values represent rotations about those
155 | * axis in that respective order.
156 | * @param rotation: The x, y and z rotations.
157 | * @return: A new quaternion.
158 | */
159 | static inline Quaternion FromEuler(Vector3 rotation);
160 |
161 | /**
162 | * Create a new quaternion from the euler angle representation of
163 | * a rotation. The z, x and y values represent rotations about those
164 | * axis in that respective order.
165 | * @param x: The rotation about the x-axis in radians.
166 | * @param y: The rotation about the y-axis in radians.
167 | * @param z: The rotation about the z-axis in radians.
168 | * @return: A new quaternion.
169 | */
170 | static inline Quaternion FromEuler(float x, float y, float z);
171 |
172 | /**
173 | * Create a quaternion rotation which rotates "fromVector" to "toVector".
174 | * @param fromVector: The vector from which to start the rotation.
175 | * @param toVector: The vector at which to end the rotation.
176 | * @return: A new quaternion.
177 | */
178 | static inline Quaternion FromToRotation(Vector3 fromVector,
179 | Vector3 toVector);
180 |
181 | /**
182 | * Returns the inverse of a rotation.
183 | * @param rotation: The quaternion in question.
184 | * @return: A new quaternion.
185 | */
186 | static inline Quaternion Inverse(Quaternion rotation);
187 |
188 | /**
189 | * Interpolates between a and b by t, which is clamped to the range [0-1].
190 | * The result is normalized before being returned.
191 | * @param a: The starting rotation.
192 | * @param b: The ending rotation.
193 | * @return: A new quaternion.
194 | */
195 | static inline Quaternion Lerp(Quaternion a, Quaternion b, float t);
196 |
197 | /**
198 | * Interpolates between a and b by t. This normalizes the result when
199 | * complete.
200 | * @param a: The starting rotation.
201 | * @param b: The ending rotation.
202 | * @param t: The interpolation value.
203 | * @return: A new quaternion.
204 | */
205 | static inline Quaternion LerpUnclamped(Quaternion a, Quaternion b,
206 | float t);
207 |
208 | /**
209 | * Creates a rotation with the specified forward direction. This is the
210 | * same as calling LookRotation with (0, 1, 0) as the upwards vector.
211 | * The output is undefined for parallel vectors.
212 | * @param forward: The forward direction to look toward.
213 | * @return: A new quaternion.
214 | */
215 | static inline Quaternion LookRotation(Vector3 forward);
216 |
217 | /**
218 | * Creates a rotation with the specified forward and upwards directions.
219 | * The output is undefined for parallel vectors.
220 | * @param forward: The forward direction to look toward.
221 | * @param upwards: The direction to treat as up.
222 | * @return: A new quaternion.
223 | */
224 | static inline Quaternion LookRotation(Vector3 forward, Vector3 upwards);
225 |
226 | /**
227 | * Returns the norm of a quaternion.
228 | * @param rotation: The quaternion in question.
229 | * @return: A scalar value.
230 | */
231 | static inline float Norm(Quaternion rotation);
232 |
233 | /**
234 | * Returns a quaternion with identical rotation and a norm of one.
235 | * @param rotation: The quaternion in question.
236 | * @return: A new quaternion.
237 | */
238 | static inline Quaternion Normalized(Quaternion rotation);
239 |
240 | /**
241 | * Returns a new Quaternion created by rotating "from" towards "to" by
242 | * "maxRadiansDelta". This will not overshoot, and if a negative delta is
243 | * applied, it will rotate till completely opposite "to" and then stop.
244 | * @param from: The rotation at which to start.
245 | * @param to: The rotation at which to end.
246 | # @param maxRadiansDelta: The maximum number of radians to rotate.
247 | * @return: A new Quaternion.
248 | */
249 | static inline Quaternion RotateTowards(Quaternion from, Quaternion to,
250 | float maxRadiansDelta);
251 |
252 | /**
253 | * Returns a new quaternion interpolated between a and b, using spherical
254 | * linear interpolation. The variable t is clamped to the range [0-1]. The
255 | * resulting quaternion will be normalized.
256 | * @param a: The starting rotation.
257 | * @param b: The ending rotation.
258 | * @param t: The interpolation value.
259 | * @return: A new quaternion.
260 | */
261 | static inline Quaternion Slerp(Quaternion a, Quaternion b, float t);
262 |
263 | /**
264 | * Returns a new quaternion interpolated between a and b, using spherical
265 | * linear interpolation. The resulting quaternion will be normalized.
266 | * @param a: The starting rotation.
267 | * @param b: The ending rotation.
268 | * @param t: The interpolation value.
269 | * @return: A new quaternion.
270 | */
271 | static inline Quaternion SlerpUnclamped(Quaternion a, Quaternion b,
272 | float t);
273 |
274 | /**
275 | * Outputs the angle axis representation of the provided quaternion.
276 | * @param rotation: The input quaternion.
277 | * @param angle: The output angle.
278 | * @param axis: The output axis.
279 | */
280 | static inline void ToAngleAxis(Quaternion rotation, float &angle,
281 | Vector3 &axis);
282 |
283 | /**
284 | * Returns the Euler angle representation of a rotation. The resulting
285 | * vector contains the rotations about the z, x and y axis, in that order.
286 | * @param rotation: The quaternion to convert.
287 | * @return: A new vector.
288 | */
289 | static inline Vector3 ToEuler(Quaternion rotation);
290 |
291 | /**
292 | * Operator overloading.
293 | */
294 | inline struct Quaternion& operator+=(const float rhs);
295 | inline struct Quaternion& operator-=(const float rhs);
296 | inline struct Quaternion& operator*=(const float rhs);
297 | inline struct Quaternion& operator/=(const float rhs);
298 | inline struct Quaternion& operator+=(const Quaternion rhs);
299 | inline struct Quaternion& operator-=(const Quaternion rhs);
300 | inline struct Quaternion& operator*=(const Quaternion rhs);
301 | };
302 |
303 | inline Quaternion operator-(Quaternion rhs);
304 | inline Quaternion operator+(Quaternion lhs, const float rhs);
305 | inline Quaternion operator-(Quaternion lhs, const float rhs);
306 | inline Quaternion operator*(Quaternion lhs, const float rhs);
307 | inline Quaternion operator/(Quaternion lhs, const float rhs);
308 | inline Quaternion operator+(const float lhs, Quaternion rhs);
309 | inline Quaternion operator-(const float lhs, Quaternion rhs);
310 | inline Quaternion operator*(const float lhs, Quaternion rhs);
311 | inline Quaternion operator/(const float lhs, Quaternion rhs);
312 | inline Quaternion operator+(Quaternion lhs, const Quaternion rhs);
313 | inline Quaternion operator-(Quaternion lhs, const Quaternion rhs);
314 | inline Quaternion operator*(Quaternion lhs, const Quaternion rhs);
315 | inline Vector3 operator*(Quaternion lhs, const Vector3 rhs);
316 | inline bool operator==(const Quaternion lhs, const Quaternion rhs);
317 | inline bool operator!=(const Quaternion lhs, const Quaternion rhs);
318 |
319 |
320 |
321 | /*******************************************************************************
322 | * Implementation
323 | */
324 |
325 | Quaternion::Quaternion() : X(0), Y(0), Z(0), W(1) {}
326 | Quaternion::Quaternion(float data[]) : X(data[0]), Y(data[1]), Z(data[2]),
327 | W(data[3]) {}
328 | Quaternion::Quaternion(Vector3 vector, float scalar) : X(vector.X),
329 | Y(vector.Y), Z(vector.Z), W(scalar) {}
330 | Quaternion::Quaternion(float x, float y, float z, float w) : X(x), Y(y),
331 | Z(z), W(w) {}
332 |
333 |
334 | Quaternion Quaternion::Identity() { return Quaternion(0, 0, 0, 1); }
335 |
336 |
337 | float Quaternion::Angle(Quaternion a, Quaternion b)
338 | {
339 | float dot = Dot(a, b);
340 | return acos(fmin(fabs(dot), 1)) * 2;
341 | }
342 |
343 | Quaternion Quaternion::Conjugate(Quaternion rotation)
344 | {
345 | return Quaternion(-rotation.X, -rotation.Y, -rotation.Z, rotation.W);
346 | }
347 |
348 | float Quaternion::Dot(Quaternion lhs, Quaternion rhs)
349 | {
350 | return lhs.X * rhs.X + lhs.Y * rhs.Y + lhs.Z * rhs.Z + lhs.W * rhs.W;
351 | }
352 |
353 | Quaternion Quaternion::FromAngleAxis(float angle, Vector3 axis)
354 | {
355 | Quaternion q;
356 | float m = sqrt(axis.X * axis.X + axis.Y * axis.Y + axis.Z * axis.Z);
357 | float s = sin(angle / 2) / m;
358 | q.X = axis.X * s;
359 | q.Y = axis.Y * s;
360 | q.Z = axis.Z * s;
361 | q.W = cos(angle / 2);
362 | return q;
363 | }
364 |
365 | Quaternion Quaternion::FromEuler(Vector3 rotation)
366 | {
367 | return FromEuler(rotation.X, rotation.Y, rotation.Z);
368 | }
369 |
370 | Quaternion Quaternion::FromEuler(float x, float y, float z)
371 | {
372 | float cx = cos(x * 0.5);
373 | float cy = cos(y * 0.5);
374 | float cz = cos(z * 0.5);
375 | float sx = sin(x * 0.5);
376 | float sy = sin(y * 0.5);
377 | float sz = sin(z * 0.5);
378 | Quaternion q;
379 | q.X = cx * sy * sz + cy * cz * sx;
380 | q.Y = cx * cz * sy - cy * sx * sz;
381 | q.Z = cx * cy * sz - cz * sx * sy;
382 | q.W = sx * sy * sz + cx * cy * cz;
383 | return q;
384 | }
385 |
386 | Quaternion Quaternion::FromToRotation(Vector3 fromVector, Vector3 toVector)
387 | {
388 | float dot = Vector3::Dot(fromVector, toVector);
389 | float k = sqrt(Vector3::SqrMagnitude(fromVector) *
390 | Vector3::SqrMagnitude(toVector));
391 | if (fabs(dot / k + 1) < 0.00001)
392 | {
393 | Vector3 ortho = Vector3::Orthogonal(fromVector);
394 | return Quaternion(Vector3::Normalized(ortho), 0);
395 | }
396 | Vector3 cross = Vector3::Cross(fromVector, toVector);
397 | return Normalized(Quaternion(cross, dot + k));
398 | }
399 |
400 | Quaternion Quaternion::Inverse(Quaternion rotation)
401 | {
402 | float n = Norm(rotation);
403 | return Conjugate(rotation) / (n * n);
404 | }
405 |
406 | Quaternion Quaternion::Lerp(Quaternion a, Quaternion b, float t)
407 | {
408 | if (t < 0) return Normalized(a);
409 | else if (t > 1) return Normalized(b);
410 | return LerpUnclamped(a, b, t);
411 | }
412 |
413 | Quaternion Quaternion::LerpUnclamped(Quaternion a, Quaternion b, float t)
414 | {
415 | Quaternion quaternion;
416 | if (Dot(a, b) >= 0)
417 | quaternion = a * (1 - t) + b * t;
418 | else
419 | quaternion = a * (1 - t) - b * t;
420 | return Normalized(quaternion);
421 | }
422 |
423 | Quaternion Quaternion::LookRotation(Vector3 forward)
424 | {
425 | return LookRotation(forward, Vector3(0, 1, 0));
426 | }
427 |
428 | Quaternion Quaternion::LookRotation(Vector3 forward, Vector3 upwards)
429 | {
430 | // Normalize inputs
431 | forward = Vector3::Normalized(forward);
432 | upwards = Vector3::Normalized(upwards);
433 | // Don't allow zero vectors
434 | if (Vector3::SqrMagnitude(forward) < SMALL_float || Vector3::SqrMagnitude(upwards) < SMALL_float)
435 | return Quaternion::Identity();
436 | // Handle alignment with up direction
437 | if (1 - fabs(Vector3::Dot(forward, upwards)) < SMALL_float)
438 | return FromToRotation(Vector3::Forward(), forward);
439 | // Get orthogonal vectors
440 | Vector3 right = Vector3::Normalized(Vector3::Cross(upwards, forward));
441 | upwards = Vector3::Cross(forward, right);
442 | // Calculate rotation
443 | Quaternion quaternion;
444 | float radicand = right.X + upwards.Y + forward.Z;
445 | if (radicand > 0)
446 | {
447 | quaternion.W = sqrt(1.0 + radicand) * 0.5;
448 | float recip = 1.0 / (4.0 * quaternion.W);
449 | quaternion.X = (upwards.Z - forward.Y) * recip;
450 | quaternion.Y = (forward.X - right.Z) * recip;
451 | quaternion.Z = (right.Y - upwards.X) * recip;
452 | }
453 | else if (right.X >= upwards.Y && right.X >= forward.Z)
454 | {
455 | quaternion.X = sqrt(1.0 + right.X - upwards.Y - forward.Z) * 0.5;
456 | float recip = 1.0 / (4.0 * quaternion.X);
457 | quaternion.W = (upwards.Z - forward.Y) * recip;
458 | quaternion.Z = (forward.X + right.Z) * recip;
459 | quaternion.Y = (right.Y + upwards.X) * recip;
460 | }
461 | else if (upwards.Y > forward.Z)
462 | {
463 | quaternion.Y = sqrt(1.0 - right.X + upwards.Y - forward.Z) * 0.5;
464 | float recip = 1.0 / (4.0 * quaternion.Y);
465 | quaternion.Z = (upwards.Z + forward.Y) * recip;
466 | quaternion.W = (forward.X - right.Z) * recip;
467 | quaternion.X = (right.Y + upwards.X) * recip;
468 | }
469 | else
470 | {
471 | quaternion.Z = sqrt(1.0 - right.X - upwards.Y + forward.Z) * 0.5;
472 | float recip = 1.0 / (4.0 * quaternion.Z);
473 | quaternion.Y = (upwards.Z + forward.Y) * recip;
474 | quaternion.X = (forward.X + right.Z) * recip;
475 | quaternion.W = (right.Y - upwards.X) * recip;
476 | }
477 | return quaternion;
478 | }
479 |
480 | float Quaternion::Norm(Quaternion rotation)
481 | {
482 | return sqrt(rotation.X * rotation.X +
483 | rotation.Y * rotation.Y +
484 | rotation.Z * rotation.Z +
485 | rotation.W * rotation.W);
486 | }
487 |
488 | Quaternion Quaternion::Normalized(Quaternion rotation)
489 | {
490 | return rotation / Norm(rotation);
491 | }
492 |
493 | Quaternion Quaternion::RotateTowards(Quaternion from, Quaternion to,
494 | float maxRadiansDelta)
495 | {
496 | float angle = Quaternion::Angle(from, to);
497 | if (angle == 0)
498 | return to;
499 | maxRadiansDelta = fmax(maxRadiansDelta, angle - M_PI);
500 | float t = fmin(1, maxRadiansDelta / angle);
501 | return Quaternion::SlerpUnclamped(from, to, t);
502 | }
503 |
504 | Quaternion Quaternion::Slerp(Quaternion a, Quaternion b, float t)
505 | {
506 | if (t < 0) return Normalized(a);
507 | else if (t > 1) return Normalized(b);
508 | return SlerpUnclamped(a, b, t);
509 | }
510 |
511 | Quaternion Quaternion::SlerpUnclamped(Quaternion a, Quaternion b, float t)
512 | {
513 | float n1;
514 | float n2;
515 | float n3 = Dot(a, b);
516 | bool flag = false;
517 | if (n3 < 0)
518 | {
519 | flag = true;
520 | n3 = -n3;
521 | }
522 | if (n3 > 0.999999)
523 | {
524 | n2 = 1 - t;
525 | n1 = flag ? -t : t;
526 | }
527 | else
528 | {
529 | float n4 = acos(n3);
530 | float n5 = 1 / sin(n4);
531 | n2 = sin((1 - t) * n4) * n5;
532 | n1 = flag ? -sin(t * n4) * n5 : sin(t * n4) * n5;
533 | }
534 | Quaternion quaternion;
535 | quaternion.X = (n2 * a.X) + (n1 * b.X);
536 | quaternion.Y = (n2 * a.Y) + (n1 * b.Y);
537 | quaternion.Z = (n2 * a.Z) + (n1 * b.Z);
538 | quaternion.W = (n2 * a.W) + (n1 * b.W);
539 | return Normalized(quaternion);
540 | }
541 |
542 | void Quaternion::ToAngleAxis(Quaternion rotation, float &angle, Vector3 &axis)
543 | {
544 | if (rotation.W > 1)
545 | rotation = Normalized(rotation);
546 | angle = 2 * acos(rotation.W);
547 | float s = sqrt(1 - rotation.W * rotation.W);
548 | if (s < 0.00001) {
549 | axis.X = 1;
550 | axis.Y = 0;
551 | axis.Z = 0;
552 | } else {
553 | axis.X = rotation.X / s;
554 | axis.Y = rotation.Y / s;
555 | axis.Z = rotation.Z / s;
556 | }
557 | }
558 |
559 | Vector3 Quaternion::ToEuler(Quaternion rotation)
560 | {
561 | float sqw = rotation.W * rotation.W;
562 | float sqx = rotation.X * rotation.X;
563 | float sqy = rotation.Y * rotation.Y;
564 | float sqz = rotation.Z * rotation.Z;
565 | // If normalized is one, otherwise is correction factor
566 | float unit = sqx + sqy + sqz + sqw;
567 | float test = rotation.X * rotation.W - rotation.Y * rotation.Z;
568 | Vector3 v;
569 | // Singularity at north pole
570 | if (test > 0.4995f * unit)
571 | {
572 | v.Y = 2 * atan2(rotation.Y, rotation.X);
573 | v.X = M_PI_2;
574 | v.Z = 0;
575 | return v;
576 | }
577 | // Singularity at south pole
578 | if (test < -0.4995f * unit)
579 | {
580 | v.Y = -2 * atan2(rotation.Y, rotation.X);
581 | v.X = -M_PI_2;
582 | v.Z = 0;
583 | return v;
584 | }
585 | // Yaw
586 | v.Y = atan2(2 * rotation.W * rotation.Y + 2 * rotation.Z * rotation.X,
587 | 1 - 2 * (rotation.X * rotation.X + rotation.Y * rotation.Y));
588 | // Pitch
589 | v.X = asin(2 * (rotation.W * rotation.X - rotation.Y * rotation.Z));
590 | // Roll
591 | v.Z = atan2(2 * rotation.W * rotation.Z + 2 * rotation.X * rotation.Y,
592 | 1 - 2 * (rotation.Z * rotation.Z + rotation.X * rotation.X));
593 | return v;
594 | }
595 |
596 | struct Quaternion& Quaternion::operator+=(const float rhs)
597 | {
598 | X += rhs;
599 | Y += rhs;
600 | Z += rhs;
601 | W += rhs;
602 | return *this;
603 | }
604 |
605 | struct Quaternion& Quaternion::operator-=(const float rhs)
606 | {
607 | X -= rhs;
608 | Y -= rhs;
609 | Z -= rhs;
610 | W -= rhs;
611 | return *this;
612 | }
613 |
614 | struct Quaternion& Quaternion::operator*=(const float rhs)
615 | {
616 | X *= rhs;
617 | Y *= rhs;
618 | Z *= rhs;
619 | W *= rhs;
620 | return *this;
621 | }
622 |
623 | struct Quaternion& Quaternion::operator/=(const float rhs)
624 | {
625 | X /= rhs;
626 | Y /= rhs;
627 | Z /= rhs;
628 | W /= rhs;
629 | return *this;
630 | }
631 |
632 | struct Quaternion& Quaternion::operator+=(const Quaternion rhs)
633 | {
634 | X += rhs.X;
635 | Y += rhs.Y;
636 | Z += rhs.Z;
637 | W += rhs.W;
638 | return *this;
639 | }
640 |
641 | struct Quaternion& Quaternion::operator-=(const Quaternion rhs)
642 | {
643 | X -= rhs.X;
644 | Y -= rhs.Y;
645 | Z -= rhs.Z;
646 | W -= rhs.W;
647 | return *this;
648 | }
649 |
650 | struct Quaternion& Quaternion::operator*=(const Quaternion rhs)
651 | {
652 | Quaternion q;
653 | q.W = W * rhs.W - X * rhs.X - Y * rhs.Y - Z * rhs.Z;
654 | q.X = X * rhs.W + W * rhs.X + Y * rhs.Z - Z * rhs.Y;
655 | q.Y = W * rhs.Y - X * rhs.Z + Y * rhs.W + Z * rhs.X;
656 | q.Z = W * rhs.Z + X * rhs.Y - Y * rhs.X + Z * rhs.W;
657 | *this = q;
658 | return *this;
659 | }
660 |
661 | Quaternion operator-(Quaternion rhs) { return rhs * -1; }
662 | Quaternion operator+(Quaternion lhs, const float rhs) { return lhs += rhs; }
663 | Quaternion operator-(Quaternion lhs, const float rhs) { return lhs -= rhs; }
664 | Quaternion operator*(Quaternion lhs, const float rhs) { return lhs *= rhs; }
665 | Quaternion operator/(Quaternion lhs, const float rhs) { return lhs /= rhs; }
666 | Quaternion operator+(const float lhs, Quaternion rhs) { return rhs += lhs; }
667 | Quaternion operator-(const float lhs, Quaternion rhs) { return rhs -= lhs; }
668 | Quaternion operator*(const float lhs, Quaternion rhs) { return rhs *= lhs; }
669 | Quaternion operator/(const float lhs, Quaternion rhs) { return rhs /= lhs; }
670 | Quaternion operator+(Quaternion lhs, const Quaternion rhs)
671 | {
672 | return lhs += rhs;
673 | }
674 | Quaternion operator-(Quaternion lhs, const Quaternion rhs)
675 | {
676 | return lhs -= rhs;
677 | }
678 | Quaternion operator*(Quaternion lhs, const Quaternion rhs)
679 | {
680 | return lhs *= rhs;
681 | }
682 |
683 | Vector3 operator*(Quaternion lhs, const Vector3 rhs)
684 | {
685 | Vector3 u = Vector3(lhs.X, lhs.Y, lhs.Z);
686 | float s = lhs.W;
687 | return u * (Vector3::Dot(u, rhs) * 2)
688 | + rhs * (s * s - Vector3::Dot(u, u))
689 | + Vector3::Cross(u, rhs) * (2.0 * s);
690 | }
691 |
692 | bool operator==(const Quaternion lhs, const Quaternion rhs)
693 | {
694 | return lhs.X == rhs.X &&
695 | lhs.Y == rhs.Y &&
696 | lhs.Z == rhs.Z &&
697 | lhs.W == rhs.W;
698 | }
699 |
700 | bool operator!=(const Quaternion lhs, const Quaternion rhs)
701 | {
702 | return !(lhs == rhs);
703 | }
--------------------------------------------------------------------------------
/app/src/main/cpp/Engine/API/Rect.hpp:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #define _USE_MATH_DEFINES
4 | #include
5 | #include
6 |
7 | struct Rect
8 | {
9 | union
10 | {
11 | struct
12 | {
13 | float x;
14 | float y;
15 | float width;
16 | float height;
17 | };
18 | float data[4];
19 | };
20 |
21 | inline Rect();
22 | inline Rect(float XMin, float YMin, float Width, float Height);
23 | };
24 |
25 | Rect::Rect() : x(0), y(0), width(0), height(0) {}
26 | Rect::Rect(float XMin, float YMin, float Width, float Height) : x(XMin), y(YMin), width(Width), height(Height) {}
27 |
28 |
--------------------------------------------------------------------------------
/app/src/main/cpp/Engine/API/Unity.h:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 | #include
10 | #include "API.h"
11 | #include "Rect.hpp"
12 | #include "Color.hpp"
13 | #include "Vector3.hpp"
14 | #include "Vector2.hpp"
15 | #include "Matrix4x4.hpp"
16 | #include "Quaternion.hpp"
17 |
18 | static inline float NormalizeAngle(float angle) {
19 | while (angle > 360)
20 | angle -= 360;
21 | while (angle < 0)
22 | angle += 360;
23 | return angle;
24 | }
25 |
26 | static inline Vector3 NormalizeAngles(Vector3 angles) {
27 | angles.X = NormalizeAngle(angles.X);
28 | angles.Y = NormalizeAngle(angles.Y);
29 | angles.Z = NormalizeAngle(angles.Z);
30 | return angles;
31 | }
32 |
33 | static inline Vector3 ToEulerRad(Quaternion q1) {
34 | float Rad2Deg = 360.0 / (M_PI * 2.0);
35 |
36 | float sqw = q1.W * q1.W;
37 | float sqx = q1.X * q1.X;
38 | float sqy = q1.Y * q1.Y;
39 | float sqz = q1.Z * q1.Z;
40 | float unit = sqx + sqy + sqz + sqw;
41 | float test = q1.X * q1.W - q1.Y * q1.Z;
42 | Vector3 v;
43 |
44 | if (test > 0.4995 * unit) {
45 | v.Y = 2.0 * atan2f(q1.Y, q1.X);
46 | v.X = M_PI / 2.0;
47 | v.Z = 0;
48 | return NormalizeAngles(v * Rad2Deg);
49 | }
50 | if (test < -0.4995 * unit) {
51 | v.Y = -2.0 * atan2f(q1.Y, q1.X);
52 | v.X = -M_PI / 2.0;
53 | v.Z = 0;
54 | return NormalizeAngles(v * Rad2Deg);
55 | }
56 | Quaternion q(q1.W, q1.Z, q1.X, q1.Y);
57 | v.Y = atan2f(2.0 * q.X * q.W + 2.0 * q.Y * q.Z, 1 - 2.0 * (q.Z * q.Z + q.W * q.W)); // yaw
58 | v.X = asinf(2.0 * (q.X * q.Z - q.W * q.Y)); // pitch
59 | v.Z = atan2f(2.0 * q.X * q.Y + 2.0 * q.Z * q.W, 1 - 2.0 * (q.Y * q.Y + q.Z * q.Z)); // roll
60 | return NormalizeAngles(v * Rad2Deg);
61 | }
62 |
63 | static inline Quaternion GetRotationToLocation(Vector3 targetLocation, float y_bias, Vector3 myLoc) {
64 | return Quaternion::LookRotation((targetLocation + Vector3(0, y_bias, 0)) - myLoc,
65 | Vector3(0, 1, 0));
66 | }
67 |
68 | template
69 | struct monoArray {
70 | void *klass;
71 | void *monitor;
72 | void *bounds;
73 | int max_length;
74 | void *vector[1];
75 |
76 | int getLength() {
77 | return max_length;
78 | }
79 |
80 | T getPointer() {
81 | return (T) vector;
82 | }
83 | };
84 |
85 | template
86 | struct monoList {
87 | void *unk0;
88 | void *unk1;
89 | monoArray *items;
90 | int size;
91 | int version;
92 |
93 | T getItems() {
94 | return items->getPointer();
95 | }
96 |
97 | auto operator[](int dex) {
98 | return items->getPointer()[dex];
99 | }
100 |
101 | int getSize() {
102 | return size;
103 | }
104 |
105 | int getVersion() {
106 | return version;
107 | }
108 | };
109 |
110 | template
111 | struct monoDictionary {
112 | void *unk0;
113 | void *unk1;
114 | monoArray *table;
115 | monoArray *linkSlots;
116 | monoArray *keys;
117 | monoArray *values;
118 | int touchedSlots;
119 | int emptySlot;
120 | int size;
121 |
122 | K getKeys() {
123 | return keys->getPointer();
124 | }
125 |
126 | V getValues() {
127 | return values->getPointer();
128 | }
129 |
130 | int getNumKeys() {
131 | return keys->getLength();
132 | }
133 |
134 | int getNumValues() {
135 | return values->getLength();
136 | }
137 |
138 | int getSize() {
139 | return size;
140 | }
141 | };
--------------------------------------------------------------------------------
/app/src/main/cpp/Engine/API/Vector2.hpp:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #define _USE_MATH_DEFINES
4 | #include
5 |
6 |
7 | struct Vector2
8 | {
9 | union
10 | {
11 | struct
12 | {
13 | float X;
14 | float Y;
15 | };
16 | float data[2];
17 | };
18 |
19 |
20 | /**
21 | * Constructors.
22 | */
23 | inline Vector2();
24 | inline Vector2(float value);
25 | inline Vector2(float x, float y);
26 |
27 |
28 | /**
29 | * Constants for common vectors.
30 | */
31 | static inline Vector2 Zero();
32 | static inline Vector2 One();
33 | static inline Vector2 Right();
34 | static inline Vector2 Left();
35 | static inline Vector2 Up();
36 | static inline Vector2 Down();
37 |
38 |
39 | /**
40 | * Returns the angle between two vectors in radians.
41 | * @param a: The first vector.
42 | * @param b: The second vector.
43 | * @return: A scalar value.
44 | */
45 | static inline float Angle(Vector2 a, Vector2 b);
46 |
47 | /**
48 | * Returns a vector with its magnitude clamped to maxLength.
49 | * @param vector: The target vector.
50 | * @param maxLength: The maximum length of the return vector.
51 | * @return: A new vector.
52 | */
53 | static inline Vector2 ClampMagnitude(Vector2 vector, float maxLength);
54 |
55 | /**
56 | * Returns the component of a in the direction of b (scalar projection).
57 | * @param a: The target vector.
58 | * @param b: The vector being compared against.
59 | * @return: A scalar value.
60 | */
61 | static inline float Component(Vector2 a, Vector2 b);
62 |
63 | /**
64 | * Returns the distance between a and b.
65 | * @param a: The first point.
66 | * @param b: The second point.
67 | * @return: A scalar value.
68 | */
69 | static inline float Distance(Vector2 a, Vector2 b);
70 |
71 | static inline std::string ToString(Vector2 a);
72 |
73 | /**
74 | * Returns the dot product of two vectors.
75 | * @param lhs: The left side of the multiplication.
76 | * @param rhs: The right side of the multiplication.
77 | * @return: A scalar value.
78 | */
79 | static inline float Dot(Vector2 lhs, Vector2 rhs);
80 |
81 | /**
82 | * Converts a polar representation of a vector into cartesian
83 | * coordinates.
84 | * @param rad: The magnitude of the vector.
85 | * @param theta: The angle from the X axis.
86 | * @return: A new vector.
87 | */
88 | static inline Vector2 FromPolar(float rad, float theta);
89 |
90 | /**
91 | * Returns a vector linearly interpolated between a and b, moving along
92 | * a straight line. The vector is clamped to never go beyond the end points.
93 | * @param a: The starting point.
94 | * @param b: The ending point.
95 | * @param t: The interpolation value [0-1].
96 | * @return: A new vector.
97 | */
98 | static inline Vector2 Lerp(Vector2 a, Vector2 b, float t);
99 |
100 | /**
101 | * Returns a vector linearly interpolated between a and b, moving along
102 | * a straight line.
103 | * @param a: The starting point.
104 | * @param b: The ending point.
105 | * @param t: The interpolation value [0-1] (no actual bounds).
106 | * @return: A new vector.
107 | */
108 | static inline Vector2 LerpUnclamped(Vector2 a, Vector2 b, float t);
109 |
110 | /**
111 | * Returns the magnitude of a vector.
112 | * @param v: The vector in question.
113 | * @return: A scalar value.
114 | */
115 | static inline float Magnitude(Vector2 v);
116 |
117 | /**
118 | * Returns a vector made from the largest components of two other vectors.
119 | * @param a: The first vector.
120 | * @param b: The second vector.
121 | * @return: A new vector.
122 | */
123 | static inline Vector2 Max(Vector2 a, Vector2 b);
124 |
125 | /**
126 | * Returns a vector made from the smallest components of two other vectors.
127 | * @param a: The first vector.
128 | * @param b: The second vector.
129 | * @return: A new vector.
130 | */
131 | static inline Vector2 Min(Vector2 a, Vector2 b);
132 |
133 | /**
134 | * Returns a vector "maxDistanceDelta" units closer to the target. This
135 | * interpolation is in a straight line, and will not overshoot.
136 | * @param current: The current position.
137 | * @param target: The destination position.
138 | * @param maxDistanceDelta: The maximum distance to move.
139 | * @return: A new vector.
140 | */
141 | static inline Vector2 MoveTowards(Vector2 current, Vector2 target,
142 | float maxDistanceDelta);
143 |
144 | /**
145 | * Returns a new vector with magnitude of one.
146 | * @param v: The vector in question.
147 | * @return: A new vector.
148 | */
149 | static inline Vector2 Normalized(Vector2 v);
150 |
151 | /**
152 | * Creates a new coordinate system out of the two vectors.
153 | * Normalizes "normal" and normalizes "tangent" and makes it orthogonal to
154 | * "normal"..
155 | * @param normal: A reference to the first axis vector.
156 | * @param tangent: A reference to the second axis vector.
157 | */
158 | static inline void OrthoNormalize(Vector2 &normal, Vector2 &tangent);
159 |
160 | /**
161 | * Returns the vector projection of a onto b.
162 | * @param a: The target vector.
163 | * @param b: The vector being projected onto.
164 | * @return: A new vector.
165 | */
166 | static inline Vector2 Project(Vector2 a, Vector2 b);
167 |
168 | /**
169 | * Returns a vector reflected about the provided line.
170 | * This behaves as if there is a plane with the line as its normal, and the
171 | * vector comes in and bounces off this plane.
172 | * @param vector: The vector traveling inward at the imaginary plane.
173 | * @param line: The line about which to reflect.
174 | * @return: A new vector pointing outward from the imaginary plane.
175 | */
176 | static inline Vector2 Reflect(Vector2 vector, Vector2 line);
177 |
178 | /**
179 | * Returns the vector rejection of a on b.
180 | * @param a: The target vector.
181 | * @param b: The vector being projected onto.
182 | * @return: A new vector.
183 | */
184 | static inline Vector2 Reject(Vector2 a, Vector2 b);
185 |
186 | /**
187 | * Rotates vector "current" towards vector "target" by "maxRadiansDelta".
188 | * This treats the vectors as directions and will linearly interpolate
189 | * between their magnitudes by "maxMagnitudeDelta". This function does not
190 | * overshoot. If a negative delta is supplied, it will rotate away from
191 | * "target" until it is pointing the opposite direction, but will not
192 | * overshoot that either.
193 | * @param current: The starting direction.
194 | * @param target: The destination direction.
195 | * @param maxRadiansDelta: The maximum number of radians to rotate.
196 | * @param maxMagnitudeDelta: The maximum delta for magnitude interpolation.
197 | * @return: A new vector.
198 | */
199 | static inline Vector2 RotateTowards(Vector2 current, Vector2 target,
200 | float maxRadiansDelta,
201 | float maxMagnitudeDelta);
202 |
203 | /**
204 | * Multiplies two vectors component-wise.
205 | * @param a: The lhs of the multiplication.
206 | * @param b: The rhs of the multiplication.
207 | * @return: A new vector.
208 | */
209 | static inline Vector2 Scale(Vector2 a, Vector2 b);
210 |
211 | /**
212 | * Returns a vector rotated towards b from a by the percent t.
213 | * Since interpolation is done spherically, the vector moves at a constant
214 | * angular velocity. This rotation is clamped to 0 <= t <= 1.
215 | * @param a: The starting direction.
216 | * @param b: The ending direction.
217 | * @param t: The interpolation value [0-1].
218 | */
219 | static inline Vector2 Slerp(Vector2 a, Vector2 b, float t);
220 |
221 | /**
222 | * Returns a vector rotated towards b from a by the percent t.
223 | * Since interpolation is done spherically, the vector moves at a constant
224 | * angular velocity. This rotation is unclamped.
225 | * @param a: The starting direction.
226 | * @param b: The ending direction.
227 | * @param t: The interpolation value [0-1].
228 | */
229 | static inline Vector2 SlerpUnclamped(Vector2 a, Vector2 b, float t);
230 |
231 | /**
232 | * Returns the squared magnitude of a vector.
233 | * This is useful when comparing relative lengths, where the exact length
234 | * is not important, and much time can be saved by not calculating the
235 | * square root.
236 | * @param v: The vector in question.
237 | * @return: A scalar value.
238 | */
239 | static inline float SqrMagnitude(Vector2 v);
240 |
241 | /**
242 | * Calculates the polar coordinate space representation of a vector.
243 | * @param vector: The vector to convert.
244 | * @param rad: The magnitude of the vector.
245 | * @param theta: The angle from the X axis.
246 | */
247 | static inline void ToPolar(Vector2 vector, float &rad, float &theta);
248 |
249 |
250 | /**
251 | * Operator overloading.
252 | */
253 | inline struct Vector2& operator+=(const float rhs);
254 | inline struct Vector2& operator-=(const float rhs);
255 | inline struct Vector2& operator*=(const float rhs);
256 | inline struct Vector2& operator/=(const float rhs);
257 | inline struct Vector2& operator+=(const Vector2 rhs);
258 | inline struct Vector2& operator-=(const Vector2 rhs);
259 | };
260 |
261 | inline Vector2 operator-(Vector2 rhs);
262 | inline Vector2 operator+(Vector2 lhs, const float rhs);
263 | inline Vector2 operator-(Vector2 lhs, const float rhs);
264 | inline Vector2 operator*(Vector2 lhs, const float rhs);
265 | inline Vector2 operator/(Vector2 lhs, const float rhs);
266 | inline Vector2 operator+(const float lhs, Vector2 rhs);
267 | inline Vector2 operator-(const float lhs, Vector2 rhs);
268 | inline Vector2 operator*(const float lhs, Vector2 rhs);
269 | inline Vector2 operator/(const float lhs, Vector2 rhs);
270 | inline Vector2 operator+(Vector2 lhs, const Vector2 rhs);
271 | inline Vector2 operator-(Vector2 lhs, const Vector2 rhs);
272 | inline bool operator==(const Vector2 lhs, const Vector2 rhs);
273 | inline bool operator!=(const Vector2 lhs, const Vector2 rhs);
274 |
275 |
276 |
277 | /*******************************************************************************
278 | * Implementation
279 | */
280 |
281 | Vector2::Vector2() : X(0), Y(0) {}
282 | Vector2::Vector2(float value) : X(value), Y(value) {}
283 | Vector2::Vector2(float x, float y) : X(x), Y(y) {}
284 |
285 |
286 | Vector2 Vector2::Zero() { return Vector2(0, 0); }
287 | Vector2 Vector2::One() { return Vector2(1, 1); }
288 | Vector2 Vector2::Right() { return Vector2(1, 0); }
289 | Vector2 Vector2::Left() { return Vector2(-1, 0); }
290 | Vector2 Vector2::Up() { return Vector2(0, 1); }
291 | Vector2 Vector2::Down() { return Vector2(0, -1); }
292 |
293 |
294 | float Vector2::Angle(Vector2 a, Vector2 b)
295 | {
296 | float v = Dot(a, b) / (Magnitude(a) * Magnitude(b));
297 | v = fmax(v, -1.0);
298 | v = fmin(v, 1.0);
299 | return acos(v);
300 | }
301 |
302 | Vector2 Vector2::ClampMagnitude(Vector2 vector, float maxLength)
303 | {
304 | float length = Magnitude(vector);
305 | if (length > maxLength)
306 | vector *= maxLength / length;
307 | return vector;
308 | }
309 |
310 | float Vector2::Component(Vector2 a, Vector2 b)
311 | {
312 | return Dot(a, b) / Magnitude(b);
313 | }
314 |
315 | float Vector2::Distance(Vector2 a, Vector2 b)
316 | {
317 | return Vector2::Magnitude(a - b);
318 | }
319 |
320 | std::string Vector2::ToString(Vector2 a){
321 | return to_string((int) a.X) + ", " + to_string((int) a.Y);
322 | }
323 |
324 | float Vector2::Dot(Vector2 lhs, Vector2 rhs)
325 | {
326 | return lhs.X * rhs.X + lhs.Y * rhs.Y;
327 | }
328 |
329 | Vector2 Vector2::FromPolar(float rad, float theta)
330 | {
331 | Vector2 v;
332 | v.X = rad * cos(theta);
333 | v.Y = rad * sin(theta);
334 | return v;
335 | }
336 |
337 | Vector2 Vector2::Lerp(Vector2 a, Vector2 b, float t)
338 | {
339 | if (t < 0) return a;
340 | else if (t > 1) return b;
341 | return LerpUnclamped(a, b, t);
342 | }
343 |
344 | Vector2 Vector2::LerpUnclamped(Vector2 a, Vector2 b, float t)
345 | {
346 | return (b - a) * t + a;
347 | }
348 |
349 | float Vector2::Magnitude(Vector2 v)
350 | {
351 | return sqrt(SqrMagnitude(v));
352 | }
353 |
354 | Vector2 Vector2::Max(Vector2 a, Vector2 b)
355 | {
356 | float x = a.X > b.X ? a.X : b.X;
357 | float y = a.Y > b.Y ? a.Y : b.Y;
358 | return Vector2(x, y);
359 | }
360 |
361 | Vector2 Vector2::Min(Vector2 a, Vector2 b)
362 | {
363 | float x = a.X > b.X ? b.X : a.X;
364 | float y = a.Y > b.Y ? b.Y : a.Y;
365 | return Vector2(x, y);
366 | }
367 |
368 | Vector2 Vector2::MoveTowards(Vector2 current, Vector2 target,
369 | float maxDistanceDelta)
370 | {
371 | Vector2 d = target - current;
372 | float m = Magnitude(d);
373 | if (m < maxDistanceDelta || m == 0)
374 | return target;
375 | return current + (d * maxDistanceDelta / m);
376 | }
377 |
378 | Vector2 Vector2::Normalized(Vector2 v)
379 | {
380 | float mag = Magnitude(v);
381 | if (mag == 0)
382 | return Vector2::Zero();
383 | return v / mag;
384 | }
385 |
386 | void Vector2::OrthoNormalize(Vector2 &normal, Vector2 &tangent)
387 | {
388 | normal = Normalized(normal);
389 | tangent = Reject(tangent, normal);
390 | tangent = Normalized(tangent);
391 | }
392 |
393 | Vector2 Vector2::Project(Vector2 a, Vector2 b)
394 | {
395 | float m = Magnitude(b);
396 | return Dot(a, b) / (m * m) * b;
397 | }
398 |
399 | Vector2 Vector2::Reflect(Vector2 vector, Vector2 planeNormal)
400 | {
401 | return vector - 2 * Project(vector, planeNormal);
402 | }
403 |
404 | Vector2 Vector2::Reject(Vector2 a, Vector2 b)
405 | {
406 | return a - Project(a, b);
407 | }
408 |
409 | Vector2 Vector2::RotateTowards(Vector2 current, Vector2 target,
410 | float maxRadiansDelta,
411 | float maxMagnitudeDelta)
412 | {
413 | float magCur = Magnitude(current);
414 | float magTar = Magnitude(target);
415 | float newMag = magCur + maxMagnitudeDelta *
416 | ((magTar > magCur) - (magCur > magTar));
417 | newMag = fmin(newMag, fmax(magCur, magTar));
418 | newMag = fmax(newMag, fmin(magCur, magTar));
419 |
420 | float totalAngle = Angle(current, target) - maxRadiansDelta;
421 | if (totalAngle <= 0)
422 | return Normalized(target) * newMag;
423 | else if (totalAngle >= M_PI)
424 | return Normalized(-target) * newMag;
425 |
426 | float axis = current.X * target.Y - current.Y * target.X;
427 | axis = axis / fabs(axis);
428 | if (1 - fabs(axis) >= 0.00001)
429 | axis = 1;
430 | current = Normalized(current);
431 | Vector2 newVector = current * cos(maxRadiansDelta) +
432 | Vector2(-current.Y, current.X) * sin(maxRadiansDelta) * axis;
433 | return newVector * newMag;
434 | }
435 |
436 | Vector2 Vector2::Scale(Vector2 a, Vector2 b)
437 | {
438 | return Vector2(a.X * b.X, a.Y * b.Y);
439 | }
440 |
441 | Vector2 Vector2::Slerp(Vector2 a, Vector2 b, float t)
442 | {
443 | if (t < 0) return a;
444 | else if (t > 1) return b;
445 | return SlerpUnclamped(a, b, t);
446 | }
447 |
448 | Vector2 Vector2::SlerpUnclamped(Vector2 a, Vector2 b, float t)
449 | {
450 | float magA = Magnitude(a);
451 | float magB = Magnitude(b);
452 | a /= magA;
453 | b /= magB;
454 | float dot = Dot(a, b);
455 | dot = fmax(dot, -1.0);
456 | dot = fmin(dot, 1.0);
457 | float theta = acos(dot) * t;
458 | Vector2 relativeVec = Normalized(b - a * dot);
459 | Vector2 newVec = a * cos(theta) + relativeVec * sin(theta);
460 | return newVec * (magA + (magB - magA) * t);
461 | }
462 |
463 | float Vector2::SqrMagnitude(Vector2 v)
464 | {
465 | return v.X * v.X + v.Y * v.Y;
466 | }
467 |
468 | void Vector2::ToPolar(Vector2 vector, float &rad, float &theta)
469 | {
470 | rad = Magnitude(vector);
471 | theta = atan2(vector.Y, vector.X);
472 | }
473 |
474 |
475 | struct Vector2& Vector2::operator+=(const float rhs)
476 | {
477 | X += rhs;
478 | Y += rhs;
479 | return *this;
480 | }
481 |
482 | struct Vector2& Vector2::operator-=(const float rhs)
483 | {
484 | X -= rhs;
485 | Y -= rhs;
486 | return *this;
487 | }
488 |
489 | struct Vector2& Vector2::operator*=(const float rhs)
490 | {
491 | X *= rhs;
492 | Y *= rhs;
493 | return *this;
494 | }
495 |
496 | struct Vector2& Vector2::operator/=(const float rhs)
497 | {
498 | X /= rhs;
499 | Y /= rhs;
500 | return *this;
501 | }
502 |
503 | struct Vector2& Vector2::operator+=(const Vector2 rhs)
504 | {
505 | X += rhs.X;
506 | Y += rhs.Y;
507 | return *this;
508 | }
509 |
510 | struct Vector2& Vector2::operator-=(const Vector2 rhs)
511 | {
512 | X -= rhs.X;
513 | Y -= rhs.Y;
514 | return *this;
515 | }
516 |
517 | Vector2 operator-(Vector2 rhs) { return rhs * -1; }
518 | Vector2 operator+(Vector2 lhs, const float rhs) { return lhs += rhs; }
519 | Vector2 operator-(Vector2 lhs, const float rhs) { return lhs -= rhs; }
520 | Vector2 operator*(Vector2 lhs, const float rhs) { return lhs *= rhs; }
521 | Vector2 operator/(Vector2 lhs, const float rhs) { return lhs /= rhs; }
522 | Vector2 operator+(const float lhs, Vector2 rhs) { return rhs += lhs; }
523 | Vector2 operator-(const float lhs, Vector2 rhs) { return rhs -= lhs; }
524 | Vector2 operator*(const float lhs, Vector2 rhs) { return rhs *= lhs; }
525 | Vector2 operator/(const float lhs, Vector2 rhs) { return rhs /= lhs; }
526 | Vector2 operator+(Vector2 lhs, const Vector2 rhs) { return lhs += rhs; }
527 | Vector2 operator-(Vector2 lhs, const Vector2 rhs) { return lhs -= rhs; }
528 |
529 | bool operator==(const Vector2 lhs, const Vector2 rhs)
530 | {
531 | return lhs.X == rhs.X && lhs.Y == rhs.Y;
532 | }
533 |
534 | bool operator!=(const Vector2 lhs, const Vector2 rhs)
535 | {
536 | return !(lhs == rhs);
537 | }
--------------------------------------------------------------------------------
/app/src/main/cpp/Engine/API/Vector3.hpp:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #define _USE_MATH_DEFINES
4 | #include
5 | #include
6 |
7 |
8 | struct Vector3
9 | {
10 | union
11 | {
12 | struct
13 | {
14 | float X;
15 | float Y;
16 | float Z;
17 | };
18 | float data[3];
19 | };
20 |
21 |
22 | /**
23 | * Constructors.
24 | */
25 | inline Vector3();
26 | inline Vector3(float data[]);
27 | inline Vector3(float value);
28 | inline Vector3(float x, float y);
29 | inline Vector3(float x, float y, float z);
30 |
31 |
32 | /**
33 | * Constants for common vectors.
34 | */
35 | static inline Vector3 Zero();
36 | static inline Vector3 One();
37 | static inline Vector3 Right();
38 | static inline Vector3 Left();
39 | static inline Vector3 Up();
40 | static inline Vector3 Down();
41 | static inline Vector3 Forward();
42 | static inline Vector3 Backward();
43 |
44 |
45 | /**
46 | * Returns the angle between two vectors in radians.
47 | * @param a: The first vector.
48 | * @param b: The second vector.
49 | * @return: A scalar value.
50 | */
51 | static inline float Angle(Vector3 a, Vector3 b);
52 |
53 | /**
54 | * Returns a vector with its magnitude clamped to maxLength.
55 | * @param vector: The target vector.
56 | * @param maxLength: The maximum length of the return vector.
57 | * @return: A new vector.
58 | */
59 | static inline Vector3 ClampMagnitude(Vector3 vector, float maxLength);
60 |
61 | /**
62 | * Returns the component of a in the direction of b (scalar projection).
63 | * @param a: The target vector.
64 | * @param b: The vector being compared against.
65 | * @return: A scalar value.
66 | */
67 | static inline float Component(Vector3 a, Vector3 b);
68 |
69 | /**
70 | * Returns the cross product of two vectors.
71 | * @param lhs: The left side of the multiplication.
72 | * @param rhs: The right side of the multiplication.
73 | * @return: A new vector.
74 | */
75 | static inline Vector3 Cross(Vector3 lhs, Vector3 rhs);
76 |
77 | /**
78 | * Returns the distance between a and b.
79 | * @param a: The first point.
80 | * @param b: The second point.
81 | * @return: A scalar value.
82 | */
83 | static inline float Distance(Vector3 a, Vector3 b);
84 |
85 | static inline std::string ToString(Vector3 a);
86 |
87 | /**
88 | * Returns the dot product of two vectors.
89 | * @param lhs: The left side of the multiplication.
90 | * @param rhs: The right side of the multiplication.
91 | * @return: A scalar value.
92 | */
93 | static inline float Dot(Vector3 lhs, Vector3 rhs);
94 |
95 | /**
96 | * Converts a spherical representation of a vector into cartesian
97 | * coordinates.
98 | * This uses the ISO convention (radius r, inclination theta, azimuth phi).
99 | * @param rad: The magnitude of the vector.
100 | * @param theta: The angle in the XY plane from the X axis.
101 | * @param phi: The angle from the positive Z axis to the vector.
102 | * @return: A new vector.
103 | */
104 | static inline Vector3 FromSpherical(float rad, float theta, float phi);
105 |
106 | /**
107 | * Returns a vector linearly interpolated between a and b, moving along
108 | * a straight line. The vector is clamped to never go beyond the end points.
109 | * @param a: The starting point.
110 | * @param b: The ending point.
111 | * @param t: The interpolation value [0-1].
112 | * @return: A new vector.
113 | */
114 | static inline Vector3 Lerp(Vector3 a, Vector3 b, float t);
115 |
116 | /**
117 | * Returns a vector linearly interpolated between a and b, moving along
118 | * a straight line.
119 | * @param a: The starting point.
120 | * @param b: The ending point.
121 | * @param t: The interpolation value [0-1] (no actual bounds).
122 | * @return: A new vector.
123 | */
124 | static inline Vector3 LerpUnclamped(Vector3 a, Vector3 b, float t);
125 |
126 | /**
127 | * Returns the magnitude of a vector.
128 | * @param v: The vector in question.
129 | * @return: A scalar value.
130 | */
131 | static inline float Magnitude(Vector3 v);
132 |
133 | /**
134 | * Returns a vector made from the largest components of two other vectors.
135 | * @param a: The first vector.
136 | * @param b: The second vector.
137 | * @return: A new vector.
138 | */
139 | static inline Vector3 Max(Vector3 a, Vector3 b);
140 |
141 | /**
142 | * Returns a vector made from the smallest components of two other vectors.
143 | * @param a: The first vector.
144 | * @param b: The second vector.
145 | * @return: A new vector.
146 | */
147 | static inline Vector3 Min(Vector3 a, Vector3 b);
148 |
149 | /**
150 | * Returns a vector "maxDistanceDelta" units closer to the target. This
151 | * interpolation is in a straight line, and will not overshoot.
152 | * @param current: The current position.
153 | * @param target: The destination position.
154 | * @param maxDistanceDelta: The maximum distance to move.
155 | * @return: A new vector.
156 | */
157 | static inline Vector3 MoveTowards(Vector3 current, Vector3 target,
158 | float maxDistanceDelta);
159 |
160 | /**
161 | * Returns a new vector with magnitude of one.
162 | * @param v: The vector in question.
163 | * @return: A new vector.
164 | */
165 | static inline Vector3 Normalized(Vector3 v);
166 |
167 | /**
168 | * Returns an arbitrary vector orthogonal to the input.
169 | * This vector is not normalized.
170 | * @param v: The input vector.
171 | * @return: A new vector.
172 | */
173 | static inline Vector3 Orthogonal(Vector3 v);
174 |
175 | /**
176 | * Creates a new coordinate system out of the three vectors.
177 | * Normalizes "normal", normalizes "tangent" and makes it orthogonal to
178 | * "normal" and normalizes "binormal" and makes it orthogonal to both
179 | * "normal" and "tangent".
180 | * @param normal: A reference to the first axis vector.
181 | * @param tangent: A reference to the second axis vector.
182 | * @param binormal: A reference to the third axis vector.
183 | */
184 | static inline void OrthoNormalize(Vector3 &normal, Vector3 &tangent,
185 | Vector3 &binormal);
186 |
187 | /**
188 | * Returns the vector projection of a onto b.
189 | * @param a: The target vector.
190 | * @param b: The vector being projected onto.
191 | * @return: A new vector.
192 | */
193 | static inline Vector3 Project(Vector3 a, Vector3 b);
194 |
195 | /**
196 | * Returns a vector projected onto a plane orthogonal to "planeNormal".
197 | * This can be visualized as the shadow of the vector onto the plane, if
198 | * the light source were in the direction of the plane normal.
199 | * @param vector: The vector to project.
200 | * @param planeNormal: The normal of the plane onto which to project.
201 | * @param: A new vector.
202 | */
203 | static inline Vector3 ProjectOnPlane(Vector3 vector, Vector3 planeNormal);
204 |
205 | /**
206 | * Returns a vector reflected off the plane orthogonal to the normal.
207 | * The input vector is pointed inward, at the plane, and the return vector
208 | * is pointed outward from the plane, like a beam of light hitting and then
209 | * reflecting off a mirror.
210 | * @param vector: The vector traveling inward at the plane.
211 | * @param planeNormal: The normal of the plane off of which to reflect.
212 | * @return: A new vector pointing outward from the plane.
213 | */
214 | static inline Vector3 Reflect(Vector3 vector, Vector3 planeNormal);
215 |
216 | /**
217 | * Returns the vector rejection of a on b.
218 | * @param a: The target vector.
219 | * @param b: The vector being projected onto.
220 | * @return: A new vector.
221 | */
222 | static inline Vector3 Reject(Vector3 a, Vector3 b);
223 |
224 | /**
225 | * Rotates vector "current" towards vector "target" by "maxRadiansDelta".
226 | * This treats the vectors as directions and will linearly interpolate
227 | * between their magnitudes by "maxMagnitudeDelta". This function does not
228 | * overshoot. If a negative delta is supplied, it will rotate away from
229 | * "target" until it is pointing the opposite direction, but will not
230 | * overshoot that either.
231 | * @param current: The starting direction.
232 | * @param target: The destination direction.
233 | * @param maxRadiansDelta: The maximum number of radians to rotate.
234 | * @param maxMagnitudeDelta: The maximum delta for magnitude interpolation.
235 | * @return: A new vector.
236 | */
237 | static inline Vector3 RotateTowards(Vector3 current, Vector3 target,
238 | float maxRadiansDelta,
239 | float maxMagnitudeDelta);
240 |
241 | /**
242 | * Multiplies two vectors element-wise.
243 | * @param a: The lhs of the multiplication.
244 | * @param b: The rhs of the multiplication.
245 | * @return: A new vector.
246 | */
247 | static inline Vector3 Scale(Vector3 a, Vector3 b);
248 |
249 | /**
250 | * Returns a vector rotated towards b from a by the percent t.
251 | * Since interpolation is done spherically, the vector moves at a constant
252 | * angular velocity. This rotation is clamped to 0 <= t <= 1.
253 | * @param a: The starting direction.
254 | * @param b: The ending direction.
255 | * @param t: The interpolation value [0-1].
256 | */
257 | static inline Vector3 Slerp(Vector3 a, Vector3 b, float t);
258 |
259 | /**
260 | * Returns a vector rotated towards b from a by the percent t.
261 | * Since interpolation is done spherically, the vector moves at a constant
262 | * angular velocity. This rotation is unclamped.
263 | * @param a: The starting direction.
264 | * @param b: The ending direction.
265 | * @param t: The interpolation value [0-1].
266 | */
267 | static inline Vector3 SlerpUnclamped(Vector3 a, Vector3 b, float t);
268 |
269 | /**
270 | * Returns the squared magnitude of a vector.
271 | * This is useful when comparing relative lengths, where the exact length
272 | * is not important, and much time can be saved by not calculating the
273 | * square root.
274 | * @param v: The vector in question.
275 | * @return: A scalar value.
276 | */
277 | static inline float SqrMagnitude(Vector3 v);
278 |
279 | /**
280 | * Calculates the spherical coordinate space representation of a vector.
281 | * This uses the ISO convention (radius r, inclination theta, azimuth phi).
282 | * @param vector: The vector to convert.
283 | * @param rad: The magnitude of the vector.
284 | * @param theta: The angle in the XY plane from the X axis.
285 | * @param phi: The angle from the positive Z axis to the vector.
286 | */
287 | static inline void ToSpherical(Vector3 vector, float &rad, float &theta,
288 | float &phi);
289 |
290 |
291 | /**
292 | * Operator overloading.
293 | */
294 | inline struct Vector3& operator+=(const float rhs);
295 | inline struct Vector3& operator-=(const float rhs);
296 | inline struct Vector3& operator*=(const float rhs);
297 | inline struct Vector3& operator/=(const float rhs);
298 | inline struct Vector3& operator+=(const Vector3 rhs);
299 | inline struct Vector3& operator-=(const Vector3 rhs);
300 | };
301 |
302 | inline Vector3 operator-(Vector3 rhs);
303 | inline Vector3 operator+(Vector3 lhs, const float rhs);
304 | inline Vector3 operator-(Vector3 lhs, const float rhs);
305 | inline Vector3 operator*(Vector3 lhs, const float rhs);
306 | inline Vector3 operator/(Vector3 lhs, const float rhs);
307 | inline Vector3 operator+(const float lhs, Vector3 rhs);
308 | inline Vector3 operator-(const float lhs, Vector3 rhs);
309 | inline Vector3 operator*(const float lhs, Vector3 rhs);
310 | inline Vector3 operator/(const float lhs, Vector3 rhs);
311 | inline Vector3 operator+(Vector3 lhs, const Vector3 rhs);
312 | inline Vector3 operator-(Vector3 lhs, const Vector3 rhs);
313 | inline bool operator==(const Vector3 lhs, const Vector3 rhs);
314 | inline bool operator!=(const Vector3 lhs, const Vector3 rhs);
315 |
316 |
317 |
318 | /*******************************************************************************
319 | * Implementation
320 | */
321 |
322 | Vector3::Vector3() : X(0), Y(0), Z(0) {}
323 | Vector3::Vector3(float data[]) : X(data[0]), Y(data[1]), Z(data[2]) {}
324 | Vector3::Vector3(float value) : X(value), Y(value), Z(value) {}
325 | Vector3::Vector3(float x, float y) : X(x), Y(y), Z(0) {}
326 | Vector3::Vector3(float x, float y, float z) : X(x), Y(y), Z(z) {}
327 |
328 |
329 | Vector3 Vector3::Zero() { return Vector3(0, 0, 0); }
330 | Vector3 Vector3::One() { return Vector3(1, 1, 1); }
331 | Vector3 Vector3::Right() { return Vector3(1, 0, 0); }
332 | Vector3 Vector3::Left() { return Vector3(-1, 0, 0); }
333 | Vector3 Vector3::Up() { return Vector3(0, 1, 0); }
334 | Vector3 Vector3::Down() { return Vector3(0, -1, 0); }
335 | Vector3 Vector3::Forward() { return Vector3(0, 0, 1); }
336 | Vector3 Vector3::Backward() { return Vector3(0, 0, -1); }
337 |
338 |
339 | float Vector3::Angle(Vector3 a, Vector3 b)
340 | {
341 | float v = Dot(a, b) / (Magnitude(a) * Magnitude(b));
342 | v = fmax(v, -1.0);
343 | v = fmin(v, 1.0);
344 | return acos(v);
345 | }
346 |
347 | Vector3 Vector3::ClampMagnitude(Vector3 vector, float maxLength)
348 | {
349 | float length = Magnitude(vector);
350 | if (length > maxLength)
351 | vector *= maxLength / length;
352 | return vector;
353 | }
354 |
355 | float Vector3::Component(Vector3 a, Vector3 b)
356 | {
357 | return Dot(a, b) / Magnitude(b);
358 | }
359 |
360 | Vector3 Vector3::Cross(Vector3 lhs, Vector3 rhs)
361 | {
362 | float x = lhs.Y * rhs.Z - lhs.Z * rhs.Y;
363 | float y = lhs.Z * rhs.X - lhs.X * rhs.Z;
364 | float z = lhs.X * rhs.Y - lhs.Y * rhs.X;
365 | return Vector3(x, y, z);
366 | }
367 |
368 | float Vector3::Distance(Vector3 a, Vector3 b)
369 | {
370 | return Vector3::Magnitude(a - b);
371 | }
372 |
373 | float Vector3::Dot(Vector3 lhs, Vector3 rhs)
374 | {
375 | return lhs.X * rhs.X + lhs.Y * rhs.Y + lhs.Z * rhs.Z;
376 | }
377 |
378 | Vector3 Vector3::FromSpherical(float rad, float theta, float phi)
379 | {
380 | Vector3 v;
381 | v.X = rad * sin(theta) * cos(phi);
382 | v.Y = rad * sin(theta) * sin(phi);
383 | v.Z = rad * cos(theta);
384 | return v;
385 | }
386 |
387 | Vector3 Vector3::Lerp(Vector3 a, Vector3 b, float t)
388 | {
389 | if (t < 0) return a;
390 | else if (t > 1) return b;
391 | return LerpUnclamped(a, b, t);
392 | }
393 |
394 | Vector3 Vector3::LerpUnclamped(Vector3 a, Vector3 b, float t)
395 | {
396 | return (b - a) * t + a;
397 | }
398 |
399 | float Vector3::Magnitude(Vector3 v)
400 | {
401 | return sqrt(SqrMagnitude(v));
402 | }
403 |
404 | Vector3 Vector3::Max(Vector3 a, Vector3 b)
405 | {
406 | float x = a.X > b.X ? a.X : b.X;
407 | float y = a.Y > b.Y ? a.Y : b.Y;
408 | float z = a.Z > b.Z ? a.Z : b.Z;
409 | return Vector3(x, y, z);
410 | }
411 |
412 | Vector3 Vector3::Min(Vector3 a, Vector3 b)
413 | {
414 | float x = a.X > b.X ? b.X : a.X;
415 | float y = a.Y > b.Y ? b.Y : a.Y;
416 | float z = a.Z > b.Z ? b.Z : a.Z;
417 | return Vector3(x, y, z);
418 | }
419 |
420 | Vector3 Vector3::MoveTowards(Vector3 current, Vector3 target,
421 | float maxDistanceDelta)
422 | {
423 | Vector3 d = target - current;
424 | float m = Magnitude(d);
425 | if (m < maxDistanceDelta || m == 0)
426 | return target;
427 | return current + (d * maxDistanceDelta / m);
428 | }
429 |
430 | Vector3 Vector3::Normalized(Vector3 v)
431 | {
432 | float mag = Magnitude(v);
433 | if (mag == 0)
434 | return Vector3::Zero();
435 | return v / mag;
436 | }
437 |
438 | Vector3 Vector3::Orthogonal(Vector3 v)
439 | {
440 | return v.Z < v.X ? Vector3(v.Y, -v.X, 0) : Vector3(0, -v.Z, v.Y);
441 | }
442 |
443 | void Vector3::OrthoNormalize(Vector3 &normal, Vector3 &tangent,
444 | Vector3 &binormal)
445 | {
446 | normal = Normalized(normal);
447 | tangent = ProjectOnPlane(tangent, normal);
448 | tangent = Normalized(tangent);
449 | binormal = ProjectOnPlane(binormal, tangent);
450 | binormal = ProjectOnPlane(binormal, normal);
451 | binormal = Normalized(binormal);
452 | }
453 |
454 | Vector3 Vector3::Project(Vector3 a, Vector3 b)
455 | {
456 | float m = Magnitude(b);
457 | return Dot(a, b) / (m * m) * b;
458 | }
459 |
460 | Vector3 Vector3::ProjectOnPlane(Vector3 vector, Vector3 planeNormal)
461 | {
462 | return Reject(vector, planeNormal);
463 | }
464 |
465 | Vector3 Vector3::Reflect(Vector3 vector, Vector3 planeNormal)
466 | {
467 | return vector - 2 * Project(vector, planeNormal);
468 | }
469 |
470 | Vector3 Vector3::Reject(Vector3 a, Vector3 b)
471 | {
472 | return a - Project(a, b);
473 | }
474 |
475 | Vector3 Vector3::RotateTowards(Vector3 current, Vector3 target,
476 | float maxRadiansDelta,
477 | float maxMagnitudeDelta)
478 | {
479 | float magCur = Magnitude(current);
480 | float magTar = Magnitude(target);
481 | float newMag = magCur + maxMagnitudeDelta *
482 | ((magTar > magCur) - (magCur > magTar));
483 | newMag = fmin(newMag, fmax(magCur, magTar));
484 | newMag = fmax(newMag, fmin(magCur, magTar));
485 |
486 | float totalAngle = Angle(current, target) - maxRadiansDelta;
487 | if (totalAngle <= 0)
488 | return Normalized(target) * newMag;
489 | else if (totalAngle >= M_PI)
490 | return Normalized(-target) * newMag;
491 |
492 | Vector3 axis = Cross(current, target);
493 | float magAxis = Magnitude(axis);
494 | if (magAxis == 0)
495 | axis = Normalized(Cross(current, current + Vector3(3.95, 5.32, -4.24)));
496 | else
497 | axis /= magAxis;
498 | current = Normalized(current);
499 | Vector3 newVector = current * cos(maxRadiansDelta) +
500 | Cross(axis, current) * sin(maxRadiansDelta);
501 | return newVector * newMag;
502 | }
503 |
504 | Vector3 Vector3::Scale(Vector3 a, Vector3 b)
505 | {
506 | return Vector3(a.X * b.X, a.Y * b.Y, a.Z * b.Z);
507 | }
508 |
509 | Vector3 Vector3::Slerp(Vector3 a, Vector3 b, float t)
510 | {
511 | if (t < 0) return a;
512 | else if (t > 1) return b;
513 | return SlerpUnclamped(a, b, t);
514 | }
515 |
516 | Vector3 Vector3::SlerpUnclamped(Vector3 a, Vector3 b, float t)
517 | {
518 | float magA = Magnitude(a);
519 | float magB = Magnitude(b);
520 | a /= magA;
521 | b /= magB;
522 | float dot = Dot(a, b);
523 | dot = fmax(dot, -1.0);
524 | dot = fmin(dot, 1.0);
525 | float theta = acos(dot) * t;
526 | Vector3 relativeVec = Normalized(b - a * dot);
527 | Vector3 newVec = a * cos(theta) + relativeVec * sin(theta);
528 | return newVec * (magA + (magB - magA) * t);
529 | }
530 |
531 | float Vector3::SqrMagnitude(Vector3 v)
532 | {
533 | return v.X * v.X + v.Y * v.Y + v.Z * v.Z;
534 | }
535 |
536 | void Vector3::ToSpherical(Vector3 vector, float &rad, float &theta,
537 | float &phi)
538 | {
539 | rad = Magnitude(vector);
540 | float v = vector.Z / rad;
541 | v = fmax(v, -1.0);
542 | v = fmin(v, 1.0);
543 | theta = acos(v);
544 | phi = atan2(vector.Y, vector.X);
545 | }
546 |
547 |
548 | struct Vector3& Vector3::operator+=(const float rhs)
549 | {
550 | X += rhs;
551 | Y += rhs;
552 | Z += rhs;
553 | return *this;
554 | }
555 |
556 | struct Vector3& Vector3::operator-=(const float rhs)
557 | {
558 | X -= rhs;
559 | Y -= rhs;
560 | Z -= rhs;
561 | return *this;
562 | }
563 |
564 | struct Vector3& Vector3::operator*=(const float rhs)
565 | {
566 | X *= rhs;
567 | Y *= rhs;
568 | Z *= rhs;
569 | return *this;
570 | }
571 |
572 | struct Vector3& Vector3::operator/=(const float rhs)
573 | {
574 | X /= rhs;
575 | Y /= rhs;
576 | Z /= rhs;
577 | return *this;
578 | }
579 |
580 | struct Vector3& Vector3::operator+=(const Vector3 rhs)
581 | {
582 | X += rhs.X;
583 | Y += rhs.Y;
584 | Z += rhs.Z;
585 | return *this;
586 | }
587 |
588 | struct Vector3& Vector3::operator-=(const Vector3 rhs)
589 | {
590 | X -= rhs.X;
591 | Y -= rhs.Y;
592 | Z -= rhs.Z;
593 | return *this;
594 | }
595 |
596 | std::string Vector3::ToString(Vector3 a) {
597 | return to_string((int) a.X) + ", " + to_string((int) a.Y) + ", " + to_string((int) a.Z);
598 | }
599 |
600 | Vector3 operator-(Vector3 rhs) { return rhs * -1; }
601 | Vector3 operator+(Vector3 lhs, const float rhs) { return lhs += rhs; }
602 | Vector3 operator-(Vector3 lhs, const float rhs) { return lhs -= rhs; }
603 | Vector3 operator*(Vector3 lhs, const float rhs) { return lhs *= rhs; }
604 | Vector3 operator/(Vector3 lhs, const float rhs) { return lhs /= rhs; }
605 | Vector3 operator+(const float lhs, Vector3 rhs) { return rhs += lhs; }
606 | Vector3 operator-(const float lhs, Vector3 rhs) { return rhs -= lhs; }
607 | Vector3 operator*(const float lhs, Vector3 rhs) { return rhs *= lhs; }
608 | Vector3 operator/(const float lhs, Vector3 rhs) { return rhs /= lhs; }
609 | Vector3 operator+(Vector3 lhs, const Vector3 rhs) { return lhs += rhs; }
610 | Vector3 operator-(Vector3 lhs, const Vector3 rhs) { return lhs -= rhs; }
611 |
612 | bool operator==(const Vector3 lhs, const Vector3 rhs)
613 | {
614 | return lhs.X == rhs.X && lhs.Y == rhs.Y && lhs.Z == rhs.Z;
615 | }
616 |
617 | bool operator!=(const Vector3 lhs, const Vector3 rhs)
618 | {
619 | return !(lhs == rhs);
620 | }
--------------------------------------------------------------------------------
/app/src/main/cpp/Engine/Includes.hpp:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | /*
4 | * macro definitions
5 | */
6 |
7 | #define getFieldOffset(method) Il2Cpp::GetFieldOffset(getAssembly(), getNamespace(), getClass(), method)
8 | #define getMethodOffset(method, param) (uintptr_t) Il2Cpp::GetMethodOffset(getAssembly(), getNamespace(), getClass(), method, param)
9 | #define getFieldStaticVal(method, out) Il2Cpp::GetStaticFieldValue(getAssembly(), getNamespace(), getClass(),method,out)
10 | #define setPointer(func, method, param) func = Il2Cpp::GetMethod(getAssembly(), getNamespace(), getClass(), method, param)
11 | #define setHook(func, func_name) \
12 | if (func != nullptr) \
13 | DobbyHook((void *) func, reinterpret_cast(new_##func), reinterpret_cast(&func)); \
14 | else \
15 | LOGE("Failed to hook %s", func_name); \
16 | \
17 | /*
18 | * API define
19 | */
20 |
21 | #include "Logger.h"
22 | #include "API/Unity.h"
23 | #include "KittyMemory/KittyInclude.hpp"
24 | #include
25 |
26 | /*
27 | * Early class define so it can be used for other classes
28 | */
29 | class ExampleEntry;
30 |
31 | /*
32 | * Include our structure classes
33 | */
34 | #include "Structure/ExampleEntry.hpp"
--------------------------------------------------------------------------------
/app/src/main/cpp/Engine/Structure/CBaseEntry.cpp:
--------------------------------------------------------------------------------
1 | #include "CBaseEntry.hpp"
2 |
3 | std::mutex listMutex;
4 | std::vector> list;
5 |
6 | template
7 | std::shared_ptr ListCBaseEntry::get() {
8 | std::lock_guard guard(listMutex);
9 | for (auto &entry : list) {
10 | if (dynamic_cast(entry)) {
11 | return std::static_pointer_cast(entry);
12 | }
13 | }
14 | return nullptr;
15 | }
16 |
17 | void ListCBaseEntry::add(const std::shared_ptr& entry) {
18 | std::lock_guard guard(listMutex);
19 | list.push_back(entry);
20 | }
21 |
22 | void ListCBaseEntry::remove(const std::shared_ptr& entry) {
23 | std::lock_guard guard(listMutex);
24 | auto it = std::find(list.begin(), list.end(), entry);
25 | if (it != list.end()) {
26 | list.erase(it);
27 | }
28 | }
29 |
30 | std::vector> ListCBaseEntry::getList() {
31 | std::lock_guard guard(listMutex);
32 | return list; // This makes a copy of the list
33 | }
34 |
35 | void ListCBaseEntry::Initialize() {
36 | std::lock_guard guard(listMutex);
37 | for (auto &entry : list) {
38 | entry->Initialize();
39 | entry->Hook();
40 | }
41 | }
--------------------------------------------------------------------------------
/app/src/main/cpp/Engine/Structure/CBaseEntry.hpp:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 | #include
5 | #include
6 |
7 | class CBaseEntry {
8 | public:
9 | virtual const char *getAssembly() = 0;
10 | virtual const char *getNamespace() = 0;
11 | virtual const char *getClass() = 0;
12 | virtual void Initialize() = 0;
13 |
14 | // TODO: Add this to the game loop
15 | virtual void Update() {};
16 |
17 | // Define all necessary hooks here
18 | virtual void Hook() = 0;
19 |
20 | virtual ~CBaseEntry() = default;
21 | };
22 |
23 | namespace ListCBaseEntry {
24 |
25 | void add(const std::shared_ptr& entry);
26 |
27 | void remove(const std::shared_ptr& entry);
28 |
29 | template
30 | std::shared_ptr get();
31 |
32 | std::vector> getList();
33 |
34 | void Initialize();
35 | };
--------------------------------------------------------------------------------
/app/src/main/cpp/Engine/Structure/ExampleEntry.cpp:
--------------------------------------------------------------------------------
1 | #include "../Includes.hpp"
2 |
3 | bool (*AreStatsValid)(ExampleEntry *, void *) = nullptr;
4 |
5 | bool new_AreStatsValid(ExampleEntry *self, void *a2) {
6 | return true;
7 | }
8 |
9 | void ExampleEntry::Initialize() {
10 | setPointer(AreStatsValid, "AreStatsValid", 1);
11 | }
12 |
13 | void ExampleEntry::Hook() {
14 | setHook(AreStatsValid, "AreStatsValid");
15 | }
16 |
17 | const char *ExampleEntry::getAssembly() {
18 | return "Assembly-CSharp.dll";
19 | }
20 |
21 | const char *ExampleEntry::getNamespace() {
22 | return "";
23 | }
24 |
25 | const char *ExampleEntry::getClass() {
26 | return "ExampleEntry";
27 | }
--------------------------------------------------------------------------------
/app/src/main/cpp/Engine/Structure/ExampleEntry.hpp:
--------------------------------------------------------------------------------
1 | #include "CBaseEntry.hpp"
2 |
3 | /*
4 | * This file is just sample, you can modify this
5 | */
6 | class ExampleEntry : public CBaseEntry {
7 | public:
8 | const char *getAssembly() override;
9 |
10 | const char *getNamespace() override;
11 |
12 | const char *getClass() override;
13 |
14 | void Initialize() override;
15 |
16 | void Hook() override;
17 | };
18 |
--------------------------------------------------------------------------------
/app/src/main/cpp/Utils/Logger.h:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | #define _TAG "cheat_native"
4 | #define LOGI(...) __android_log_print(ANDROID_LOG_INFO,_TAG,__VA_ARGS__)
5 | #define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,_TAG,__VA_ARGS__)
6 | #define LOGW(...) __android_log_print(ANDROID_LOG_WARN,_TAG,__VA_ARGS__)
7 | #define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,_TAG,__VA_ARGS__)
--------------------------------------------------------------------------------
/app/src/main/cpp/native-lib.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include "Engine/Includes.hpp"
5 |
6 | __attribute__ ((constructor))
7 | void lib_main() {
8 | std::thread([]() {
9 | ProcMap map;
10 | do {
11 | map = KittyMemory::getElfBaseMap("libil2cpp.so");
12 | sleep(1);
13 | } while (!map.isValid() && !map.isValidELF());
14 |
15 | if (Il2Cpp::Init("libil2cpp.so") == -1) {
16 | LOGE("Il2Cpp::Init Failed!");
17 | return;
18 | }
19 |
20 | // Initialize the classes
21 | ListCBaseEntry::add(std::make_shared());
22 | ListCBaseEntry::Initialize();
23 | }).detach();
24 | }
25 |
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 | plugins {
3 | id 'com.android.library' version '8.1.0' apply false
4 | }
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 | # IDE (e.g. Android Studio) users:
3 | # Gradle settings configured through the IDE *will override*
4 | # any settings specified in this file.
5 | # For more details on how to configure your build environment visit
6 | # http://www.gradle.org/docs/current/userguide/build_environment.html
7 | # Specifies the JVM arguments used for the daemon process.
8 | # The setting is particularly useful for tweaking memory settings.
9 | org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
10 | # When configured, Gradle will run in incubating parallel mode.
11 | # This option should only be used with decoupled projects. More details, visit
12 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
13 | # org.gradle.parallel=true
14 | # AndroidX package structure to make it clearer which packages are bundled with the
15 | # Android operating system, and which are packaged with your app's APK
16 | # https://developer.android.com/topic/libraries/support-library/androidx-rn
17 | android.useAndroidX=true
18 | # Enables namespacing of each library's R class so that its R class includes only the
19 | # resources declared in the library itself and none from the library's dependencies,
20 | # thereby reducing the size of the R class for that library
21 | android.nonTransitiveRClass=true
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BryanGIG/Android-Native-Mod/c7056e4c2b728ef298c0e816bbfe6971cdb1281e/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Wed Jan 03 17:57:32 ICT 2024
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.0-bin.zip
5 | zipStoreBase=GRADLE_USER_HOME
6 | zipStorePath=wrapper/dists
7 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 |
3 | #
4 | # Copyright 2015 the original author or authors.
5 | #
6 | # Licensed under the Apache License, Version 2.0 (the "License");
7 | # you may not use this file except in compliance with the License.
8 | # You may obtain a copy of the License at
9 | #
10 | # https://www.apache.org/licenses/LICENSE-2.0
11 | #
12 | # Unless required by applicable law or agreed to in writing, software
13 | # distributed under the License is distributed on an "AS IS" BASIS,
14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | # See the License for the specific language governing permissions and
16 | # limitations under the License.
17 | #
18 |
19 | ##############################################################################
20 | ##
21 | ## Gradle start up script for UN*X
22 | ##
23 | ##############################################################################
24 |
25 | # Attempt to set APP_HOME
26 | # Resolve links: $0 may be a link
27 | PRG="$0"
28 | # Need this for relative symlinks.
29 | while [ -h "$PRG" ] ; do
30 | ls=`ls -ld "$PRG"`
31 | link=`expr "$ls" : '.*-> \(.*\)$'`
32 | if expr "$link" : '/.*' > /dev/null; then
33 | PRG="$link"
34 | else
35 | PRG=`dirname "$PRG"`"/$link"
36 | fi
37 | done
38 | SAVED="`pwd`"
39 | cd "`dirname \"$PRG\"`/" >/dev/null
40 | APP_HOME="`pwd -P`"
41 | cd "$SAVED" >/dev/null
42 |
43 | APP_NAME="Gradle"
44 | APP_BASE_NAME=`basename "$0"`
45 |
46 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
47 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
48 |
49 | # Use the maximum available, or set MAX_FD != -1 to use that value.
50 | MAX_FD="maximum"
51 |
52 | warn () {
53 | echo "$*"
54 | }
55 |
56 | die () {
57 | echo
58 | echo "$*"
59 | echo
60 | exit 1
61 | }
62 |
63 | # OS specific support (must be 'true' or 'false').
64 | cygwin=false
65 | msys=false
66 | darwin=false
67 | nonstop=false
68 | case "`uname`" in
69 | CYGWIN* )
70 | cygwin=true
71 | ;;
72 | Darwin* )
73 | darwin=true
74 | ;;
75 | MINGW* )
76 | msys=true
77 | ;;
78 | NONSTOP* )
79 | nonstop=true
80 | ;;
81 | esac
82 |
83 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
84 |
85 |
86 | # Determine the Java command to use to start the JVM.
87 | if [ -n "$JAVA_HOME" ] ; then
88 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
89 | # IBM's JDK on AIX uses strange locations for the executables
90 | JAVACMD="$JAVA_HOME/jre/sh/java"
91 | else
92 | JAVACMD="$JAVA_HOME/bin/java"
93 | fi
94 | if [ ! -x "$JAVACMD" ] ; then
95 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
96 |
97 | Please set the JAVA_HOME variable in your environment to match the
98 | location of your Java installation."
99 | fi
100 | else
101 | JAVACMD="java"
102 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
103 |
104 | Please set the JAVA_HOME variable in your environment to match the
105 | location of your Java installation."
106 | fi
107 |
108 | # Increase the maximum file descriptors if we can.
109 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
110 | MAX_FD_LIMIT=`ulimit -H -n`
111 | if [ $? -eq 0 ] ; then
112 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
113 | MAX_FD="$MAX_FD_LIMIT"
114 | fi
115 | ulimit -n $MAX_FD
116 | if [ $? -ne 0 ] ; then
117 | warn "Could not set maximum file descriptor limit: $MAX_FD"
118 | fi
119 | else
120 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
121 | fi
122 | fi
123 |
124 | # For Darwin, add options to specify how the application appears in the dock
125 | if $darwin; then
126 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
127 | fi
128 |
129 | # For Cygwin or MSYS, switch paths to Windows format before running java
130 | if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
131 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
132 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
133 |
134 | JAVACMD=`cygpath --unix "$JAVACMD"`
135 |
136 | # We build the pattern for arguments to be converted via cygpath
137 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
138 | SEP=""
139 | for dir in $ROOTDIRSRAW ; do
140 | ROOTDIRS="$ROOTDIRS$SEP$dir"
141 | SEP="|"
142 | done
143 | OURCYGPATTERN="(^($ROOTDIRS))"
144 | # Add a user-defined pattern to the cygpath arguments
145 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
146 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
147 | fi
148 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
149 | i=0
150 | for arg in "$@" ; do
151 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
152 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
153 |
154 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
155 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
156 | else
157 | eval `echo args$i`="\"$arg\""
158 | fi
159 | i=`expr $i + 1`
160 | done
161 | case $i in
162 | 0) set -- ;;
163 | 1) set -- "$args0" ;;
164 | 2) set -- "$args0" "$args1" ;;
165 | 3) set -- "$args0" "$args1" "$args2" ;;
166 | 4) set -- "$args0" "$args1" "$args2" "$args3" ;;
167 | 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
168 | 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
169 | 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
170 | 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
171 | 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
172 | esac
173 | fi
174 |
175 | # Escape application args
176 | save () {
177 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
178 | echo " "
179 | }
180 | APP_ARGS=`save "$@"`
181 |
182 | # Collect all arguments for the java command, following the shell quoting and substitution rules
183 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
184 |
185 | exec "$JAVACMD" "$@"
186 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @rem
2 | @rem Copyright 2015 the original author or authors.
3 | @rem
4 | @rem Licensed under the Apache License, Version 2.0 (the "License");
5 | @rem you may not use this file except in compliance with the License.
6 | @rem You may obtain a copy of the License at
7 | @rem
8 | @rem https://www.apache.org/licenses/LICENSE-2.0
9 | @rem
10 | @rem Unless required by applicable law or agreed to in writing, software
11 | @rem distributed under the License is distributed on an "AS IS" BASIS,
12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | @rem See the License for the specific language governing permissions and
14 | @rem limitations under the License.
15 | @rem
16 |
17 | @if "%DEBUG%" == "" @echo off
18 | @rem ##########################################################################
19 | @rem
20 | @rem Gradle startup script for Windows
21 | @rem
22 | @rem ##########################################################################
23 |
24 | @rem Set local scope for the variables with windows NT shell
25 | if "%OS%"=="Windows_NT" setlocal
26 |
27 | set DIRNAME=%~dp0
28 | if "%DIRNAME%" == "" set DIRNAME=.
29 | set APP_BASE_NAME=%~n0
30 | set APP_HOME=%DIRNAME%
31 |
32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter.
33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
34 |
35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
37 |
38 | @rem Find java.exe
39 | if defined JAVA_HOME goto findJavaFromJavaHome
40 |
41 | set JAVA_EXE=java.exe
42 | %JAVA_EXE% -version >NUL 2>&1
43 | if "%ERRORLEVEL%" == "0" goto execute
44 |
45 | echo.
46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
47 | echo.
48 | echo Please set the JAVA_HOME variable in your environment to match the
49 | echo location of your Java installation.
50 |
51 | goto fail
52 |
53 | :findJavaFromJavaHome
54 | set JAVA_HOME=%JAVA_HOME:"=%
55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
56 |
57 | if exist "%JAVA_EXE%" goto execute
58 |
59 | echo.
60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
61 | echo.
62 | echo Please set the JAVA_HOME variable in your environment to match the
63 | echo location of your Java installation.
64 |
65 | goto fail
66 |
67 | :execute
68 | @rem Setup the command line
69 |
70 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
71 |
72 |
73 | @rem Execute Gradle
74 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
75 |
76 | :end
77 | @rem End local scope for the variables with windows NT shell
78 | if "%ERRORLEVEL%"=="0" goto mainEnd
79 |
80 | :fail
81 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
82 | rem the _cmd.exe /c_ return code!
83 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
84 | exit /b 1
85 |
86 | :mainEnd
87 | if "%OS%"=="Windows_NT" endlocal
88 |
89 | :omega
90 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | pluginManagement {
2 | repositories {
3 | google()
4 | mavenCentral()
5 | gradlePluginPortal()
6 | }
7 | }
8 | dependencyResolutionManagement {
9 | repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
10 | repositories {
11 | google()
12 | mavenCentral()
13 | }
14 | }
15 |
16 | rootProject.name = "Android Native Mod Template"
17 | include ':app'
18 |
--------------------------------------------------------------------------------