Explorar o código

working HMD skin animation

Nicolas Cannasse %!s(int64=11) %!d(string=hai) anos
pai
achega
c640e58698
Modificáronse 3 ficheiros con 59 adicións e 8 borrados
  1. 16 2
      hxd/fmt/fbx/HMDOut.hx
  2. 37 5
      hxd/fmt/hmd/Library.hx
  3. 6 1
      samples/skin/Main.hx

+ 16 - 2
hxd/fmt/fbx/HMDOut.hx

@@ -44,7 +44,7 @@ class HMDOut extends BaseLibrary {
 		var stride = 3 + (normals == null ? 0 : 3) + uvs.length * 2 + (colors == null ? 0 : 3);
 		if( skin != null ) {
 			if( bonesPerVertex <= 0 || bonesPerVertex > 4 ) throw "assert";
-			g.vertexFormat.push(new GeometryFormat("weights", [DFloat, DVec2, DVec3, DVec4][bonesPerVertex]));
+			g.vertexFormat.push(new GeometryFormat("weights", [DFloat, DVec2, DVec3, DVec4][bonesPerVertex-1]));
 			g.vertexFormat.push(new GeometryFormat("indexes", DBytes4));
 			stride += 1 + bonesPerVertex;
 		}
@@ -273,6 +273,12 @@ class HMDOut extends BaseLibrary {
 
 			var q = m.toQuaternion(true);
 			q.normalize();
+			if( q.w < 0 ) {
+				q.x *= -1;
+				q.y *= -1;
+				q.z *= -1;
+				q.w *= -1;
+			}
 			p.qx = q.x;
 			p.qy = q.y;
 			p.qz = q.z;
@@ -381,7 +387,8 @@ class HMDOut extends BaseLibrary {
 			j.parent = jo.parent == null ? -1 : jo.parent.index;
 			j.bind = jo.bindIndex;
 			j.position = makePosition(jo.defMat);
-			if( jo.transPos != null ) j.transpos = makePosition(jo.transPos);
+			if( jo.transPos != null )
+				j.transpos = makePosition(jo.transPos);
 			s.joints.push(j);
 		}
 		return s;
@@ -392,6 +399,12 @@ class HMDOut extends BaseLibrary {
 		var q = new h3d.Quat();
 		q.initRotateMatrix(m);
 		q.normalize();
+		if( q.w < 0 ) {
+			q.x *= -1;
+			q.y *= -1;
+			q.z *= -1;
+			q.w *= -1;
+		}
 		p.sx = 1;
 		p.sy = 1;
 		p.sz = 1;
@@ -432,6 +445,7 @@ class HMDOut extends BaseLibrary {
 					}
 					if( o.flags.has(HasRotation) ) {
 						var ql = Math.sqrt(f.qx * f.qx + f.qy * f.qy + f.qz * f.qz + f.qw * f.qw);
+						if( f.qw < 0 ) ql = -ql;
 						dataOut.writeFloat(f.qx / ql);
 						dataOut.writeFloat(f.qy / ql);
 						dataOut.writeFloat(f.qz / ql);

+ 37 - 5
hxd/fmt/hmd/Library.hx

@@ -7,12 +7,14 @@ class Library {
 	var header : Data;
 	var cachedPrimitives : Array<h3d.prim.Primitive>;
 	var cachedAnimations : Map<String, h3d.anim.Animation>;
+	var cachedSkin : Map<String, h3d.anim.Skin>;
 
 	public function new(entry, header) {
 		this.entry = entry;
 		this.header = header;
 		cachedPrimitives = [];
 		cachedAnimations = new Map();
+		cachedSkin = new Map();
 	}
 
 	function makePrimitive( id : Int ) {
@@ -41,8 +43,36 @@ class Library {
 		return mat;
 	}
 
+	@:access(h3d.anim.Skin)
 	function makeSkin( skin : Skin ) {
-		var s = new h3d.anim.Skin(skin.name, 0, 3);
+		var s = cachedSkin.get(skin.name);
+		if( s != null )
+			return s;
+		s = new h3d.anim.Skin(skin.name, 0, 3);
+		s.namedJoints = new Map();
+		s.allJoints = [];
+		s.boundJoints = [];
+		s.rootJoints = [];
+		for( joint in skin.joints ) {
+			var j = new h3d.anim.Skin.Joint();
+			j.name = joint.name;
+			j.index = s.allJoints.length;
+			j.defMat = joint.position.toMatrix();
+			if( joint.bind >= 0 ) {
+				j.bindIndex = joint.bind;
+				j.transPos = joint.transpos.toMatrix();
+				s.boundJoints[j.bindIndex] = j;
+			}
+			if( joint.parent >= 0 ) {
+				var p = s.allJoints[joint.parent];
+				p.subs.push(j);
+				j.parent = p;
+			} else
+				s.rootJoints.push(j);
+			s.allJoints.push(j);
+			s.namedJoints.set(j.name, j);
+		}
+		cachedSkin.set(skin.name, s);
 		return s;
 	}
 
@@ -58,9 +88,11 @@ class Library {
 				obj = new h3d.scene.Object();
 			} else {
 				var prim = m.geometries.length == 1 ? makePrimitive(m.geometries[0]) : new h3d.prim.MultiPrimitive([for( g in m.geometries ) makePrimitive(g)]);
-				if( m.skin != null )
-					obj = new h3d.scene.Skin(makeSkin(m.skin), [for( m in m.materials ) makeMaterial(m, loadTexture)]);
-				else if( m.materials.length == 1 )
+				if( m.skin != null ) {
+					var sk = new h3d.scene.Skin(makeSkin(m.skin), [for( m in m.materials ) makeMaterial(m, loadTexture)]);
+					sk.primitive = prim;
+					obj = sk;
+				} else if( m.materials.length == 1 )
 					obj = new h3d.scene.Mesh(prim, makeMaterial(m.materials[0],loadTexture));
 				else
 					obj = new h3d.scene.MultiMaterial(prim, [for( m in m.materials ) makeMaterial(m,loadTexture)]);
@@ -127,7 +159,7 @@ class Library {
 						f.qx = data.getFloat(p); p += 4;
 						f.qy = data.getFloat(p); p += 4;
 						f.qz = data.getFloat(p); p += 4;
-						var qw = 1 - f.qx * f.qx + f.qy * f.qy + f.qz * f.qz;
+						var qw = 1 - (f.qx * f.qx + f.qy * f.qy + f.qz * f.qz);
 						f.qw = qw < 0 ? -Math.sqrt( -qw) : Math.sqrt(qw);
 					} else {
 						f.qx = 0;

+ 6 - 1
samples/skin/Main.hx

@@ -10,7 +10,7 @@ class Main extends hxd.App {
 		s3d.camera.pos.set( -2, -3, 2);
 		s3d.camera.target.z += 1;
 
-		obj.playAnimation(prim.loadAnimation());
+		obj.playAnimation(prim.loadAnimation(LinearAnim));
 
 		// add lights
 		var dir = new DirLight(new h3d.Vector( -1, 3, -10), s3d);
@@ -27,6 +27,11 @@ class Main extends hxd.App {
 		shadow.power = 50;
 	}
 
+	function loadMaterial( name : String, _ ) {
+		var name = name.split("\\").pop();
+		return new h3d.mat.MeshMaterial(loadTexture(name));
+	}
+
 	function loadTexture( name : String ) {
 		name = name.split("/").pop();
 		return hxd.Res.load(name).toTexture();