forked from LeenkxTeam/LNXSDK
		
	
		
			
	
	
		
			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;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 |