Wasm dans le moteur de l'armurerie

Pour ceux qui sont dans le réservoir, wasm ou WebAssembly est un langage de programmation de bas niveau pour une machine virtuelle de pile autrefois conçue comme une cible de compilation portable pour les langages de haut niveau tels que C, C ++, C #, Rust, Go. En termes simples, vous pouvez écrire du code haute performance, compact et portable à l'aide de wasm. Notre armurerie utilise également le wasm. Grâce à lui, le moteur peut fonctionner dans le navigateur et sur d'autres plates-formes utilisant Krom.





Traits en C et rouille

Wasm est également utilisé dans les traits ou les scripts. Pour ce faire, nous écrirons un script de rotation de cube en C.





Code de rotation du cube
#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;
}
      
      







Compiler le code source en C nous aidera à webassembly.studio . Nous allons déplacer le fichier wasm résultant dans le dossier blend_location / Bundled.





Ensuite, créons un cube dans Blender, allons dans les propriétés - Objet - Traits d'armurerie, créons un nouveau trait wasm, sélectionnez notre fichier wasm dans les modules . Appuyez sur F5 et regardez le cube tourner. Un exemple peut être téléchargé à partir d'ici .





La même chose mais seulement à Rust.





Code de rouille
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;
}
      
      







Nous compilons et transférons vers Bundled .





Appel au wasm de Haxe

Wasm peut être appelé directement à partir des propriétés écrites en haxe. Commençons par une simple fonction C.





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

WASM_EXPORT
float test() {
	return 0.01f;
}
      
      



Nous compilons la source dans webassembly.studio . Placez le fichier résultant dans blend_location / Bundled.





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



Des exemples peuvent être téléchargés ici .





  1. Moteur de l'armurerie. introduction





  2. Création de niveau dans l'armurerie





  3. Bases de l'armurerie. Traits












All Articles