Просмотр исходного кода

DynamicJoints: refactor + clear all allocs

lviguier 6 месяцев назад
Родитель
Сommit
a79861ff91
3 измененных файлов с 128 добавлено и 134 удалено
  1. 92 90
      h3d/anim/BufferAnimation.hx
  2. 5 1
      h3d/prim/ModelDatabase.hx
  3. 31 43
      h3d/scene/Skin.hx

+ 92 - 90
h3d/anim/BufferAnimation.hx

@@ -164,47 +164,99 @@ class BufferAnimation extends Animation {
 			}
 			}
 
 
 			var m = o.matrix;
 			var m = o.matrix;
-			var skinData = o.targetSkin?.skinData;
-			if( m != null && !(skinData != null && !skinData.allJoints[o.targetJoint].shouldReceiveAnimation())) {
-				if( layout.has(Position) ) {
-					m._41 = lerpValue();
-					m._42 = lerpValue();
-					m._43 = lerpValue();
-				} else {
-					m._41 = m._14;
-					m._42 = m._24;
-					m._43 = m._34;
-				}
+			if( m != null) {
+				var skinData = o.targetSkin?.skinData;
+				if (!(skinData != null && !skinData.allJoints[o.targetJoint].shouldReceiveAnimation())) {
+					if( layout.has(Position) ) {
+						m._41 = lerpValue();
+						m._42 = lerpValue();
+						m._43 = lerpValue();
+					} else {
+						m._41 = m._14;
+						m._42 = m._24;
+						m._43 = m._34;
+					}
+
+					if( layout.has(Rotation) ) {
+						var q1x : Float32 = data[offset1++];
+						var q1y : Float32 = data[offset1++];
+						var q1z : Float32 = data[offset1++];
+						var q1w : Float32 = Math.sqrt(hxd.Math.abs(1 - (q1x*q1x+q1y*q1y+q1z*q1z)));
+						var q2x : Float32 = data[offset2++];
+						var q2y : Float32 = data[offset2++];
+						var q2z : Float32 = data[offset2++];
+						var q2w : Float32 = Math.sqrt(hxd.Math.abs(1 - (q2x*q2x+q2y*q2y+q2z*q2z)));
+
+						// qlerp nearest
+						var dot = q1x * q2x + q1y * q2y + q1z * q2z + q1w * q2w;
+						var q2 = dot < 0 ? -k2 : k2;
+						var qx = q1x * k1 + q2x * q2;
+						var qy = q1y * k1 + q2y * q2;
+						var qz = q1z * k1 + q2z * q2;
+						var qw = q1w * k1 + q2w * q2;
+						// make sure the resulting quaternion is normalized
+						var ql = 1 / Math.sqrt(qx * qx + qy * qy + qz * qz + qw * qw);
+						qx *= ql;
+						qy *= ql;
+						qz *= ql;
+						qw *= ql;
+
+						if( decompose ) {
+							m._12 = qx;
+							m._13 = qy;
+							m._21 = qz;
+							m._23 = qw;
+							if( layout.has(Scale) ) {
+								m._11 = lerpValue();
+								m._22 = lerpValue();
+								m._33 = lerpValue();
+							} else {
+								m._11 = 1;
+								m._22 = 1;
+								m._33 = 1;
+							}
+						} else {
+							// quaternion to matrix
+							var xx = qx * qx;
+							var xy = qx * qy;
+							var xz = qx * qz;
+							var xw = qx * qw;
+							var yy = qy * qy;
+							var yz = qy * qz;
+							var yw = qy * qw;
+							var zz = qz * qz;
+							var zw = qz * qw;
+							m._11 = 1 - 2 * ( yy + zz );
+							m._12 = 2 * ( xy + zw );
+							m._13 = 2 * ( xz - yw );
+							m._21 = 2 * ( xy - zw );
+							m._22 = 1 - 2 * ( xx + zz );
+							m._23 = 2 * ( yz + xw );
+							m._31 = 2 * ( xz + yw );
+							m._32 = 2 * ( yz - xw );
+							m._33 = 1 - 2 * ( xx + yy );
+							if( layout.has(Scale) ) {
+								var sx = lerpValue();
+								var sy = lerpValue();
+								var sz = lerpValue();
+								m._11 *= sx;
+								m._12 *= sx;
+								m._13 *= sx;
+								m._21 *= sy;
+								m._22 *= sy;
+								m._23 *= sy;
+								m._31 *= sz;
+								m._32 *= sz;
+								m._33 *= sz;
+							}
+						}
+
+					} else {
+						m._12 = 0;
+						m._13 = 0;
+						m._21 = 0;
+						m._23 = decompose ? 1 : 0;
 
 
-				if( layout.has(Rotation) ) {
-					var q1x : Float32 = data[offset1++];
-					var q1y : Float32 = data[offset1++];
-					var q1z : Float32 = data[offset1++];
-					var q1w : Float32 = Math.sqrt(hxd.Math.abs(1 - (q1x*q1x+q1y*q1y+q1z*q1z)));
-					var q2x : Float32 = data[offset2++];
-					var q2y : Float32 = data[offset2++];
-					var q2z : Float32 = data[offset2++];
-					var q2w : Float32 = Math.sqrt(hxd.Math.abs(1 - (q2x*q2x+q2y*q2y+q2z*q2z)));
-
-					// qlerp nearest
-					var dot = q1x * q2x + q1y * q2y + q1z * q2z + q1w * q2w;
-					var q2 = dot < 0 ? -k2 : k2;
-					var qx = q1x * k1 + q2x * q2;
-					var qy = q1y * k1 + q2y * q2;
-					var qz = q1z * k1 + q2z * q2;
-					var qw = q1w * k1 + q2w * q2;
-					// make sure the resulting quaternion is normalized
-					var ql = 1 / Math.sqrt(qx * qx + qy * qy + qz * qz + qw * qw);
-					qx *= ql;
-					qy *= ql;
-					qz *= ql;
-					qw *= ql;
-
-					if( decompose ) {
-						m._12 = qx;
-						m._13 = qy;
-						m._21 = qz;
-						m._23 = qw;
 						if( layout.has(Scale) ) {
 						if( layout.has(Scale) ) {
 							m._11 = lerpValue();
 							m._11 = lerpValue();
 							m._22 = lerpValue();
 							m._22 = lerpValue();
@@ -214,56 +266,6 @@ class BufferAnimation extends Animation {
 							m._22 = 1;
 							m._22 = 1;
 							m._33 = 1;
 							m._33 = 1;
 						}
 						}
-					} else {
-						// quaternion to matrix
-						var xx = qx * qx;
-						var xy = qx * qy;
-						var xz = qx * qz;
-						var xw = qx * qw;
-						var yy = qy * qy;
-						var yz = qy * qz;
-						var yw = qy * qw;
-						var zz = qz * qz;
-						var zw = qz * qw;
-						m._11 = 1 - 2 * ( yy + zz );
-						m._12 = 2 * ( xy + zw );
-						m._13 = 2 * ( xz - yw );
-						m._21 = 2 * ( xy - zw );
-						m._22 = 1 - 2 * ( xx + zz );
-						m._23 = 2 * ( yz + xw );
-						m._31 = 2 * ( xz + yw );
-						m._32 = 2 * ( yz - xw );
-						m._33 = 1 - 2 * ( xx + yy );
-						if( layout.has(Scale) ) {
-							var sx = lerpValue();
-							var sy = lerpValue();
-							var sz = lerpValue();
-							m._11 *= sx;
-							m._12 *= sx;
-							m._13 *= sx;
-							m._21 *= sy;
-							m._22 *= sy;
-							m._23 *= sy;
-							m._31 *= sz;
-							m._32 *= sz;
-							m._33 *= sz;
-						}
-					}
-
-				} else {
-					m._12 = 0;
-					m._13 = 0;
-					m._21 = 0;
-					m._23 = decompose ? 1 : 0;
-
-					if( layout.has(Scale) ) {
-						m._11 = lerpValue();
-						m._22 = lerpValue();
-						m._33 = lerpValue();
-					} else {
-						m._11 = 1;
-						m._22 = 1;
-						m._33 = 1;
 					}
 					}
 				}
 				}
 
 

+ 5 - 1
h3d/prim/ModelDatabase.hx

@@ -162,8 +162,12 @@ class ModelDatabase {
 			newJ.globalForce = new Vector(jConf.globalForce.x, jConf.globalForce.y, jConf.globalForce.z);
 			newJ.globalForce = new Vector(jConf.globalForce.x, jConf.globalForce.y, jConf.globalForce.z);
 			skinData.allJoints[j.index] = newJ;
 			skinData.allJoints[j.index] = newJ;
 
 
-			j.parent?.subs.remove(j);
 			j.parent?.subs.push(newJ);
 			j.parent?.subs.push(newJ);
+			j.parent?.subs.remove(j);
+			if (newJ.subs != null) {
+				for (s in newJ.subs)
+					s.parent = newJ;
+			}
 		}
 		}
 
 
 		input.skin.setSkinData(skinData);
 		input.skin.setSkinData(skinData);

+ 31 - 43
h3d/scene/Skin.hx

@@ -105,10 +105,13 @@ class JointData {
 @:access(h3d.scene.Skin)
 @:access(h3d.scene.Skin)
 class DynamicJointData extends JointData {
 class DynamicJointData extends JointData {
 	public var absPos : h3d.Matrix;
 	public var absPos : h3d.Matrix;
+	public var relPos : h3d.Matrix;
 	public var speed : h3d.Vector;
 	public var speed : h3d.Vector;
 
 
 	static var newWorldPos = new Vector(0, 0, 0);
 	static var newWorldPos = new Vector(0, 0, 0);
 	static var expectedPos = new Vector(0, 0, 0);
 	static var expectedPos = new Vector(0, 0, 0);
+	static var tmpVec = new Vector(0, 0, 0);
+	static var tmpVec2 = new Vector(0, 0, 0);
 	static var tmpQ = new Quat();
 	static var tmpQ = new Quat();
 
 
 	var f = -1;
 	var f = -1;
@@ -167,41 +170,42 @@ class DynamicJointData extends JointData {
 	function computeDyn(skin: h3d.scene.Skin, j: h3d.anim.Skin.Joint) {
 	function computeDyn(skin: h3d.scene.Skin, j: h3d.anim.Skin.Joint) {
 		var j : DynamicJoint = cast j;
 		var j : DynamicJoint = cast j;
 		var jData : DynamicJointData = Std.downcast(skin.jointsData[j.index], DynamicJointData);
 		var jData : DynamicJointData = Std.downcast(skin.jointsData[j.index], DynamicJointData);
-		jData.speed?.load(Std.downcast(skin.jointsData[j.index], DynamicJointData).speed);
-		jData.absPos?.load(Std.downcast(skin.jointsData[j.index], DynamicJointData).absPos);
-		var absPos = absPos == null ? jData.currentAbsPose : absPos;
-		var relPos = jData.currentRelPose == null ? j.defMat : jData.currentRelPose;
-		var newWorldPos = absPos.getPosition();
-		var expectedPos = absPos.getPosition();
+		var absPos = jData.absPos == null ?  jData.currentAbsPose : jData.absPos;
+		var relPos = j.defMat;
+		newWorldPos.load(absPos.getPosition());
+		expectedPos.load(absPos.getPosition());
 
 
 		// Resistance (force resistance)
 		// Resistance (force resistance)
 		var globalForce = j.globalForce;
 		var globalForce = j.globalForce;
-		speed += globalForce * (1.0 - j.resistance);
+		speed.load(speed + globalForce * (1.0 - j.resistance));
 
 
 		// Damping (inertia attenuation)
 		// Damping (inertia attenuation)
 		jData.speed *= 1.0 - j.damping;
 		jData.speed *= 1.0 - j.damping;
 		if (jData.speed.lengthSq() > DynamicJoint.SLEEP_THRESHOLD)
 		if (jData.speed.lengthSq() > DynamicJoint.SLEEP_THRESHOLD)
-			newWorldPos += jData.speed * hxd.Timer.dt;
+			newWorldPos.load(newWorldPos + jData.speed * hxd.Timer.dt);
 
 
 		// Stiffness (shape keeper)
 		// Stiffness (shape keeper)
-        expectedPos = relPos.multiplied(skin.jointsData[j.parent.index].currentAbsPose).getPosition();
+		Skin.TMP_MAT.multiply(relPos, skin.jointsData[j.parent.index].currentAbsPose);
+        expectedPos.load(Skin.TMP_MAT.getPosition());
         newWorldPos.lerp(newWorldPos, expectedPos, j.stiffness);
         newWorldPos.lerp(newWorldPos, expectedPos, j.stiffness);
 
 
 		// Slackness (length keeper)
 		// Slackness (length keeper)
 		var dirToParent = (newWorldPos - skin.jointsData[j.parent.index].currentAbsPose.getPosition()).normalized();
 		var dirToParent = (newWorldPos - skin.jointsData[j.parent.index].currentAbsPose.getPosition()).normalized();
 		var lengthToParent = relPos.getPosition().length();
 		var lengthToParent = relPos.getPosition().length();
-		expectedPos = skin.jointsData[j.parent.index].currentAbsPose.getPosition() + dirToParent * lengthToParent;
+		expectedPos.load(skin.jointsData[j.parent.index].currentAbsPose.getPosition() + dirToParent * lengthToParent);
 		newWorldPos.lerp(expectedPos, newWorldPos, j.slackness);
 		newWorldPos.lerp(expectedPos, newWorldPos, j.slackness);
 
 
 		// Apply computed position to joint
 		// Apply computed position to joint
-		jData.speed = (jData.speed + (newWorldPos - absPos.getPosition()) * (1.0 / hxd.Timer.dt)) * 0.5;
+		jData.speed.load((jData.speed + (newWorldPos - absPos.getPosition()) * (1.0 / hxd.Timer.dt)) * 0.5);
 		jData.currentAbsPose.setPosition(newWorldPos);
 		jData.currentAbsPose.setPosition(newWorldPos);
 		if (jData.absPos == null)
 		if (jData.absPos == null)
 			jData.absPos = new h3d.Matrix();
 			jData.absPos = new h3d.Matrix();
-		jData.absPos.load(jData.currentAbsPose.clone());
-		if (jData.currentRelPose == null)
-			jData.currentRelPose = new Matrix();
-		jData.currentRelPose.load(relPos);
+		jData.absPos.load(jData.currentAbsPose);
+		if (jData.relPos == null)
+			jData.relPos = new Matrix();
+
+		skin.jointsData[j.parent.index].currentAbsPose.getInverse(Skin.TMP_MAT);
+		jData.relPos.multiply(jData.absPos, Skin.TMP_MAT);
 
 
 		if( j.bindIndex >= 0 )
 		if( j.bindIndex >= 0 )
 			skin.currentPalette[j.bindIndex].multiply3x4inline(j.transPos, jData.currentAbsPose);
 			skin.currentPalette[j.bindIndex].multiply3x4inline(j.transPos, jData.currentAbsPose);
@@ -211,45 +215,29 @@ class DynamicJointData extends JointData {
 	}
 	}
 
 
 	function computeRotationDyn(skin: h3d.scene.Skin, j: h3d.anim.Skin.Joint) {
 	function computeRotationDyn(skin: h3d.scene.Skin, j: h3d.anim.Skin.Joint) {
-		if ( j.follow != null || j.subs.length != 1 ) return;
-
-		var child = Std.downcast(j.subs[0], DynamicJoint);
-		if (child == null) return;
+		if ( j.follow != null ) return;
 
 
 		var jData = skin.jointsData[j.index];
 		var jData = skin.jointsData[j.index];
 		var jDynData = Std.downcast(skin.jointsData[j.index], DynamicJointData);
 		var jDynData = Std.downcast(skin.jointsData[j.index], DynamicJointData);
-		Skin.TMP_MAT.load(jData.currentAbsPose);
 		var dynJoint = Std.downcast(j, DynamicJoint);
 		var dynJoint = Std.downcast(j, DynamicJoint);
-		if (dynJoint != null)
-			Skin.TMP_MAT.load(jDynData.absPos);
-
-		var offset = Std.downcast(skin.jointsData[child.index], DynamicJointData).absPos.getPosition() - Skin.TMP_MAT.getPosition();
-		offset.transform3x3(jData.currentAbsPose.getInverse());
-		tmpQ.initMoveTo(Std.downcast(skin.jointsData[child.index], DynamicJointData).currentRelPose.getPosition().normalized(), offset.normalized());
-		tmpQ.toMatrix(Skin.TMP_MAT);
+		if (j.subs.length == 1) {
+			var child = Std.downcast(j.subs[0], DynamicJoint);
+			if (child == null) return;
 
 
-		jData.currentAbsPose.multiply(Skin.TMP_MAT, jData.currentAbsPose);
+			var childData = Std.downcast(skin.jointsData[child.index], DynamicJointData);
+			tmpVec.load(child.defMat.getPosition().normalized());
+			tmpVec2.load(childData.relPos.getPosition().normalized());
+			tmpQ.initMoveTo(tmpVec, tmpVec2);
+			tmpQ.toMatrix(Skin.TMP_MAT);
 
 
-		if (j.subs != null) {
-			for (s in j.subs)
-				recomputeAbsPos(skin, cast s);
+			jData.currentAbsPose.multiply(Skin.TMP_MAT, jData.currentAbsPose);
 		}
 		}
 
 
 		if( j.bindIndex >= 0 )
 		if( j.bindIndex >= 0 )
 			skin.currentPalette[j.bindIndex].multiply3x4inline(j.transPos, jData.currentAbsPose);
 			skin.currentPalette[j.bindIndex].multiply3x4inline(j.transPos, jData.currentAbsPose);
 
 
-		if (dynJoint != null)
-			jData.currentAbsPose.load(jDynData.absPos);
-	}
-
-	function recomputeAbsPos(skin: h3d.scene.Skin, dynJoint : DynamicJoint) {
-		var r = skin.jointsData[dynJoint.index].currentRelPose;
-		skin.jointsData[dynJoint.index].currentAbsPose.multiply3x4inline(r != null ? r : dynJoint.defMat, skin.jointsData[dynJoint.parent.index].currentAbsPose);
-		if (dynJoint.subs == null)
-			return;
-
-		for (s in dynJoint.subs)
-			recomputeAbsPos(skin, cast s);
+		if (jDynData != null)
+			jDynData.absPos.load(jDynData.currentAbsPose);
 	}
 	}
 }
 }