Esempio n. 1
0
 public JobYield(JobSpecification job, Vector4 planeInWorldSpace, Vector3 focalPointInWorldSpace, IEnumerable <MeshSnapshot> alfa, IEnumerable <MeshSnapshot> bravo)
 {
     Job = job;
     PlaneInWorldSpace      = planeInWorldSpace;
     FocalPointInWorldSpace = focalPointInWorldSpace;
     Alfa  = alfa;
     Bravo = bravo;
 }
Esempio n. 2
0
        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);
            }
        }
Esempio n. 3
0
 public JobYield(JobSpecification job, IEnumerable <MeshSnapshot> alfa, IEnumerable <MeshSnapshot> bravo)
 {
     Job   = job;
     Alfa  = alfa;
     Bravo = bravo;
 }
Esempio n. 4
0
 public JobState(JobSpecification specification)
 {
     Specification = specification;
 }