Wasm no Armory Engine

Para aqueles que estão no tanque, wasm ou WebAssembly é uma linguagem de programação de baixo nível para uma máquina de pilha virtual, uma vez projetada como um alvo de compilação portátil para linguagens de alto nível, como C, C ++, C #, Rust, Go. Simplificando, você pode escrever código de alto desempenho, compacto e portátil usando wasm. Nosso Arsenal também usa wasm. Graças a ele, o motor pode rodar no navegador e em outras plataformas usando Krom.





Traços em C e Rust

Wasm também é usado em traits ou scripts. Para fazer isso, vamos escrever um script de rotação de cubo em C.





Código de rotação do cubo
#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;
}
      
      







Compilar o código-fonte em C nos ajudará a webassembly.studio . Iremos mover o arquivo wasm resultante para a pasta blend_location / Bundled.





A seguir, vamos criar um cubo no blender, vá para propriedades - Objeto - Traços de Arsenal, crie um novo traço de wasm, selecione nosso arquivo wasm em módulos . Pressione F5 e observe o cubo girar. Um exemplo pode ser baixado aqui .





A mesma coisa, mas apenas em Rust.





Código de ferrugem
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;
}
      
      







Nós compilamos e transferimos para o Bundled .





Ligando para o wasm de Haxe

Wasm pode ser chamado diretamente de propriedades escritas em haxe. Vamos começar com uma função C simples.





#define WASM_EXPORT __attribute__((visibility("default")))

WASM_EXPORT
float test() {
	return 0.01f;
}
      
      



Compilamos o código-fonte em webassembly.studio . Coloque o arquivo resultante em blend_location / Bundled.





Chamando test () de 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);
			});
		});
	}
}
      
      



Os exemplos podem ser baixados aqui .





  1. Armory Engine. Introdução





  2. Criação de nível no Armory





  3. Fundamentos do arsenal. Traços












All Articles