Example #1
0
        void GenerateSegment(
            CurveBase curve,
            List <FrenetFrame> frames,
            List <Vector3> vertices,
            List <Vector3> normals,
            List <Vector4> tangents,
            int index
            )
        {
            // 0.0 ~ 1.0
            float u = 1f * index / tubularSegments;

            Vector3     p  = curve.GetPointAt(u);
            FrenetFrame fr = frames[index];

            Vector3 N = fr.Normal;
            Vector3 B = fr.Binormal;

            for (int j = 0; j <= radialSegments; j++)
            {
                // 0.0 ~ 2π
                float rad = 1f * j / radialSegments * PI2;

                // 円周に沿って均等に頂点を配置する
                float   cos = Mathf.Cos(rad), sin = Mathf.Sin(rad);
                Vector3 v = (cos * N + sin * B).normalized;
                vertices.Add(p + radius * v);
                normals.Add(v);

                Vector3 tangent = fr.Tangent;
                tangents.Add(new Vector4(tangent.x, tangent.y, tangent.z, 0f));
            }
        }
 public TreeSegment(FrenetFrame frame, Vector3 position, float radius)
 {
     this.frame    = frame;
     this.position = position;
     this.radius   = radius;
 }
Example #3
0
        public List <FrenetFrame> ComputeFrenetFrames(int segments, Vector3 normal, Vector3 binormal, bool closed = false)
        {
            var tangents  = new Vector3[segments + 1];
            var normals   = new Vector3[segments + 1];
            var binormals = new Vector3[segments + 1];

            for (int i = 0; i <= segments; i++)
            {
                var u = (1f * i) / segments;
                tangents[i] = GetTangentAt(u).normalized;
            }

            normals[0]   = normal;
            binormals[0] = binormal;

            float theta;

            for (int i = 1; i <= segments; i++)
            {
                // copy previous
                normals[i]   = normals[i - 1];
                binormals[i] = binormals[i - 1];

                var axis = Vector3.Cross(tangents[i - 1], tangents[i]);
                if (axis.magnitude > float.Epsilon)
                {
                    axis.Normalize();

                    float dot = Vector3.Dot(tangents[i - 1], tangents[i]);

                    theta = Mathf.Acos(Mathf.Clamp(dot, -1f, 1f));

                    normals[i] = Quaternion.AngleAxis(theta * Mathf.Rad2Deg, axis) * normals[i];
                }

                binormals[i] = Vector3.Cross(tangents[i], normals[i]).normalized;
            }

            if (closed)
            {
                theta  = Mathf.Acos(Mathf.Clamp(Vector3.Dot(normals[0], normals[segments]), -1f, 1f));
                theta /= segments;

                if (Vector3.Dot(tangents[0], Vector3.Cross(normals[0], normals[segments])) > 0f)
                {
                    theta = -theta;
                }

                for (int i = 1; i <= segments; i++)
                {
                    normals[i]   = (Quaternion.AngleAxis(Mathf.Deg2Rad * theta * i, tangents[i]) * normals[i]);
                    binormals[i] = Vector3.Cross(tangents[i], normals[i]);
                }
            }

            var frames = new List <FrenetFrame>();
            int n      = tangents.Length;

            for (int i = 0; i < n; i++)
            {
                var frame = new FrenetFrame(tangents[i], normals[i], binormals[i]);
                frames.Add(frame);
            }
            return(frames);
        }
Example #4
0
 public TreeSegment(FrenetFrame frame, Vector3 position)
 {
     this.frame    = frame;
     this.position = position;
 }