Wasm в Armory Engine

от автора

Для тех кто в танке — wasm или WebAssembly это язык программирования низкого уровня для виртуальной стековой машины раз разработанный как портативная цель компиляции для высокоуровневых языков, таких как Си, C++, C#, Rust, Go. Проще говоря вы можете писать высокопроизводительный, компактный и переносимый код используя wasm. Наш Armory тоже использует wasm. Благодаря ему движок может работать в браузере и на других платформах с использованием Krom.

Traits на С и Rust

Еще wasm используется в traits или скриптах. Для этого мы напишем скрипт вращения куба на языке Си.

Код вращения куба
#define WASM_EXPORT __attribute__((visibility("default")))  // Declare Armory API used in this module // github.com/armory3d/armory/blob/master/Sources/armory/trait/internal/wasm_api.h void notify_on_update(void* f); int get_object(const char* name); void set_transform(int object, float x, float y, float z, 	float rx, float ry, float rz, float sx, float sy, float sz);  WASM_EXPORT void update() { 	static float rot = 0.0f; 	rot += 0.01f; 	set_transform(get_object("Cube"), 0, 0, 0, 0, 0, rot, 1, 1, 1); // Set cube rotation }  // Include main function, Armory calls it when trait is instantiated WASM_EXPORT int main() { 	notify_on_update(update); // Register callback 	return 0; }

Скомпилировать этот исходник на С нам поможет webassembly.studio. Получившийся wasm файл мы переместим папку blend_location/Bundled.

Далее, создадим в blender куб, перейдем в properties — Object — Armory Traits, создадим новую wasm traits, в modules выберем наш wasm файл. Нажимаем F5 и смотрим как вращается куб. Пример можно скачать отсюда.

Тоже самое но только на Rust.

Код на Rust
extern {   fn notify_on_update(f: extern fn() -> ()) -> ();   fn get_object(name: *const i8) -> i32;   fn set_transform(object: i32, x: f32, y: f32, z: f32, rx: f32, ry: f32, rz: f32, sx: f32, sy: f32, sz: f32) -> (); }  #[no_mangle] pub extern "C" fn update() -> () {   unsafe {     let name = std::ffi::CString::new("Cube").unwrap();     let object = get_object(name.as_ptr());     static mut rot: f32 = 0.1;     rot += 0.01;     set_transform(object, 0.0, 0.0, 0.0, 0.0, 0.0, rot, 1.0, 1.0, 1.0);   } }  #[no_mangle] pub extern "C" fn main() -> i32 {   unsafe {     notify_on_update(update);   }   return 0; }

Компилируем и переносим в Bundled.

Вызов wasm на Haxe

Wasm можно вызвать прямо из properties написанного в haxe. Начнем с простой функции С.

#define WASM_EXPORT __attribute__((visibility("default")))  WASM_EXPORT float test() { 	return 0.01f; }

Компилируем исходник в webassembly.studio. Полученный файл помещаем в blend_location/Bundled.

Вызов test() из Haxe.

package arm; import iron.data.*  class MyTrait extends iron.Trait { 	public function new() { 		super(); 		notifyOnInit(init); 	}  	function init() { 		Data.getBlob("main.wasm", function(b:kha.Blob) { // Load wasm blob 			var wasm = Wasm.instance(b); // Create wasm module 			var rot = 0.0; 			notifyOnUpdate(function() { 				rot += wasm.exports.test(); // Call function from wasm module! 				object.transform.setRotation(0, 0, rot); 			}); 		}); 	} }

Примеры можно скачать отсюда.

  1. Armory Engine. Введение

  2. Создание уровня в Armory

  3. Основы Armory. Traits

ссылка на оригинал статьи https://habr.com/ru/post/531964/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *