protected virtual void Awake() { rope = GetComponent <ObiRopeBase>(); rope.OnInitialized += UpdateRenderer; rope.OnAddedToSolver += Subscribe; rope.OnRemovedFromSolver += Unsubscribe; }
/** * 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>(); }
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>(); }
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); } } }
/** * 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]); } } }