Wasm en el Armory Engine

Para aquellos en el tanque, wasm o WebAssembly es un lenguaje de programación de bajo nivel para una máquina de pila virtual que alguna vez fue diseñada como un destino de compilación portátil para lenguajes de alto nivel como C, C ++, C #, Rust, Go. En pocas palabras, puede escribir código de alto rendimiento, compacto y portátil utilizando wasm. Nuestra Armería también usa wasm. Gracias a él, el motor puede ejecutarse en el navegador y en otras plataformas usando Krom.





Rasgos en C y Rust

Wasm también se usa en rasgos o guiones. Para hacer esto, escribiremos un script de rotación de cubos en C.





Código de rotación del 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 el código fuente en C nos ayudará a webassembly.studio . Moviremos el archivo wasm resultante a la carpeta blend_location / Bundled.





A continuación, creemos un cubo en Blender, vayamos a propiedades - Objeto - Rasgos de armería, creemos un nuevo rasgo de wasm, seleccionemos nuestro archivo wasm en módulos . Presione F5 y observe cómo gira el cubo. Puede descargar un ejemplo desde aquí .





Lo mismo pero solo en Rust.





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







Recopilamos y transferimos a Bundled .





Llamando a wasm desde Haxe

Se puede llamar a Wasm directamente desde propiedades escritas en haxe. Comencemos con una función C simple.





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

WASM_EXPORT
float test() {
	return 0.01f;
}
      
      



Compilamos el código fuente en webassembly.studio . Coloque el archivo resultante en blend_location / Bundled.





Llamando test () desde 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);
			});
		});
	}
}
      
      



Se pueden descargar ejemplos desde aquí .





  1. Motor de armería. Introducción





  2. Creación de niveles en Armory





  3. Conceptos básicos de la armería. Rasgos












All Articles