public override void TransportFrame(CurveFrame frame, CurveSection section, float sectionTwist) { if (frame != null) { frame.Transport(section, sectionTwist); } }
public void Set(CurveSection section) { normal = section.normal; tangent = section.tangent; binormal = Vector3.Cross(tangent, normal); position = section.positionAndRadius; }
public void Transport(CurveSection section, float twist) { // Calculate delta rotation: Quaternion rotQ = Quaternion.FromToRotation(tangent, section.tangent); Quaternion twistQ = Quaternion.AngleAxis(twist, section.tangent); Quaternion finalQ = twistQ * rotQ; // Rotate previous frame axes to obtain the new ones: normal = finalQ * normal; binormal = finalQ * binormal; tangent = section.tangent; position = section.positionAndRadius; }
/** * Generate a list of smooth curves using particles as control points. Will take into account cuts in the rope, * generating one curve for each continuous piece of rope. */ public void SmoothCurvesFromParticles() { curves.Clear(); curveSections = 0; curveLength = 0; // count amount of segments in each rope chunk: CountContinuousSegments(); ObiDistanceConstraintBatch distanceBatch = DistanceConstraints.GetFirstBatch(); Matrix4x4 w2l = transform.worldToLocalMatrix; int firstSegment = 0; // generate curve for each rope chunk: for (int i = 0; i < rawCurves.Count; ++i) { int segments = rawCurves[i].Count - 1; // allocate memory for the curve: ObiList <CurveSection> controlPoints = rawCurves[i]; // get control points position: for (int m = 0; m < segments; ++m) { int particleIndex = distanceBatch.springIndices[(firstSegment + m) * 2]; controlPoints[m] = new CurveSection(w2l.MultiplyPoint3x4(GetParticlePosition(particleIndex)), solidRadii[particleIndex], (this.colors != null && particleIndex < this.colors.Length) ? this.colors[particleIndex] : Color.white); // last segment adds its second particle too: if (m == segments - 1) { particleIndex = distanceBatch.springIndices[(firstSegment + m) * 2 + 1]; controlPoints[m + 1] = new CurveSection(w2l.MultiplyPoint3x4(GetParticlePosition(particleIndex)), solidRadii[particleIndex], (this.colors != null && particleIndex < this.colors.Length) ? this.colors[particleIndex] : Color.white); } } firstSegment += segments; // get smooth curve points: ChaikinSmoothing(controlPoints, curves[i], smoothing); // count total curve sections and total curve length: curveSections += curves[i].Count - 1; curveLength += CalculateCurveLength(curves[i]); } }
/** * Generate a list of smooth curves using particles as control points. Will take into account cuts in the rope, * generating one curve for each continuous piece of rope. */ public void SmoothCurvesFromParticles() { curves.Clear(); curveSections = 0; curveLength = 0; // count amount of segments in each rope chunk: CountContinuousSegments(); Matrix4x4 w2l = transform.worldToLocalMatrix; Quaternion matrixRotation = Quaternion.LookRotation( w2l.GetColumn(2), w2l.GetColumn(1)); int firstSegment = 0; // generate curve for each rope chunk: for (int i = 0; i < rawCurves.Count; ++i) { int segments = rawCurves[i].Count - 1; // allocate memory for the curve: ObiList <CurveSection> controlPoints = rawCurves[i]; // get control points position: int lastParticle = -1; int particle1 = -1, particle2 = -1; for (int m = 0; m < segments; ++m) { if (GetStructuralConstraintParticles(firstSegment + m, ref particle1, ref particle2)) { if (m == 0) { lastParticle = particle1; } // Find next and previous vectors: Vector3 nextV = GetParticlePosition(particle2) - GetParticlePosition(particle1); Vector3 prevV = GetParticlePosition(particle1) - GetParticlePosition(lastParticle); Vector3 pos = w2l.MultiplyPoint3x4(GetParticlePosition(particle1)); Quaternion orient = matrixRotation * Quaternion.SlerpUnclamped(GetParticleOrientation(lastParticle), GetParticleOrientation(particle1), 0.5f); Vector3 tangent = w2l.MultiplyVector(prevV + nextV).normalized; Color color = (this.colors != null && particle1 < this.colors.Length) ? this.colors[particle1] : Color.white; controlPoints[m] = new CurveSection(new Vector4(pos.x, pos.y, pos.z, principalRadii[particle1][0]), tangent, orient * Vector3.up, color); lastParticle = particle1; } } // last segment adds its second particle too: if (segments > 0) { Vector3 pos = w2l.MultiplyPoint3x4(GetParticlePosition(particle2)); Quaternion orient = matrixRotation * GetParticleOrientation(particle1); Vector3 tangent = w2l.MultiplyVector(GetParticlePosition(particle2) - GetParticlePosition(particle1)).normalized; Color color = (this.colors != null && particle2 < this.colors.Length) ? this.colors[particle2] : Color.white; controlPoints[segments] = new CurveSection(new Vector4(pos.x, pos.y, pos.z, principalRadii[particle2][0]), tangent, orient * Vector3.up, color); } firstSegment += segments; // get smooth curve points: ChaikinSmoothing(controlPoints, curves[i], smoothing); // count total curve sections and total curve length: curveSections += curves[i].Count - 1; curveLength += CalculateCurveLength(curves[i]); } }
public abstract void TransportFrame(CurveFrame frame, CurveSection section, float sectionTwist);