public void TestInit() { m_rigRepo = A.Fake <IRigRepository>(); m_equipmentRepo = A.Fake <IEquipmentRepository>(); m_rigTemplateRepo = A.Fake <IRigTemplateRepository>(); m_testSubject = new RigGenerator(m_rigRepo, m_equipmentRepo, m_rigTemplateRepo); }
// TODO (mogens) move this to RigConversion in animation package ? public static BlobAssetReference <RigDefinition> ConvertRig(RigComponent rigComponent) { var skeletonNodes = RigGenerator.ExtractSkeletonNodesFromRigComponent(rigComponent); var channels = RigGenerator.ExtractAnimationChannelFromRigComponent(rigComponent); var rigDefinition = RigBuilder.CreateRigDefinition(skeletonNodes, null, channels); return(rigDefinition); }
public override void PreProcessData <T>(T data) { if (data is RigComponent) { var rig = data as RigComponent; for (var boneIter = 0; boneIter < rig.Bones.Length; boneIter++) { if (MotionName == rig.Bones[boneIter].name) { m_MotionId = RigGenerator.ComputeRelativePath(rig.Bones[boneIter], rig.transform); } } } }
/// <summary> /// From the transform's name, find the path in the rig that will later be converted to /// a hash, and then the hash will be used to find an index in the AnimationStream. /// </summary> public ChannelWeightQuery CreateFeatherBlendQuery(RigComponent rig, List <FeatherBlend> blendMap) { string status = ""; List <ChannelWeightMap> channels = new List <ChannelWeightMap>(); for (var mapIter = 0; mapIter < blendMap.Count; mapIter++) { bool success = false; for (var srcBoneIter = 0; srcBoneIter < rig.Bones.Length; srcBoneIter++) { if (blendMap[mapIter].Id == rig.Bones[srcBoneIter].name) { var srcPath = RigGenerator.ComputeRelativePath(rig.Bones[srcBoneIter], rig.transform); channels.Add(new ChannelWeightMap() { Id = srcPath, Weight = blendMap[mapIter].Weight }); } success = true; } if (!success) { status = status + mapIter + " "; } } ChannelWeightQuery featherBlendQuery = new ChannelWeightQuery(); featherBlendQuery.Channels = new ChannelWeightMap[channels.Count]; for (var iter = 0; iter < channels.Count; iter++) { featherBlendQuery.Channels[iter] = channels[iter]; } if (!string.IsNullOrEmpty(status)) { UnityEngine.Debug.LogError("Faulty Entries : " + status); } return(featherBlendQuery); }
public static void BuildRigDefinitionBlobAsset(string path) { var gameObject = AssetDatabase.LoadMainAssetAtPath(path) as GameObject; if (gameObject == null) { throw new NullReferenceException($"Asset '{path}' not found"); } var blobPath = GetBlobAssetPath(path); var skeletonNode = RigGenerator.ExtractSkeletonNodesFromGameObject(gameObject); var rigDefinition = RigBuilder.CreateRigDefinition(skeletonNode); BlobFile.WriteBlobAsset(ref rigDefinition, blobPath); }
public void GenerateJackupRig_RigAndEquipment_Created_Correctly() { // arrange IFileSystem fIleSystem = new FileSystem(); ISerializer serializer = new EmmockJsonSerializer(); IRigRepository rigRepo = new FileRigStore(fIleSystem, serializer); IEquipmentRepository equipmentRepo = new FileEquipmentStore(fIleSystem, serializer); IRigTemplateRepository rigTemplateRepo = new FileRigTemplateStore(fIleSystem, serializer); RigTemplate rigTemplate = rigTemplateRepo.GetRigTemplate("Jackup"); // act RigGenerator rigGenerator = new RigGenerator(rigRepo, equipmentRepo, rigTemplateRepo); Rig generatedRig = rigGenerator.GenerateRig("Jackup", "Rig For Test", ""); Rig actualRig = rigRepo.GetAll().FirstOrDefault(r => r.Id == generatedRig.Id); // assert Assert.IsNotNull(actualRig); Assert.AreEqual(generatedRig.Name, actualRig.Name); // TODO: Much deeper check around equipment created from generator }
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 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); }
void ConvertSkinnedMeshRenderes(RigBasedAssetAuthoring assetAuthoring, Entity assetEntity, RigComponent rigComponent) { var skinnedMeshRenderers = assetAuthoring.GetComponentsInChildren <SkinnedMeshRenderer>(); if (skinnedMeshRenderers.Length > 0) { DstEntityManager.AddBuffer <RigBasedAsset.SkinnedMeshRenderer>(assetEntity); } foreach (var meshRenderer in skinnedMeshRenderers) { var skinEntity = GetPrimaryEntity(meshRenderer.gameObject); //var skinEntity = conversionSystem.CreateAdditionalEntity(meshRenderer); #if UNITY_EDITOR DstEntityManager.SetName(skinEntity, "Entity " + skinEntity.Index + " Skin_" + meshRenderer.gameObject.name); #endif var skinRendererBuffer = DstEntityManager.GetBuffer <RigBasedAsset.SkinnedMeshRenderer>(assetEntity); skinRendererBuffer.Add(new RigBasedAsset.SkinnedMeshRenderer { Value = skinEntity, }); //var rigEntity = GetPrimaryEntity(src.Rig); //DstEntityManager.AddComponentData(entity, new SkinnedMeshComponentData { RigEntity = rigEntity }); DstEntityManager.AddComponentData(skinEntity, new SkinnedMeshRigEntity { Value = assetEntity }); DstEntityManager.AddComponentData(skinEntity, new LocalToWorld()); DstEntityManager.AddComponentData(skinEntity, new BoneIndexOffset()); DstEntityManager.AddBuffer <SkinnedMeshToRigIndex>(skinEntity); DstEntityManager.AddBuffer <BindPose>(skinEntity); DstEntityManager.AddBuffer <SkinMatrix>(skinEntity); var skeletonIndexArray = DstEntityManager.GetBuffer <SkinnedMeshToRigIndex>(skinEntity); var bindPoseArray = DstEntityManager.GetBuffer <BindPose>(skinEntity); var skinMatrices = DstEntityManager.GetBuffer <SkinMatrix>(skinEntity); var smBones = meshRenderer.bones; skeletonIndexArray.ResizeUninitialized(smBones.Length); bindPoseArray.ResizeUninitialized(smBones.Length); skinMatrices.ResizeUninitialized(smBones.Length); //GameDebug.Log("skin smBones"); //for (int i = 0; i < smBones.Length; i++) //{ // var relativePath = RigGenerator.ComputeRelativePath(smBones[i], transform); // var id = (StringHash)relativePath; // GameDebug.Log(" " + i + ":" + id.Id + " path:" + relativePath); //} for (int j = 0; j != smBones.Length; ++j) { var remap = new SkinnedMeshToRigIndex { Value = -1 }; var smBoneRelativePath = RigGenerator.ComputeRelativePath(smBones[j], assetAuthoring.transform); var smBoneId = (StringHash)smBoneRelativePath; for (int k = 0; k != rigComponent.Bones.Length; ++k) { var relativePath = RigGenerator.ComputeRelativePath(rigComponent.Bones[k], rigComponent.transform); var id = (StringHash)relativePath; if (smBoneId.Equals(id)) { remap.Value = k; break; } } skeletonIndexArray[j] = remap; var bindPose = meshRenderer.sharedMesh.bindposes[j]; bindPoseArray[j] = new BindPose { Value = bindPose }; var skinMat = math.mul(meshRenderer.bones[j].localToWorldMatrix, bindPose); skinMatrices[j] = new SkinMatrix { Value = new float3x4(skinMat.c0.xyz, skinMat.c1.xyz, skinMat.c2.xyz, skinMat.c3.xyz) }; } } }
public void Convert(Entity entity, EntityManager dstManager, GameObjectConversionSystem conversionSystem) { if (Clips == null || BlendThresholds == null) { return; } if (!dstManager.HasComponent <Rig>(entity)) { throw new System.InvalidOperationException("RigComponent must be converted before this component."); } if (Clips.Length != BlendThresholds.Length) { throw new System.InvalidOperationException("You must have the same number of clips and blendthresholds."); } var rigComponent = GetComponent <RigComponent>() as RigComponent; StringHash motionId = ""; for (var boneIter = 0; boneIter < rigComponent.Bones.Length; boneIter++) { if (MotionJointName == rigComponent.Bones[boneIter].name) { motionId = RigGenerator.ComputeRelativePath(rigComponent.Bones[boneIter], rigComponent.transform); } } var rigDefinition = dstManager.GetComponentData <Rig>(entity); var clipConfiguration = new ClipConfiguration(); clipConfiguration.Mask = ClipConfigurationMask.LoopTime | ClipConfigurationMask.LoopValues | ClipConfigurationMask.CycleRootMotion | ClipConfigurationMask.DeltaRootMotion; clipConfiguration.MotionID = motionId; var denseClips = new NativeArray <SampleClip>(Clips.Length, Allocator.Temp); var durations = new NativeArray <SampleClipDuration>(Clips.Length, Allocator.Temp); var thresholds = new NativeArray <SampleClipBlendThreshold>(Clips.Length, Allocator.Temp); for (int i = 0; i < Clips.Length; i++) { conversionSystem.DeclareAssetDependency(gameObject, Clips[i]); denseClips[i] = new SampleClip { Clip = UberClipNode.Bake(rigDefinition.Value, Clips[i].ToDenseClip(), clipConfiguration, 60.0f) }; durations[i] = new SampleClipDuration { Value = denseClips[i].Clip.Value.Duration }; thresholds[i] = new SampleClipBlendThreshold { Value = BlendThresholds[i] }; } var synchronizeMotions = dstManager.AddBuffer <SampleClip>(entity); synchronizeMotions.CopyFrom(denseClips); var synchronizeMotionDurations = dstManager.AddBuffer <SampleClipDuration>(entity); synchronizeMotionDurations.CopyFrom(durations); var synchronizeMotionThresholds = dstManager.AddBuffer <SampleClipBlendThreshold>(entity); synchronizeMotionThresholds.CopyFrom(thresholds); dstManager.AddComponentData(entity, new WeightComponent { Value = 0.0f }); denseClips.Dispose(); durations.Dispose(); thresholds.Dispose(); }
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); }