Przeglądaj źródła

blendshapes: minor fixs and improvements

lviguier 1 rok temu
rodzic
commit
d8ec71cacc
1 zmienionych plików z 24 dodań i 17 usunięć
  1. 24 17
      h3d/prim/Blendshape.hx

+ 24 - 17
h3d/prim/Blendshape.hx

@@ -4,9 +4,7 @@ package h3d.prim;
 class Blendshape {
 class Blendshape {
 
 
 	var hmdModel : HMDModel;
 	var hmdModel : HMDModel;
-	var weights : Array<Float> = [];
-	var index : Int = 0;
-	var amount : Float = 0;
+	var weights : Array<Float>;
 	var inputMapping : Array<Map<String, Int>> = [];
 	var inputMapping : Array<Map<String, Int>> = [];
 	var shapesBytes = [];
 	var shapesBytes = [];
 
 
@@ -22,6 +20,8 @@ class Blendshape {
 		var size = hmdModel.data.vertexCount * vertexFormat.strideBytes;
 		var size = hmdModel.data.vertexCount * vertexFormat.strideBytes;
 		var shapes = hmdModel.lib.header.shapes;
 		var shapes = hmdModel.lib.header.shapes;
 
 
+		weights = [];
+
 		for ( s in 0...shapes.length ) {
 		for ( s in 0...shapes.length ) {
 			var s = shapes[s];
 			var s = shapes[s];
 
 
@@ -35,6 +35,8 @@ class Blendshape {
 
 
 			shapesBytes.push({ vertexBytes : vertexBytes, remapBytes : remapBytes});
 			shapesBytes.push({ vertexBytes : vertexBytes, remapBytes : remapBytes});
 			inputMapping.push(new Map());
 			inputMapping.push(new Map());
+
+			weights.push(0.0);
 		}
 		}
 
 
 		// We want to remap inputs since inputs can be not exactly in the same
 		// We want to remap inputs since inputs can be not exactly in the same
@@ -51,9 +53,10 @@ class Blendshape {
 	}
 	}
 
 
 	public function setBlendshapeAmount(blendshapeIdx: Int, amount: Float) {
 	public function setBlendshapeAmount(blendshapeIdx: Int, amount: Float) {
-		this.index = blendshapeIdx;
-		this.amount = amount;
+		if (blendshapeIdx >= this.weights.length)
+			throw 'Blendshape at index ${blendshapeIdx} doesn\'t exist (there is only ${this.weights.length} blendshapes).';
 
 
+		this.weights[blendshapeIdx] = amount;
 		uploadBlendshapeBytes();
 		uploadBlendshapeBytes();
 	}
 	}
 
 
@@ -65,6 +68,9 @@ class Blendshape {
 	}
 	}
 
 
 	function uploadBlendshapeBytes() {
 	function uploadBlendshapeBytes() {
+		if (hmdModel.buffer == null || hmdModel.buffer.isDisposed())
+			hmdModel.alloc(Engine.getCurrent());
+
 		var is32 = hmdModel.data.vertexCount > 0x10000;
 		var is32 = hmdModel.data.vertexCount > 0x10000;
 		var vertexFormat = hmdModel.data.vertexFormat;
 		var vertexFormat = hmdModel.data.vertexFormat;
 
 
@@ -72,21 +78,14 @@ class Blendshape {
 		var originalBytes = haxe.io.Bytes.alloc(size);
 		var originalBytes = haxe.io.Bytes.alloc(size);
 		hmdModel.lib.resource.entry.readBytes(originalBytes, 0, hmdModel.dataPosition + hmdModel.data.vertexPosition, size);
 		hmdModel.lib.resource.entry.readBytes(originalBytes, 0, hmdModel.dataPosition + hmdModel.data.vertexPosition, size);
 
 
+		var flagOffset = 31;
 		var shapes = hmdModel.lib.header.shapes;
 		var shapes = hmdModel.lib.header.shapes;
-		weights = [];
 
 
-		for ( s in 0...shapes.length )
-			weights[s] = s == index ? amount : 0.0;
-
-		var flagOffset = 31;
-		var bytes = haxe.io.Bytes.alloc(originalBytes.length);
-		bytes.blit(0, originalBytes, 0, originalBytes.length);
+		var bytesOffset = haxe.io.Bytes.alloc(originalBytes.length);
+		bytesOffset.fill(0, originalBytes.length, 0);
 
 
 		// Apply blendshapes offsets to original vertex
 		// Apply blendshapes offsets to original vertex
 		for (sIdx in 0...shapes.length) {
 		for (sIdx in 0...shapes.length) {
-			if (sIdx != index)
-				continue;
-
 			var sp = shapesBytes[sIdx];
 			var sp = shapesBytes[sIdx];
 			var offsetIdx = 0;
 			var offsetIdx = 0;
 			var idx = 0;
 			var idx = 0;
@@ -110,8 +109,10 @@ class Blendshape {
 							var original = originalBytes.getFloat(affectedVId * vertexFormat.stride + inputMapping[sIdx][input.name] + sizeIdx << 2);
 							var original = originalBytes.getFloat(affectedVId * vertexFormat.stride + inputMapping[sIdx][input.name] + sizeIdx << 2);
 							var offset = sp.vertexBytes.getFloat(offsetIdx * shapes[sIdx].vertexFormat.stride + offsetInput + sizeIdx << 2);
 							var offset = sp.vertexBytes.getFloat(offsetIdx * shapes[sIdx].vertexFormat.stride + offsetInput + sizeIdx << 2);
 
 
-							var res = hxd.Math.lerp(original, original + offset, weights[sIdx]);
-							bytes.setFloat(affectedVId * vertexFormat.stride + inputMapping[sIdx][input.name] + sizeIdx << 2, res);
+							var res = hxd.Math.lerp(original, original + offset, weights[sIdx]) - original;
+
+							var bytePos = affectedVId * vertexFormat.stride + inputMapping[sIdx][input.name] + sizeIdx << 2;
+							bytesOffset.setFloat(bytePos, bytesOffset.getFloat(bytePos) + res);
 						}
 						}
 
 
 						offsetInput += input.type.getSize();
 						offsetInput += input.type.getSize();
@@ -128,6 +129,12 @@ class Blendshape {
 			}
 			}
 		}
 		}
 
 
+		var bytes = haxe.io.Bytes.alloc(originalBytes.length);
+		bytes.blit(0, originalBytes, 0, originalBytes.length);
+
+		for (i in 0...(Std.int(bytesOffset.length / 4.0)))
+			bytes.setFloat(i << 2, bytes.getFloat(i << 2) + bytesOffset.getFloat(i << 2));
+
 		// Send bytes to buffer for rendering
 		// Send bytes to buffer for rendering
 		hmdModel.buffer.uploadBytes(bytes, 0, hmdModel.data.vertexCount);
 		hmdModel.buffer.uploadBytes(bytes, 0, hmdModel.data.vertexCount);
 		hmdModel.indexCount = 0;
 		hmdModel.indexCount = 0;