Esempio n. 1
0
    public Vector3 GetFaceNormal(int[] face, FractalShape baseShape, List <Vector3> normals)
    {
        int triangleIndex = -1;

        for (int i = 0; i < face.Length; i++)
        {
            for (int i1 = 0; i1 < face.Length; i1++)
            {
                for (int i2 = 0; i2 < face.Length; i2++)
                {
                    if (i == i1 || i == i2 || i1 == i2)
                    {
                        continue;
                    }
                    int[] triangle = new int[] { face[i], face[i1], face[i2] };
                    for (int i3 = 0; i3 < baseShape.triangles.Count; i3++)
                    {
                        if (baseShape.triangles[i3].points.SequenceEqual(triangle))
                        {
                            triangleIndex = i3;
                        }
                    }
                }
                if (triangleIndex != -1)
                {
                    break;
                }
            }
            if (triangleIndex != -1)
            {
                break;
            }
        }
        return(normals[triangleIndex]);
    }
Esempio n. 2
0
    public List <Shape3D> GenerateFractal(Shape3D shape, List <int[]> buildFaces, int endpt)
    {
        FractalShape origin = new FractalShape
        {
            shape      = shape,
            buildFaces = buildFaces,
            endpt      = endpt,
            depth      = 0,
        };
        List <FractalShape> unhandledChildren = new List <FractalShape> {
            origin
        };
        List <Shape3D> shapes = new List <Shape3D>();

        while (unhandledChildren.Count > 0)
        {
            List <FractalShape> newChildren = GetChildren(unhandledChildren[0]);
            unhandledChildren.AddRange(newChildren);
            foreach (FractalShape f in newChildren)
            {
                shapes.Add(f.shape);
            }

            unhandledChildren.RemoveAt(0);

            while (unhandledChildren.Count > 0 && unhandledChildren[0].depth > 3)
            {
                unhandledChildren.RemoveAt(0);
            }
        }
        return(shapes);
    }
Esempio n. 3
0
 public Fractal(FractalShape baseShape, float normalDist, float proportionBaseSize, int maxDepth)
 {
     this.baseShape          = baseShape;
     this.normalDist         = normalDist;
     this.proportionBaseSize = proportionBaseSize;
     this.maxDepth           = maxDepth;
     fractalChild            = (GameObject)Resources.Load("empty");
 }
Esempio n. 4
0
    //creates a 'transition' shape between baseShapes to maintain similar baseShape proportions.
    public List <FractalShape> GetTransitionShapes(int[] generationFaceIndexes, FractalShape baseShape, float normalDist, float proportionBaseSize, List <Vector3> normals)
    {
        List <Vector3> generationFace = new List <Vector3>();

        for (int i = 0; i < generationFaceIndexes.Length; i++)
        {
            generationFace.Add(baseShape.points[generationFaceIndexes[i]]);
        }
        Vector3 normal = GetFaceNormal(generationFaceIndexes, baseShape, normals);

        Debug.DrawLine(Vector3.zero, normal.normalized * 10, Color.cyan, 10000);
        Plane transitionPlane = new Plane(normal, generationFace[0] + normal * normalDist);

        Vector3 averageGenerationPoint = Vector3.zero;

        for (int i = 0; i < generationFace.Count; i++)
        {
            averageGenerationPoint += generationFace[i] + normal * normalDist;
        }
        averageGenerationPoint /= generationFace.Count;
        Vector2 averageGenerationPoint2D = transitionPlane.GetMappedPoint(averageGenerationPoint);

        Plane   basePlane   = new Plane(baseShape.points[baseShape.baseFace[0]], baseShape.points[baseShape.baseFace[1]], baseShape.points[baseShape.baseFace[2]]);
        Vector3 averageBase = Vector3.zero;

        for (int i = 0; i < baseShape.baseFace.Length; i++)
        {
            averageGenerationPoint += baseShape.points[baseShape.baseFace[i]] + normal * normalDist;
        }
        averageBase /= generationFace.Count;
        Vector2 averageBase2D = basePlane.GetMappedPoint(averageBase);

        List <Vector2> basePointsMapped = new List <Vector2>();

        for (int i = 0; i < baseShape.baseFace.Length; i++)
        {
            basePointsMapped.Add((basePlane.GetMappedPoint(baseShape.points[baseShape.baseFace[i]]) - averageBase2D) * proportionBaseSize);
        }

        List <Vector3> transitionFace = new List <Vector3>();

        for (int i = 0; i < basePointsMapped.Count; i++)
        {
            transitionFace.Add(basePointsMapped[i].x * transitionPlane.xDir + basePointsMapped[i].y * transitionPlane.yDir + averageGenerationPoint);
        }

        List <Vector3> transitionShapePoints = new List <Vector3>();

        transitionShapePoints.AddRange(generationFace);

        for (int i = 0; i < generationFace.Count; i++)
        {
            float leastDist      = float.MaxValue;
            int   leastDistIndex = -1;
            for (int i1 = 0; i1 < transitionFace.Count; i1++)
            {
                float sqrDist = Vector2.SqrMagnitude(transitionPlane.GetMappedPoint(transitionShapePoints[i]) - transitionPlane.GetMappedPoint(basePointsMapped[i]));
                if (sqrDist <= leastDist)
                {
                    leastDist      = sqrDist;
                    leastDistIndex = i1;
                }
            }
            Debug.DrawLine(generationFace[i], transitionFace[leastDistIndex], Color.white, 10000);
            transitionShapePoints.Add(transitionFace[leastDistIndex]);
            transitionFace.RemoveAt(leastDistIndex);
        }

        List <int[]> transitionShapeTriangles = new List <int[]>();

        for (int i = 0; i < generationFace.Count; i++)
        {
            //transitionShapeTriangles.Add(new int[] { i, i + generationFace.Count, (i + generationFace.Count - 1) % transitionShapePoints.Count });
            transitionShapeTriangles.Add(new int[] { i, (i + 1) % generationFace.Count, (i + generationFace.Count + 1) % transitionShapePoints.Count });

            if (i + 2 < generationFace.Count)
            {
                transitionShapeTriangles.Add(new int[] { 0, i + 1, i + 2 });
                transitionShapeTriangles.Add(new int[] { generationFace.Count, i + generationFace.Count + 1, i + generationFace.Count + 2 });
            }
        }

        FractalShape transitionShape = new FractalShape(transitionShapePoints, transitionShapeTriangles, new int[0], new List <int[]>());

        List <Vector2> baseShapeMapped   = new List <Vector2>();
        List <float>   distFromBasePlane = new List <float>();

        for (int i = 0; i < baseShape.points.Count; i++)
        {
            distFromBasePlane.Add(basePlane.GetDistToPlane(baseShape.points[i]) * proportionBaseSize);
            baseShapeMapped.Add((basePlane.GetMappedPoint(baseShape.points[i]) - averageBase2D) * proportionBaseSize);
        }

        List <Vector3> newBaseShapePoints = new List <Vector3>();

        for (int i = 0; i < baseShape.points.Count; i++)
        {
            newBaseShapePoints.Add(baseShapeMapped[i].x * transitionPlane.xDir + baseShapeMapped[i].y * transitionPlane.yDir + distFromBasePlane[i] * transitionPlane.normal.normalized + averageGenerationPoint);
        }
        FractalShape newBaseShape = new FractalShape(newBaseShapePoints, baseShape.triangles, baseShape.trianglesHash, baseShape.baseFace, baseShape.generationFaces);

        return(new List <FractalShape> {
            transitionShape, newBaseShape
        });
    }
Esempio n. 5
0
    public List <FractalShape> GetChildren(FractalShape origin)
    {
        List <int[]>   triangles = origin.buildFaces;
        List <Vector3> points    = origin.shape.points;
        int            endpt     = origin.endpt;

        Vector3 avgPt = Vector3.zero;

        foreach (Vector3 v in origin.shape.points)
        {
            avgPt += v;
        }
        avgPt /= origin.shape.points.Count;

        List <FractalShape> children = new List <FractalShape>();

        foreach (int[] triangle in triangles)
        {
            List <Vector3> childPoints = new List <Vector3>();
            childPoints.Add(points[endpt]);

            int[] triPts = new int[2];
            int   ind    = 0;
            for (int i = 0; i < triangle.Length; i++)
            {
                if (triangle[i] != endpt)
                {
                    triPts[ind] = triangle[i];
                    ind++;
                }
            }
            childPoints.Add(Vector3.Lerp(points[triPts[0]], points[endpt], UnityEngine.Random.Range(0.7f, 0.8f)));
            childPoints.Add(Vector3.Lerp(points[triPts[1]], points[endpt], UnityEngine.Random.Range(0.7f, 0.8f)));

            Vector3 A    = childPoints[0];
            Vector3 B    = childPoints[1];
            Vector3 C    = childPoints[2];
            Vector3 norm = Vector3.Cross((B - A), (C - A)).normalized;
            int     mult = -1;
            if (Vector3.Angle(norm, A - avgPt) < 90)
            {
                mult = 1;
            }
            float d = -Vector3.Dot(norm, A);
            float w = Vector3.Dot(norm, -norm * mult);
            //reverse array if counter clockwise
            if (w > 0)
            {
                childPoints.Reverse();
            }

            Vector3 sum = Vector3.zero;
            foreach (Vector3 v in childPoints)
            {
                sum += v;
            }
            Vector3 center = sum / 3;


            Plane   p        = new Plane(childPoints[0], childPoints[1], childPoints[2]);
            Vector3 outPoint = center + p.normal.normalized * (normalfactor / Mathf.Sqrt(origin.depth + 1));
            childPoints.Add(outPoint);

            int[][]      childTriangles = new int[][] { new int[] { 0, 1, 2 }, new int[] { 0, 1, 3 }, new int[] { 0, 2, 3 }, new int[] { 1, 2, 3 } };
            List <int[]> buildFaces     = new List <int[]>
            {
                childTriangles[1], childTriangles[2], childTriangles[3]
            };

            Shape3D      s     = new Shape3D(childTriangles, childPoints);
            FractalShape child = new FractalShape
            {
                shape      = s,
                buildFaces = buildFaces,
                endpt      = 3,
                depth      = origin.depth + 1,
            };
            children.Add(child);
        }
        return(children);
    }