protected virtual void Awake()
 {
     rope = GetComponent <ObiRopeBase>();
     rope.OnInitialized       += UpdateRenderer;
     rope.OnAddedToSolver     += Subscribe;
     rope.OnRemovedFromSolver += Unsubscribe;
 }
Beispiel #2
0
        /**
         * Generates raw curve chunks from the rope description.
         */
        private void AllocateRawChunks(ObiRopeBase actor)
        {
            using (m_AllocateRawChunksPerfMarker.Auto())
            {
                rawChunks.Clear();

                if (actor.path == null)
                {
                    return;
                }

                // Count particles for each chunk.
                int particles = 0;
                for (int i = 0; i < actor.elements.Count; ++i)
                {
                    particles++;
                    // At discontinuities, start a new chunk.
                    if (i < actor.elements.Count - 1 && actor.elements[i].particle2 != actor.elements[i + 1].particle1)
                    {
                        AllocateChunk(++particles);
                        particles = 0;
                    }
                }
                AllocateChunk(++particles);
            }
        }
        public float thicknessScale = 0.8f;  /**< Scales section thickness.*/

        void OnEnable()
        {
            CreateMeshIfNeeded();

            Camera.onPreCull += UpdateRenderer;

            rope     = GetComponent <ObiRopeBase>();
            smoother = GetComponent <ObiPathSmoother>();
        }
Beispiel #4
0
        public float thicknessScale = 0.8f;  /**< Scales section thickness.*/

        void OnEnable()
        {
            CreateMeshIfNeeded();

#if (UNITY_2019_1_OR_NEWER)
            renderCallback = new System.Action <ScriptableRenderContext, Camera>((cntxt, cam) => { UpdateRenderer(cam); });
            RenderPipelineManager.beginCameraRendering += renderCallback;
#endif
            Camera.onPreCull += UpdateRenderer;

            rope     = GetComponent <ObiRopeBase>();
            smoother = GetComponent <ObiPathSmoother>();
        }
Beispiel #5
0
        private void PathFrameFromParticle(ObiRopeBase actor, ref ObiPathFrame frame, int particleIndex)
        {
            // Update current frame values from particles:
            frame.position  = w2l.MultiplyPoint3x4(actor.GetParticlePosition(particleIndex));
            frame.thickness = actor.GetParticleMaxRadius(particleIndex);
            frame.color     = actor.GetParticleColor(particleIndex);

            // Use particle orientation if possible:
            if (actor.usesOrientedParticles)
            {
                Quaternion orientation = w2lRotation * Quaternion.SlerpUnclamped(actor.GetParticleOrientation(particleIndex), actor.GetParticleOrientation(Mathf.Max(0, particleIndex - 1)), 0.5f);
                frame.normal   = orientation * Vector3.up;
                frame.binormal = orientation * Vector3.right;
                frame.tangent  = orientation * Vector3.forward;
            }
        }
        public void CreateChainLinkInstances(ObiRopeBase rope)
        {
            ClearChainLinkInstances();

            if (linkPrefabs.Count > 0)
            {
                for (int i = 0; i < rope.particleCount; ++i)
                {
                    int index = randomizeLinks ? UnityEngine.Random.Range(0, linkPrefabs.Count) : i % linkPrefabs.Count;

                    GameObject linkInstance = null;

                    if (linkPrefabs[index] != null)
                    {
                        linkInstance = GameObject.Instantiate(linkPrefabs[index]);
                        linkInstance.transform.SetParent(rope.transform, false);
                        linkInstance.hideFlags = HideFlags.HideAndDontSave;
                        linkInstance.SetActive(false);
                    }

                    linkInstances.Add(linkInstance);
                }
            }
        }
Beispiel #7
0
        /**
         * Generates smooth curve chunks.
         */
        public void GenerateSmoothChunks(ObiRopeBase actor, uint smoothingLevels)
        {
            using (m_GenerateSmoothChunksPerfMarker.Auto())
            {
                smoothChunks.Clear();
                smoothSections = 0;
                smoothLength   = 0;

                if (!Application.isPlaying)
                {
                    actor.RebuildElementsFromConstraints();
                }

                AllocateRawChunks(actor);

                w2l         = actor.transform.worldToLocalMatrix;
                w2lRotation = w2l.rotation;

                // keep track of the first element of each chunk
                int chunkStart = 0;

                ObiPathFrame frame_0 = new ObiPathFrame(); // "next" frame
                ObiPathFrame frame_1 = new ObiPathFrame(); // current frame
                ObiPathFrame frame_2 = new ObiPathFrame(); // previous frame

                // generate curve for each rope chunk:
                for (int i = 0; i < rawChunks.Count; ++i)
                {
                    int elementCount = rawChunks[i].Count - 1;

                    // Initialize frames:
                    frame_0.Reset();
                    frame_1.Reset();
                    frame_2.Reset();

                    PathFrameFromParticle(actor, ref frame_1, actor.elements[chunkStart].particle1, false);

                    frame_2 = frame_1;

                    for (int m = 1; m <= rawChunks[i].Count; ++m)
                    {
                        int index;
                        if (m >= elementCount)
                        {
                            // second particle of last element in the chunk.
                            index = actor.elements[chunkStart + elementCount - 1].particle2;
                        }
                        else
                        {
                            //first particle of current element.
                            index = actor.elements[chunkStart + m].particle1;
                        }

                        // generate curve frame from particle:
                        PathFrameFromParticle(actor, ref frame_0, index);

                        if (actor.usesOrientedParticles)
                        {
                            // copy frame directly.
                            frame_2 = frame_1;
                        }
                        else
                        {
                            // perform parallel transport, using forward / backward average to calculate tangent.
                            frame_1.tangent = ((frame_1.position - frame_2.position) + (frame_0.position - frame_1.position)).normalized;
                            frame_2.Transport(frame_1, twist);
                        }

                        // in case we wrapped around the rope, average first and last frames:
                        if (chunkStart + m > actor.activeParticleCount)
                        {
                            frame_2 = rawChunks[0][0] = 0.5f * frame_2 + 0.5f * rawChunks[0][0];
                        }

                        frame_1 = frame_0;

                        rawChunks[i][m - 1] = frame_2;
                    }

                    // increment chunkStart by the amount of elements in this chunk:
                    chunkStart += elementCount;

                    // adaptive curvature-based decimation:
                    if (Decimate(rawChunks[i], smoothChunks[i], decimation))
                    {
                        // if any decimation took place, swap raw and smooth chunks:
                        var aux = rawChunks[i];
                        rawChunks[i]    = smoothChunks[i];
                        smoothChunks[i] = aux;
                    }

                    // get smooth curve points:
                    Chaikin(rawChunks[i], smoothChunks[i], smoothingLevels);

                    // count total curve sections and total curve length:
                    smoothSections += smoothChunks[i].Count - 1;
                    smoothLength   += CalculateChunkLength(smoothChunks[i]);
                }
            }
        }