public JobYield(JobSpecification job, Vector4 planeInWorldSpace, Vector3 focalPointInWorldSpace, IEnumerable <MeshSnapshot> alfa, IEnumerable <MeshSnapshot> bravo) { Job = job; PlaneInWorldSpace = planeInWorldSpace; FocalPointInWorldSpace = focalPointInWorldSpace; Alfa = alfa; Bravo = bravo; }
public void SeverByJoint(GameObject subject, string jointName, float rootTipProgression, Vector3?planeNormal) { //Sanity check: are we already slicing this? foreach (var extantState in jobStates) { if (ReferenceEquals(extantState.Specification.Subject, subject)) { //Debug.LogErrorFormat("Turbo Slicer was asked to slice '{0}' but this target is already enqueued.", subject.name); return; } } rootTipProgression = Mathf.Clamp01(rootTipProgression); //These here are in local space because they're only used to copy to the resultant meshes; they're not used //to transform the vertices. We expect a world-space slice input. Hackable hackable = null; { var hackables = subject.GetComponentsInChildren <Hackable>(); if (hackables.Length > 0) { if (hackables.Length > 1) { Debug.LogWarning("Limb Hacker found multiple slice configurations on object '" + subject.name + "'! Behavior is undefined."); } hackable = hackables[0]; } else { Debug.LogWarning("Limb Hacker found no slice configuration on object '" + subject.name + "'."); return; } } //We need information about which BONES are getting severed. var metadataByNodeName = new Dictionary <string, NodeMetadata>(); { var childTransformByName = new Dictionary <string, Transform>(); var parentKeyByKey = new Dictionary <string, string>(); foreach (Transform t in GetConcatenatedHierarchy(subject.transform)) { childTransformByName[t.name] = t; var parent = t.parent; if (t == subject.transform) { parent = null; } parentKeyByKey[t.name] = parent == null ? null : parent.name; } var severedByChildName = new Dictionary <string, bool>(); { foreach (string childName in childTransformByName.Keys) { severedByChildName[childName] = childName == jointName; } bool changesMade; do { changesMade = false; foreach (string childKey in childTransformByName.Keys) { bool severed = severedByChildName[childKey]; if (severed) { continue; } string parentKey = parentKeyByKey[childKey]; bool parentSevered; if (severedByChildName.TryGetValue(parentKey, out parentSevered) == false) { continue; } if (parentSevered) { severedByChildName[childKey] = true; changesMade = true; } } }while (changesMade); } foreach (var kvp in severedByChildName) { var t = childTransformByName[kvp.Key]; var isConsideredSevered = kvp.Value; metadataByNodeName[kvp.Key] = new NodeMetadata(t, isConsideredSevered); } } IEnumerable <MeshSnapshot> snapshots; var forwardPassAgent = subject.GetComponent <ForwardPassAgent>(); if (forwardPassAgent == null) { var snapshotBuilder = new List <MeshSnapshot>(); var skinnedMeshRenderers = subject.GetComponentsInChildren <SkinnedMeshRenderer>(true); foreach (var smr in skinnedMeshRenderers) { var mesh = smr.sharedMesh; var boneMetadata = new BoneMetadata[smr.bones.Length]; var bones = smr.bones; var bindPoses = mesh.bindposes; for (int i = 0; i < boneMetadata.Length; i++) { boneMetadata[i] = new BoneMetadata(i, bones[i].name, bindPoses[i]); } int?infillIndex = null; if (hackable.infillMaterial != null) { var mats = smr.sharedMaterials; for (int i = 0; i < mats.Length; i++) { if (hackable.infillMaterial == mats[i]) { infillIndex = i; break; } } } MeshSnapshot snapshot; MeshSnapshot preloadedFragment; if (preloadedMeshes.TryGetValue(mesh.GetInstanceID(), out preloadedFragment)) { //The preloaded fragments are missing data which is particular to the SMR. We'll combine it with such data here. snapshot = preloadedFragment.WithKey(smr.name).WithMaterials(smr.sharedMaterials).WithBoneMetadata(boneMetadata).WithInfillIndex(infillIndex); } else { var indices = new int[mesh.subMeshCount][]; for (int i = 0; i < mesh.subMeshCount; i++) { indices[i] = mesh.GetIndices(i); } snapshot = new MeshSnapshot( smr.name, mesh.vertices, mesh.normals, mesh.uv, mesh.tangents, mesh.boneWeights, smr.sharedMaterials, boneMetadata, infillIndex, indices); } snapshotBuilder.Add(snapshot); } snapshots = snapshotBuilder; } else { snapshots = forwardPassAgent.Snapshot; } var jobSpec = new JobSpecification(subject, hackable, snapshots, metadataByNodeName, hackable.infillMaterial, jointName, rootTipProgression, planeNormal, hackable.infillMode, true); var jobState = new JobState(jobSpec); try { switch (workerThreadMode) { case WorkerThreadMode.Asynchronous: jobStates.Add(jobState); #if NETFX_CORE && !UNITY_EDITOR System.Threading.Tasks.Task.Factory.StartNew(ThreadSafeHack.Slice, jobState); #else System.Threading.ThreadPool.QueueUserWorkItem(ThreadSafeHack.Slice, jobState); #endif break; case WorkerThreadMode.Synchronous: ThreadSafeHack.Slice(jobState); if (jobState.HasYield) { ConsumeJobYield(jobState); } else if (jobState.HasException) { throw jobState.Exception; } break; default: throw new System.NotImplementedException(); } } catch (System.Exception ex) { Debug.LogException(ex, subject); } }
public JobYield(JobSpecification job, IEnumerable <MeshSnapshot> alfa, IEnumerable <MeshSnapshot> bravo) { Job = job; Alfa = alfa; Bravo = bravo; }
public JobState(JobSpecification specification) { Specification = specification; }