コード例 #1
0
    public void Init()
    {
        OnSelect += () =>
        {
            //Debug.Log(name + " OnSelect , selectablePaths.Count = " + selectablePaths.Count);
            //MWB_SelectionQuery.Instance.CleanRegisteredPaths();
            //MWB_SelectionQuery.Instance.RegisterPaths(selectablePaths);

            List <MWB_SelectablePath> previousSelectedPaths = MWB_SelectionQuery.Instance.SelectedPaths;
            // valid world
            List <MWB_DummyObjectList> previousSelectedWorlds = new List <MWB_DummyObjectList>();

            foreach (MWB_SelectablePath previousSelectedPath in previousSelectedPaths)
            {
                MWB_Path            t_previousSelectedPath = previousSelectedPath as MWB_Path;
                MWB_DummyObjectList t_world = t_previousSelectedPath.SourceDummyObject.correspondingDummyList;

                previousSelectedWorlds.Add(t_world);
            }

            List <MWB_SelectablePath> newSelectedPaths = new List <MWB_SelectablePath>();
            foreach (MWB_SelectablePath selectablePath in selectablePaths)
            {
                MWB_Path t_selectablePath = selectablePath as MWB_Path;

                if (t_selectablePath.SourceDummyObject != null && previousSelectedWorlds.Contains(t_selectablePath.SourceDummyObject.correspondingDummyList))
                {
                    newSelectedPaths.Add(selectablePath);
                }
            }

            MWB_SelectionQuery.Instance.ChangeSelectablePathList(selectablePaths);

            // pre select some of the paths base on previously selected worlds
            MWB_SelectionQuery.Instance.SelectPaths(newSelectedPaths);
        };
        OnDeselect += () =>
        {
            //Debug.Log(name + " OnDeselect ");
            //MWB_SelectionQuery.Instance.CleanRegisteredPaths();
        };
        //
        MWB_PathFactory Factory = MWB_PathFactory.Instance;

        if (CurrentMainPath == null)
        {
            RootPath = CurrentMainPath = Factory.GetPath();
        }
        else
        {
            var newPath = Factory.GetSubPath(CurrentMainPath);
            CurrentMainPath = newPath;
        }
        //selectablePaths.Add(RootPath);
    }
コード例 #2
0
    private MWB_DummyObjectList GenerateDummyObjects(MWB_ObjectList objectList, bool isInitializedAsAble)
    {
        MWB_DummyObjectList dummyObjectList = new MWB_DummyObjectList();

        GameObject parent = new GameObject("initial dummy parent");

        parent.transform.parent = dummyMasterParent.transform;
        // !!! IMPORTANT
        parent.transform.localPosition = transform.localPosition;
        parent.transform.localRotation = transform.localRotation;
        parent.transform.localScale    = transform.localScale;
        // add parent to dummyParent list for clean up !
        dummyParentList.Add(parent);
        //
        foreach (MWB_Object mwbObject in objectList.MWB_Objects)
        {
            GameObject forkedObject = Instantiate(mwbObject.gameObject, parent.transform);
            // Set layer
            forkedObject.layer = MWBWaitingLayer;
            forkedObject.SetActive(isInitializedAsAble);
            // turning MWB_Object to Dummy Object
            Destroy(forkedObject.GetComponent <MWB_Object>());

            var dummy = forkedObject.AddComponent <MWB_DummyObject>();
            dummy.Manager = this;
            // record object source
            dummy.objectSource = mwbObject;
            // record fork source ( initial object has null )
            dummy.forkedSource = null;
            //record corresponding dummy list
            dummy.correspondingDummyList = dummyObjectList;

            // set pathIndex
            //dummy.pathIndex = 0;

            // record previous transform data segment (initial dummy object has null)
            dummy.transformDataSegment.previousSegment = null;

            // use main path to generate sub path
            dummy.SetSubPath(mwbObject.CurrentMainPath);

            // assign reference of dummy to path
            dummy.dummyMainPath.SourceDummyObject = dummy;
            //
            dummyObjectList.AddToDummyObjectList(dummy);
        }

        return(dummyObjectList);
    }
コード例 #3
0
    private void CleanUp()
    {
        m_collidingDummyObjects.Clear();
        focusingDummyObjectList = null;
        forkedFrameNumber.Clear();

        // destroy all dummys used for simulation by destroying their parent
        //foreach (GameObject dummyParent in dummyParentList)
        //{
        //    Destroy(dummyParent);
        //}
        Destroy(dummyMasterParent);
        dummyParentList.Clear();

        MWB_SelectionQuery.Instance.CleanRegisteredPaths();

        // clear all registered object's selectablePaths to empty
        foreach (MWB_Object mwb_Object in m_objectList.MWB_Objects)
        {
            mwb_Object.selectablePaths.Clear();
            mwb_Object.InitializeRootPath();
        }
    }
コード例 #4
0
    private MWB_DummyObjectList ForkDummyObjects(MWB_DummyObjectList dummyObjectList, bool isInitializedAsAble, int worldIndex = 0)
    {
        //Debug.Log("Forking");
        GameObject parent = new GameObject("collide-forked dummy parent"); // this will also instantiate

        // !!! IMPORTANT : set the transform data of dummys' parent to the same as original objects'
        parent.transform.parent = dummyMasterParent.transform;
        // parent, which is the MWB_SYSTEM
        parent.transform.localPosition = transform.localPosition;
        parent.transform.localRotation = transform.localRotation;
        parent.transform.localScale    = transform.localScale;
        // add parent to dummyParent list for clean up !
        dummyParentList.Add(parent);

        MWB_DummyObjectList forkedDummyObjectList = new MWB_DummyObjectList();

        foreach (MWB_DummyObject mwbDummyObject in dummyObjectList.MWB_DummyObjects)
        {
            GameObject forkedObject = Instantiate(mwbDummyObject.gameObject, parent.transform);

            // Set layer
            forkedObject.layer = MWBWaitingLayer;
            forkedObject.SetActive(isInitializedAsAble);
            // initilize as kinematic
            forkedObject.GetComponent <Rigidbody>().isKinematic       = true;
            forkedObject.gameObject.GetComponent <Renderer>().enabled = false;
            //
            Destroy(forkedObject.GetComponent <MWB_Object>());

            MWB_DummyObject forkedDummy = forkedObject.GetComponent <MWB_DummyObject>();

            forkedDummy.Manager = this;
            // record object source
            forkedDummy.objectSource = mwbDummyObject.objectSource;
            // record fork source ( initial object has null )
            forkedDummy.forkedSource = mwbDummyObject;
            // record corresponding dummy list
            forkedDummy.correspondingDummyList = forkedDummyObjectList;

            // record previous transform data segment (initial dummy object has null)
            TransformDataSegment parentSegment = mwbDummyObject.transformDataSegment;
            forkedDummy.transformDataSegment.previousSegment = parentSegment;
            mwbDummyObject.transformDataSegment = new TransformDataSegment(parentSegment);

            // use main path to generate two sub
            MWB_Path parentPath = mwbDummyObject.dummyMainPath;

            //mwbDummyObject.RecordPosition(); // !!! Record position to avoid broken line segment

            mwbDummyObject.SetSubPath(parentPath);

            //mwbDummyObject.RecordPosition(); // !!! Record position to avoid broken line segment

            forkedDummy.SetSubPath(parentPath);

            // assign reference of dummy to path
            mwbDummyObject.dummyMainPath.SourceDummyObject = mwbDummyObject;
            forkedDummy.dummyMainPath.SourceDummyObject    = forkedDummy;
            //

            // set pathIndex
            //forkedDummy.pathIndex = mwbDummyObject.pathIndex;

            //
            Vector3 additionalImpulse;
            if (m_collidingDummyObjects.ContainsKey(mwbDummyObject))
            {
                // TODO : add a logical additional pulse, rather than just random a force

                Collision collision = m_collidingDummyObjects[mwbDummyObject];

                //additionalImpulse = Vector3.Cross(collision.impulse, Vector3.up) * collision.impulse.magnitude * 5f;
                //additionalImpulse = new Vector3(UnityEngine.Random.Range(-100, 100), 0, UnityEngine.Random.Range(-100, 100));

                Vector3 origin  = Vector3.zero;
                int     counter = 0;
                foreach (var contactPoint in collision.contacts)
                {
                    origin += contactPoint.point;
                    counter++;
                }
                origin /= counter;

                List <Vector3> perturbation = SinDistributionUtility.CalculatePerturbation(origin, collision.impulse);

                if (perturbation.Count > worldIndex)
                {
                    additionalImpulse = perturbation[worldIndex];
                }
                else
                {
                    additionalImpulse = perturbation[perturbation.Count - 1];
                }
            }
            else
            {
                additionalImpulse = Vector3.zero;
            }
            //

            // maintain rigidbody info , otherwise it'll only copy variables info but not state info
            RigidbodyState rigidbodyState = new RigidbodyState(mwbDummyObject.GetComponent <Rigidbody>(), additionalImpulse);
            forkedDummy.rigidbodyState = rigidbodyState;
            forkedDummyObjectList.AddToDummyObjectList(forkedDummy);
            //
        }

        return(forkedDummyObjectList);
    }
コード例 #5
0
    // !!! IMPORTANT : If a collision already happens and you disactive object then active , OnCollisionEnter will trigger again
    public IEnumerator Run()
    {
        OnSystemBegin.Invoke();

        dummyMasterParent = new GameObject("_TempDummyMasterParent");

        // might need a lifetime for forked MWB_System
        forkedDummyObjectLists = new List <MWB_DummyObjectList>
        {
            GenerateDummyObjects(m_objectList, true)
        };
        // set original object to disactive, and set to wait layer to avoid unnecessary collision
        foreach (MWB_Object mwbObject in m_objectList.MWB_Objects)
        {
            mwbObject.gameObject.SetActive(false);
            mwbObject.gameObject.layer = MWBWaitingLayer;
        }
        // for each forked dummyObjectList, check if the system needs to be forked
        for (int i = 0; i < forkedDummyObjectLists.Count; i++)
        {
            if (isForceStop)
            {
                break;
            }

            MWB_DummyObjectList dummyObjectList = forkedDummyObjectLists[i];
            // Set focusing dummyObjectList
            focusingDummyObjectList = dummyObjectList;

            foreach (MWB_DummyObject dummyObject in dummyObjectList.MWB_DummyObjects)
            {
                dummyObject.gameObject.layer = MWBRunningLayer;
                // try to turn on dummys
                dummyObject.rigidbody.isKinematic = false;
                // regain maintained rigidbody state ( obtained when forked )
                Rigidbody dummyRigidbody = dummyObject.GetComponent <Rigidbody>();
                dummyObject.rigidbodyState.SetRigidbodyState(ref dummyRigidbody);
                // turn visible
                dummyObject.gameObject.GetComponent <Renderer>().enabled = true;
            }

            // simulation
            for (int currentFrame = 0; currentFrame < SimulateFrameCount; currentFrame++)
            {
                if (forkedFrameNumber.ContainsKey(dummyObjectList))
                {
                    currentFrame = forkedFrameNumber[dummyObjectList];
                    // !!! IMPORTANT !!!
                    forkedFrameNumber.Remove(dummyObjectList);
                    //
                    continue;
                }
                // Record position to path ( when simulating )
                foreach (MWB_DummyObject dummy in dummyObjectList.MWB_DummyObjects)
                {
                    dummy.RecordPosition();
                }

                // simulate
                Physics.Simulate(TimeStepPerFrame);
                // for each collided object , fork dummy objects (X)
                // if this system has a dummy collision, fork once.

                LoopCounter++;
                if (LoopCounter > MaxLoopPerFrame)
                {
                    LoopCounter = 0;
                    yield return(null);
                }

                if (m_collidingDummyObjects.Count > 0)
                {
                    for (int k = 0; k < WorldForkedOnCollision; k++)
                    {
                        // fork every object in currentObjectList by their current status
                        MWB_DummyObjectList forkedMWB_DummyObjectList = ForkDummyObjects(dummyObjectList, true, k);

                        // add track to every objects that we just created
                        forkedDummyObjectLists.Add(forkedMWB_DummyObjectList);
                        // track frame
                        forkedFrameNumber.Add(forkedMWB_DummyObjectList, currentFrame);
                    }
                }

                m_collidingDummyObjects.Clear();
            }

            // Set back to waiting for simulation
            foreach (MWB_DummyObject dummyObject in dummyObjectList.MWB_DummyObjects)
            {
                dummyObject.gameObject.layer = MWBWaitingLayer;
                // try to turn off dummys
                dummyObject.rigidbody.isKinematic = true;
                dummyObject.gameObject.GetComponent <Renderer>().enabled = false;

                // register to selectable

                // ??
                //dummyObject.pathIndex = dummyObject.objectSource.selectablePaths.Count;
                // Debug.Log(dummyObject.pathIndex + " " + dummyObject.correspondingDummyList.worldIndex);

                // Do line set up at the end

                //dummyObject.objectSource.selectablePaths.Add(dummyObject.dummyMainPath);

                //
                //MWB_SelectionQuery.Instance.RegisterPath(dummyObject.dummyMainPath);
                registerPathCount++;
            }

            // update
            Progress += 1.0f / forkedDummyObjectLists.Count;
        }

        foreach (MWB_Object mwbObject in m_objectList.MWB_Objects)
        {
            mwbObject.gameObject.SetActive(true);
            mwbObject.gameObject.layer = MWBRunningLayer;

            // for updated line renderer!!!

            // Do line set up at the end
            //mwbObject.SetupLinedata();
        }

        forkedFrameNumber.Clear();
        m_collidingDummyObjects.Clear();

        // TEST PURPOSE
        // AnimationClip clip = MWBDummyClipUtility.GenerateClipFromDummyList(forkedDummyObjectLists[3]);

        // ClipExportUtility.ExportAnimationClip(clip, @"Assets/test.anim");
        //

        // output information

        Debug.Log("MWB_DummyObject.pathNumber = " + MWB_DummyObject.pathNumber);
        Debug.Log("MWB_DummyObject.dotNumber = " + MWB_DummyObject.dotNumber);
        Debug.Log("registerPathCount = " + registerPathCount);

        //
        if (isForceStop)
        {
            terminate();
            isForceStop = false;
        }
        else
        {
            OnSystemComplete.Invoke();
        }
        yield return(null);
    }
コード例 #6
0
        public static AnimationClip GenerateClipFromDummyList(MWB_DummyObjectList dummyList)
        {
            AnimationClip clip = new AnimationClip();

            foreach (MWB_DummyObject dummy in dummyList.MWB_DummyObjects)
            {
                // stack from dummy itself to its root forked source, and reverse create clips
                Stack <TransformDataSegment> dataSegmentStack   = new Stack <TransformDataSegment>();
                TransformDataSegment         currentDataSegment = dummy.transformDataSegment;

                while (currentDataSegment != null)
                {
                    dataSegmentStack.Push(currentDataSegment);
                    // travese upward in fork tree
                    currentDataSegment = currentDataSegment.previousSegment;
                }

                // for each recorded Transform data, the time interval is Time.fixedDeltaTime
                float currentRelativeTime = 0f;
                // create curves base on the dummys in the stack

                AnimationCurve localPositionXCurve = new AnimationCurve();
                AnimationCurve localPositionYCurve = new AnimationCurve();
                AnimationCurve localPositionZCurve = new AnimationCurve();

                AnimationCurve localRotationXCurve = new AnimationCurve();
                AnimationCurve localRotationYCurve = new AnimationCurve();
                AnimationCurve localRotationZCurve = new AnimationCurve();
                AnimationCurve localRotationWCurve = new AnimationCurve();

                AnimationCurve localScaleXCurve = new AnimationCurve();
                AnimationCurve localScaleYCurve = new AnimationCurve();
                AnimationCurve localScaleZCurve = new AnimationCurve();

                while (dataSegmentStack.Count > 0)
                {
                    currentDataSegment = dataSegmentStack.Pop();
                    if (currentDataSegment == null)
                    {
                        break;
                    }

                    for (int i = 0; i < currentDataSegment.transformData.Count; i++)
                    {
                        localPositionXCurve.AddKey(currentRelativeTime, currentDataSegment.transformData[i].localPosition.x);
                        localPositionYCurve.AddKey(currentRelativeTime, currentDataSegment.transformData[i].localPosition.y);
                        localPositionZCurve.AddKey(currentRelativeTime, currentDataSegment.transformData[i].localPosition.z);

                        localRotationXCurve.AddKey(currentRelativeTime, currentDataSegment.transformData[i].localRotation.x);
                        localRotationYCurve.AddKey(currentRelativeTime, currentDataSegment.transformData[i].localRotation.y);
                        localRotationZCurve.AddKey(currentRelativeTime, currentDataSegment.transformData[i].localRotation.z);
                        localRotationWCurve.AddKey(currentRelativeTime, currentDataSegment.transformData[i].localRotation.w);

                        localScaleXCurve.AddKey(currentRelativeTime, currentDataSegment.transformData[i].localScale.x);
                        localScaleYCurve.AddKey(currentRelativeTime, currentDataSegment.transformData[i].localScale.y);
                        localScaleZCurve.AddKey(currentRelativeTime, currentDataSegment.transformData[i].localScale.z);

                        currentRelativeTime += Time.fixedDeltaTime;
                    }
                }
                //
                //Debug.Log("max frame = " + currentRelativeTime / Time.fixedDeltaTime);

                // set curve into the animation clip
                clip.SetCurve(dummy.objectSource.hierachyName, typeof(Transform), "localPosition.x", localPositionXCurve);
                clip.SetCurve(dummy.objectSource.hierachyName, typeof(Transform), "localPosition.y", localPositionYCurve);
                clip.SetCurve(dummy.objectSource.hierachyName, typeof(Transform), "localPosition.z", localPositionZCurve);

                clip.SetCurve(dummy.objectSource.hierachyName, typeof(Transform), "localRotation.x", localRotationXCurve);
                clip.SetCurve(dummy.objectSource.hierachyName, typeof(Transform), "localRotation.y", localRotationYCurve);
                clip.SetCurve(dummy.objectSource.hierachyName, typeof(Transform), "localRotation.z", localRotationZCurve);
                clip.SetCurve(dummy.objectSource.hierachyName, typeof(Transform), "localRotation.w", localRotationWCurve);

                clip.SetCurve(dummy.objectSource.hierachyName, typeof(Transform), "localScale.x", localScaleXCurve);
                clip.SetCurve(dummy.objectSource.hierachyName, typeof(Transform), "localScale.y", localScaleYCurve);
                clip.SetCurve(dummy.objectSource.hierachyName, typeof(Transform), "localScale.z", localScaleZCurve);
            }
            return(clip);
        }