130 lines
		
	
	
		
			3.4 KiB
		
	
	
	
		
			Haxe
		
	
	
	
	
	
			
		
		
	
	
			130 lines
		
	
	
		
			3.4 KiB
		
	
	
	
		
			Haxe
		
	
	
	
	
	
| package iron.data;
 | |
| 
 | |
| import kha.graphics4.Usage;
 | |
| import kha.graphics4.VertexData;
 | |
| import kha.arrays.Int16Array;
 | |
| import kha.arrays.Uint32Array;
 | |
| import iron.data.SceneFormat;
 | |
| 
 | |
| class MeshData {
 | |
| 
 | |
| 	public var name: String;
 | |
| 	public var raw: TMeshData;
 | |
| 	public var format: TSceneFormat;
 | |
| 	public var geom: Geometry;
 | |
| 	public var start = 0; // Batched
 | |
| 	public var count = -1;
 | |
| 	public var refcount = 0; // Number of users
 | |
| 	public var handle: String; // Handle used to retrieve this object in Data
 | |
| 	public var scalePos: kha.FastFloat = 1.0;
 | |
| 	public var scaleTex: kha.FastFloat = 1.0;
 | |
| 	public var isSkinned: Bool;
 | |
| 
 | |
| 	public function new(raw: TMeshData, done: MeshData->Void) {
 | |
| 		this.raw = raw;
 | |
| 		this.name = raw.name;
 | |
| 
 | |
| 		if (raw.scale_pos != null) scalePos = raw.scale_pos;
 | |
| 		if (raw.scale_tex != null) scaleTex = raw.scale_tex;
 | |
| 
 | |
| 		// Mesh data
 | |
| 		var indices: Array<Uint32Array> = [];
 | |
| 		var materialIndices: Array<Int> = [];
 | |
| 		for (ind in raw.index_arrays) {
 | |
| 			indices.push(ind.values);
 | |
| 			materialIndices.push(ind.material);
 | |
| 		}
 | |
| 
 | |
| 		// Skinning
 | |
| 		isSkinned = raw.skin != null;
 | |
| 
 | |
| 		// Prepare vertex array for skinning and fill size data
 | |
| 		var vertexArrays = raw.vertex_arrays;
 | |
| 		if (isSkinned) {
 | |
| 			vertexArrays.push({ attrib: "bone", values: null, data: "short4norm" });
 | |
| 			vertexArrays.push({ attrib: "weight", values: null, data: "short4norm" });
 | |
| 		}
 | |
| 		for (i in 0...vertexArrays.length) {
 | |
| 			vertexArrays[i].size = getVertexSize(vertexArrays[i].data, getPadding(vertexArrays[i].padding));
 | |
| 		}
 | |
| 
 | |
| 		// Usage, also used for instanced data
 | |
| 		var parsedUsage = Usage.StaticUsage;
 | |
| 		if (raw.dynamic_usage != null && raw.dynamic_usage == true) parsedUsage = Usage.DynamicUsage;
 | |
| 		var usage = parsedUsage;
 | |
| 
 | |
| 		if (isSkinned) {
 | |
| 			var bonea = null;
 | |
| 			var weighta = null;
 | |
| 			var vertex_length = Std.int(vertexArrays[0].values.length / vertexArrays[0].size);
 | |
| 			var l = vertex_length * 4;
 | |
| 			bonea = new Int16Array(l);
 | |
| 			weighta = new Int16Array(l);
 | |
| 
 | |
| 			var index = 0;
 | |
| 			var ai = 0;
 | |
| 			for (i in 0...vertex_length) {
 | |
| 				var boneCount = raw.skin.bone_count_array[i];
 | |
| 				for (j in index...(index + boneCount)) {
 | |
| 					bonea[ai] = raw.skin.bone_index_array[j];
 | |
| 					weighta[ai] = raw.skin.bone_weight_array[j];
 | |
| 					ai++;
 | |
| 				}
 | |
| 				// Fill unused weights
 | |
| 				for (j in boneCount...4) {
 | |
| 					bonea[ai] = 0;
 | |
| 					weighta[ai] = 0;
 | |
| 					ai++;
 | |
| 				}
 | |
| 				index += boneCount;
 | |
| 			}
 | |
| 			vertexArrays[vertexArrays.length - 2].values = bonea;
 | |
| 			vertexArrays[vertexArrays.length - 1].values = weighta;
 | |
| 		}
 | |
| 
 | |
| 		// Make vertex buffers
 | |
| 		geom = new Geometry(this, indices, materialIndices, usage);
 | |
| 		geom.name = name;
 | |
| 
 | |
| 		done(this);
 | |
| 	}
 | |
| 
 | |
| 	public function delete() {
 | |
| 		geom.delete();
 | |
| 	}
 | |
| 
 | |
| 	public static function parse(name: String, id: String, done: MeshData->Void) {
 | |
| 		Data.getSceneRaw(name, function(format: TSceneFormat) {
 | |
| 			var raw: TMeshData = Data.getMeshRawByName(format.mesh_datas, id);
 | |
| 			if (raw == null) {
 | |
| 				trace('Mesh data "$id" not found!');
 | |
| 				done(null);
 | |
| 			}
 | |
| 
 | |
| 			new MeshData(raw, function(dat: MeshData) {
 | |
| 				dat.format = format;
 | |
| 				// Skinned
 | |
| 				#if lnx_skin
 | |
| 				if (raw.skin != null) {
 | |
| 					dat.geom.initSkeletonTransforms(raw.skin.transformsI);
 | |
| 				}
 | |
| 				#end
 | |
| 				done(dat);
 | |
| 			});
 | |
| 		});
 | |
| 	}
 | |
| 
 | |
| 	function getVertexSize(vertex_data: String, padding: Int = 0): Int {
 | |
| 		switch (vertex_data) {
 | |
| 			case "short4norm": return 4 - padding;
 | |
| 			case "short2norm": return 2 - padding;
 | |
| 			default: return 0;
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	inline function getPadding(padding: Null<Int>): Int {
 | |
| 		return padding != null ? padding : 0;
 | |
| 	}
 | |
| }
 | |
| 
 |