private RigRemapQuery CreateRemapQuery(RigComponent srcRig, RigComponent dstRig, List <string> retargetMap) { var status = ""; var translationChannels = new List <ChannelMap>(); var rotationChannels = new List <ChannelMap>(); var translationOffsets = new List <RigTranslationOffset>(); var rotationOffsets = new List <RigRotationOffset>(); //Inverse Quaternion = (x * -1, y * -1, z * -1, w) var srcRootRotInv = math.inverse(srcRig.transform.rotation); var dstRootRotInv = math.inverse(dstRig.transform.rotation); //We are iterating through the retargetMap collection.. for (var mapIter = 0; mapIter < retargetMap.Count; mapIter++) { var successFlag = false; //Splitting the element in each array when there a space. Three element //ex. "First Second Third" = ["First", "Second", "Third"] var splitMap = retargetMap[mapIter].Split(new[] { ' ' }, 3); //We are iterating through the for loop on the number of bones the srcPrefab. for (var srcBoneIter = 0; srcBoneIter < srcRig.Bones.Length; srcBoneIter++) { //We are checking if the splitMap element has atleast one element and if the first element matches any bone name of the srcRig prefab bone if (splitMap.Length > 0 && splitMap[0] == srcRig.Bones[srcBoneIter].name) { //We are iterating through the for loop on the number of bones we have on the gameObject attached to this script. for (var dstBoneIter = 0; dstBoneIter < dstRig.Bones.Length; dstBoneIter++) { //We are checking if the splitMap element has atleast two element and if the second element matches any bone name of this gameObject if (splitMap.Length > 1 && splitMap[1] == dstRig.Bones[dstBoneIter].name) { //We are checking if the splitMap has atleast three element if (splitMap.Length > 2) { //We are getting all the parent gameObject name of the current srcRig bone at srcBoneIter up until and excluding the srcRig.transform //Ex. // if srcRig.Bones[srcBoneIter] = Chest // then the srcPath = Skeleton/Root/Spine/Chest (it traverse the hierarchy and get the parent up until the srcRig.transform) var srcPath = RigGenerator.ComputeRelativePath(srcRig.Bones[srcBoneIter], srcRig.transform); var dstPath = RigGenerator.ComputeRelativePath(dstRig.Bones[dstBoneIter], dstRig.transform); if (splitMap[2] == "TR" || splitMap[2] == "T") { var translationOffset = new RigTranslationOffset(); //self bone position.y / target bone position.y to get the average height of the bone (assumed to be y/ standing up right) translationOffset.Scale = dstRig.Bones[dstBoneIter].position.y / srcRig.Bones[srcBoneIter].position.y; var dstParentRot = math.mul(dstRootRotInv, dstRig.Bones[dstBoneIter].parent.rotation); var srcParentRot = math.mul(srcRootRotInv, srcRig.Bones[srcBoneIter].parent.rotation); translationOffset.Rotation = mathex.mul(math.inverse(dstParentRot), srcParentRot); translationOffsets.Add(translationOffset); translationChannels.Add(new ChannelMap { SourceId = srcPath, DestinationId = dstPath, OffsetIndex = translationOffsets.Count }); } if (splitMap[2] == "TR" || splitMap[2] == "R") { var rotationOffset = new RigRotationOffset(); var dstParentRot = math.mul(dstRootRotInv, dstRig.Bones[dstBoneIter].parent.transform.rotation); var srcParentRot = math.mul(srcRootRotInv, srcRig.Bones[srcBoneIter].parent.transform.rotation); var dstRot = math.mul(dstRootRotInv, dstRig.Bones[dstBoneIter].transform.rotation); var srcRot = math.mul(srcRootRotInv, srcRig.Bones[srcBoneIter].transform.rotation); rotationOffset.PreRotation = mathex.mul(math.inverse(dstParentRot), srcParentRot); rotationOffset.PostRotation = mathex.mul(math.inverse(srcRot), dstRot); rotationOffsets.Add(rotationOffset); rotationChannels.Add(new ChannelMap { SourceId = srcPath, DestinationId = dstPath, OffsetIndex = rotationOffsets.Count }); } successFlag = true; } } } } } if (!successFlag) { status = status + mapIter + " "; } } var rigRemapQuery = new RigRemapQuery(); rigRemapQuery.TranslationChannels = new ChannelMap[translationChannels.Count]; for (var iter = 0; iter < translationChannels.Count; iter++) { rigRemapQuery.TranslationChannels[iter] = translationChannels[iter]; } rigRemapQuery.TranslationOffsets = new RigTranslationOffset[translationOffsets.Count + 1]; rigRemapQuery.TranslationOffsets[0] = new RigTranslationOffset(); for (var iter = 0; iter < translationOffsets.Count; iter++) { rigRemapQuery.TranslationOffsets[iter + 1] = translationOffsets[iter]; } rigRemapQuery.RotationChannels = new ChannelMap[rotationChannels.Count]; for (var iter = 0; iter < rotationChannels.Count; iter++) { rigRemapQuery.RotationChannels[iter] = rotationChannels[iter]; } rigRemapQuery.RotationOffsets = new RigRotationOffset[rotationOffsets.Count + 1]; rigRemapQuery.RotationOffsets[0] = new RigRotationOffset(); for (var iter = 0; iter < rotationOffsets.Count; iter++) { rigRemapQuery.RotationOffsets[iter + 1] = rotationOffsets[iter]; } if (!string.IsNullOrEmpty(status)) { Debug.LogError("Faulty Entries : " + status); } return(rigRemapQuery); }
public RigRemapQuery CreateRemapQuery(RigComponent srcRig, RigComponent dstRig, List<string> retargetMap) { string status = ""; List<ChannelMap> translationChannels = new List<ChannelMap>(); List<ChannelMap> rotationChannels = new List<ChannelMap>(); List<RigTranslationOffset> translationOffsets = new List<RigTranslationOffset>(); List<RigRotationOffset> rotationOffsets = new List<RigRotationOffset>(); for (var mapIter = 0; mapIter < retargetMap.Count; mapIter++) { bool success = false; string[] splitMap = retargetMap[mapIter].Split(new char[] { ' ' }, 3); for (var srcBoneIter = 0; srcBoneIter < srcRig.Bones.Length; srcBoneIter++) { if (splitMap.Length > 0 && splitMap[0] == srcRig.Bones[srcBoneIter].name) { for (var dstBoneIter = 0; dstBoneIter < dstRig.Bones.Length; dstBoneIter++) { if (splitMap.Length > 1 && splitMap[1] == dstRig.Bones[dstBoneIter].name) { if (splitMap.Length > 2) { var srcPath = RigGenerator.ComputeRelativePath(srcRig.Bones[srcBoneIter], srcRig.transform); var dstPath = RigGenerator.ComputeRelativePath(dstRig.Bones[dstBoneIter], dstRig.transform); if (splitMap[2] == "TR" || splitMap[2] == "T") { var translationOffset = new RigTranslationOffset(); // heuristic that computes retarget scale based on translation node (ex: hips) height (assumed to be y) translationOffset.Scale = dstRig.Bones[dstBoneIter].position.y / srcRig.Bones[srcBoneIter].position.y; translationOffset.Rotation = mathex.mul(math.conjugate(dstRig.Bones[dstBoneIter].parent.rotation), srcRig.Bones[srcBoneIter].parent.rotation); translationOffsets.Add(translationOffset); translationChannels.Add(new ChannelMap() { SourceId = srcPath, DestinationId = dstPath, OffsetIndex = translationOffsets.Count }); } if (splitMap[2] == "TR" || splitMap[2] == "R") { var rotationOffset = new RigRotationOffset(); rotationOffset.PreRotation = mathex.mul(math.conjugate(dstRig.Bones[dstBoneIter].parent.rotation), srcRig.Bones[srcBoneIter].parent.rotation); rotationOffset.PostRotation = mathex.mul(math.conjugate(srcRig.Bones[srcBoneIter].rotation), dstRig.Bones[dstBoneIter].rotation); rotationOffsets.Add(rotationOffset); rotationChannels.Add(new ChannelMap() { SourceId = srcPath, DestinationId = dstPath, OffsetIndex = rotationOffsets.Count }); } success = true; } } } } } if (!success) { status = status + mapIter + " "; } } RigRemapQuery rigRemapQuery = new RigRemapQuery(); rigRemapQuery.TranslationChannels = new ChannelMap[translationChannels.Count]; for (var iter = 0; iter < translationChannels.Count; iter++) { rigRemapQuery.TranslationChannels[iter] = translationChannels[iter]; } rigRemapQuery.TranslationOffsets = new RigTranslationOffset[translationOffsets.Count + 1]; rigRemapQuery.TranslationOffsets[0] = new RigTranslationOffset(); for (var iter = 0; iter < translationOffsets.Count; iter++) { rigRemapQuery.TranslationOffsets[iter + 1] = translationOffsets[iter]; } rigRemapQuery.RotationChannels = new ChannelMap[rotationChannels.Count]; for (var iter = 0; iter < rotationChannels.Count; iter++) { rigRemapQuery.RotationChannels[iter] = rotationChannels[iter]; } rigRemapQuery.RotationOffsets = new RigRotationOffset[rotationOffsets.Count + 1]; rigRemapQuery.RotationOffsets[0] = new RigRotationOffset(); for (var iter = 0; iter < rotationOffsets.Count; iter++) { rigRemapQuery.RotationOffsets[iter + 1] = rotationOffsets[iter]; } if (!string.IsNullOrEmpty(status)) { UnityEngine.Debug.LogError("Faulty Entries : " + status); } return rigRemapQuery; }
private RigRemapQuery CreateAutoRemapQuery([NotNull] RigComponent srcRig, [NotNull] RigComponent dstRig) { var translationChannels = new List <ChannelMap>(); var rotationChannels = new List <ChannelMap>(); var translationOffsets = new List <RigTranslationOffset>(); var rotationOffsets = new List <RigRotationOffset>(); var srcRootRotInv = math.inverse(srcRig.transform.rotation); var dstRootRotInv = math.inverse(dstRig.transform.rotation); for (var boneIter = 0; boneIter < srcRig.Bones.Length; boneIter++) { if (srcRig.Bones[boneIter].parent != null) { if (srcRig.Bones[boneIter].name == dstRig.Bones[boneIter].name) { var srcPath = RigGenerator.ComputeRelativePath(srcRig.Bones[boneIter], srcRig.transform); var dstPath = RigGenerator.ComputeRelativePath(dstRig.Bones[boneIter], dstRig.transform); var dstParentRot = math.mul(dstRootRotInv, dstRig.Bones[boneIter].parent.transform.rotation); var srcParentRot = math.mul(srcRootRotInv, srcRig.Bones[boneIter].parent.transform.rotation); var rotation = mathex.mul(math.inverse(dstParentRot), srcParentRot); //Got to calculate the translation. //Only applying translationOffset to the first bone (most cases the hips) if (boneIter == 1) { var translationOffset = new RigTranslationOffset { Scale = dstRig.Bones[boneIter].position.y / srcRig.Bones[boneIter].position.y, Rotation = rotation }; translationOffsets.Add(translationOffset); translationChannels.Add(new ChannelMap { DestinationId = dstPath, SourceId = srcPath, OffsetIndex = translationOffsets.Count }); } //Got to calculate the rotation. var dstRot = math.mul(dstRootRotInv, dstRig.Bones[boneIter].transform.rotation); var srcRot = math.mul(srcRootRotInv, srcRig.Bones[boneIter].transform.rotation); var rotationOffset = new RigRotationOffset { PreRotation = rotation, PostRotation = mathex.mul(math.inverse(srcRot), dstRot) }; rotationOffsets.Add(rotationOffset); rotationChannels.Add(new ChannelMap { SourceId = srcPath, DestinationId = dstPath, OffsetIndex = rotationOffsets.Count }); } } } var rigRemapQuery = new RigRemapQuery { TranslationChannels = new ChannelMap[translationChannels.Count], RotationChannels = new ChannelMap[rotationChannels.Count], TranslationOffsets = new RigTranslationOffset[translationChannels.Count + 1], RotationOffsets = new RigRotationOffset[rotationChannels.Count + 1] }; rigRemapQuery.TranslationOffsets[0] = new RigTranslationOffset(); rigRemapQuery.RotationOffsets[0] = new RigRotationOffset(); for (var iter = 0; iter < translationChannels.Count; iter++) { rigRemapQuery.TranslationChannels[iter] = translationChannels[iter]; rigRemapQuery.TranslationOffsets[iter + 1] = translationOffsets[iter]; } for (var iter = 0; iter < rotationChannels.Count; iter++) { rigRemapQuery.RotationChannels[iter] = rotationChannels[iter]; rigRemapQuery.RotationOffsets[iter + 1] = rotationOffsets[iter]; } return(rigRemapQuery); }