Example #1
0
    void OnEnable()
    {
        parts           = new FractalPart[depth][];
        matrices        = new Matrix4x4[depth][];
        matricesBuffers = new ComputeBuffer[depth];

        int stride = 16 * 4;

        for (int i = 0, length = 1; i < parts.Length; i++, length *= 5)
        {
            parts[i]           = new FractalPart[length];
            matrices[i]        = new Matrix4x4[length];
            matricesBuffers[i] = new ComputeBuffer(length, stride);
        }

        parts[0][0] = CreatePart(0);

        for (int li = 1; li < parts.Length; li++)
        {
            FractalPart[] levelParts = parts[li];
            // loop through 4 directions
            for (int fpi = 0; fpi < levelParts.Length; fpi += 5)
            {
                for (int ci = 0; ci < 5; ci++)
                {
                    levelParts[fpi + ci] = CreatePart(ci);
                }
            }
        }
    }
        private void OnEnable()
        {
            parts           = new FractalPart[depth][];
            matrices        = new Matrix4x4[depth][];
            matricesBuffers = new ComputeBuffer[depth];
            int stride = 16 * 4;

            for (int i = 0, length = 1; i < parts.Length; i++, length *= 5)
            {
                parts[i]           = new FractalPart[length];
                matrices[i]        = new Matrix4x4[length];
                matricesBuffers[i] = new ComputeBuffer(length, stride);
            }

            parts[0][0] = CreatePart(0);
            for (int li = 1; li < parts.Length; li++)
            {
                FractalPart[] levelParts = parts[li];
                for (int fpi = 0; fpi < levelParts.Length; fpi += 5)
                {
                    for (int ci = 0; ci < 5; ci++)
                    {
                        levelParts[fpi + ci] = CreatePart(ci);
                    }
                }
            }

            if (propertyBlock == null)
            {
                propertyBlock = new MaterialPropertyBlock();
            }
        }
Example #3
0
        public void Execute(int i)
        {
            FractalPart parent = parents[i / 5];
            FractalPart part   = parts[i];

            part.spinAngle += part.spinVelocity * deltaTime;

            float3     upAxis       = mul(mul(parent.worldRotation, part.rotation), up());
            float3     sagAxis      = cross(up(), upAxis);
            float      sagMagnitude = length(sagAxis);
            quaternion baseRotation;

            if (sagMagnitude > 0f)
            {
                sagAxis /= sagMagnitude;
                quaternion sagRotation = quaternion.AxisAngle(sagAxis, part.maxSagAngle * sagMagnitude);
                baseRotation = mul(sagRotation, parent.worldRotation);
            }
            else
            {
                baseRotation = parent.worldRotation;
            }

            part.worldRotation = mul(baseRotation,
                                     mul(part.rotation, quaternion.RotateY(part.spinAngle))
                                     );
            part.worldPosition =
                parent.worldPosition +
                mul(part.worldRotation, float3(0f, 1.5f * scale, 0f));
            parts[i] = part;
            float3x3 r = float3x3(part.worldRotation) * scale;

            matrices[i] = float3x4(r.c0, r.c1, r.c2, part.worldPosition);
        }
Example #4
0
    private void OnEnable()
    {
        parts           = new FractalPart[depth][];
        matrices        = new Matrix4x4[depth][];
        matricesBuffers = new ComputeBuffer[depth];

        propertyBlock ??= new MaterialPropertyBlock();

        int stride = 16 * 4; // Matrix -> 16 float -> 16 *4 bytes

        for (int i = 0, length = 1; i < depth; i++, length *= 5)
        {
            parts[i]           = new FractalPart[length];
            matrices[i]        = new Matrix4x4[length];
            matricesBuffers[i] = new ComputeBuffer(length, stride);
        }

        parts[0][0] = CreatePart(0);
        for (int li = 1; li != depth; ++li)
        {
            FractalPart[] levelParts = parts[li];
            for (int fpi = 0; fpi < levelParts.Length; fpi += 5) // 5 Fractal part is one group
            {
                for (int ci = 0; ci != 5; ++ci)
                {
                    levelParts[fpi + ci] = CreatePart(ci);
                }
            }
        }
    }
Example #5
0
        void Update()
        {
            var         deltaRotation = Quaternion.Euler(0f, 22.5f * Time.deltaTime, 0f);
            FractalPart rootPart      = parts[0][0];

            rootPart.rotation *= deltaRotation;
            rootPart.transform.localRotation = rootPart.rotation;
            parts[0][0] = rootPart;

            for (int li = 1; li < parts.Length; li++)
            {
                FractalPart[] parentParts = parts[li - 1];
                FractalPart[] levelParts  = parts[li];
                for (int fpi = 0; fpi < levelParts.Length; fpi++)
                {
                    Transform   parentTransform = parentParts[fpi / 5].transform;
                    FractalPart part            = levelParts[fpi];
                    {
                        part.rotation *= deltaRotation;
                        part.transform.localRotation =
                            parentTransform.localRotation * part.rotation;
                        part.transform.localPosition =
                            parentTransform.localPosition +
                            parentTransform.localRotation * (1.5f * part.transform.localScale.x * part.direction);
                    }
                    levelParts[fpi] = part;
                }
            }
        }
Example #6
0
 private void Awake()
 {
     parts    = new FractalPart[depth][];
     parts[0] = new FractalPart[1];
     for (int i = 0, size = 0; i < parts.Length; i++, size *= 5)
     {
         parts[i] = new FractalPart[size];
     }
     CreatePart(0);
 }
        private void Update()
        {
            float       spinAngleDelta = 22.5f * Time.deltaTime;
            FractalPart rootPart       = parts[0][0];

            float objectScale = transform.lossyScale.x;

            matrices[0][0] = Matrix4x4.TRS(
                rootPart.worldPosition, rootPart.worldRotation, objectScale * Vector3.one
                );
            float scale = objectScale;

            rootPart.spinAngle    += spinAngleDelta;
            rootPart.worldRotation =
                rootPart.rotation * Quaternion.Euler(0f, rootPart.spinAngle, 0f);
            parts[0][0] = rootPart;

            for (int li = 1; li < parts.Length; li++)
            {
                scale *= 0.5f;
                FractalPart[] parentParts   = parts[li - 1];
                FractalPart[] levelParts    = parts[li];
                Matrix4x4[]   levelMatrices = matrices[li];
                for (int fpi = 0; fpi < levelParts.Length; fpi++)
                {
                    FractalPart parent = parentParts[fpi / 5];
                    FractalPart part   = levelParts[fpi];
                    part.spinAngle += spinAngleDelta;

                    rootPart.worldRotation =
                        transform.rotation * (rootPart.rotation * Quaternion.Euler(0f, rootPart.spinAngle, 0f));
                    rootPart.worldPosition = transform.position;

                    levelParts[fpi]    = part;
                    levelMatrices[fpi] = Matrix4x4.TRS(
                        part.worldPosition, part.worldRotation, scale * Vector3.one
                        );
                }
            }

            var bounds = new Bounds(rootPart.worldPosition, 3f * objectScale * Vector3.one);

            for (int i = 0; i < matricesBuffers.Length; i++)
            {
                ComputeBuffer buffer = matricesBuffers[i];
                buffer.SetData(matrices[i]);
                propertyBlock.SetBuffer(matricesId, buffer);
                Graphics.DrawMeshInstancedProcedural(
                    mesh, 0, material, bounds, buffer.count, propertyBlock
                    );
            }
        }
Example #8
0
        public void Execute(int i)
        {
            FractalPart parent = parents[i / 5];
            FractalPart part   = parts[i];

            part.spinAngle    += spinAngleDelta;
            part.worldRotation = mul(parent.worldRotation, mul(part.rotation, quaternion.RotateY(part.spinAngle)));
            part.worldPosition = parent.worldPosition + mul(parent.worldRotation, (1.5f * scale * part.direction));
            parts[i]           = part;
            float3x3 r = float3x3(part.worldRotation) * scale;

            matrices[i] = float3x4(r.c0, r.c1, r.c2, part.worldPosition);
        }
Example #9
0
    private void OnEnable()
    {
        if (propertyBlock == null)
        {
            propertyBlock = new MaterialPropertyBlock();
        }
        parts           = new NativeArray <FractalPart> [depth];
        matrices        = new NativeArray <float4x4> [depth];
        matricesBuffers = new ComputeBuffer[depth];

        int size   = 1;
        int stride = 16 * 4;

        for (int i = 0, length = 1; i < parts.Length; i++, length *= 5)
        {
            parts[i]           = new NativeArray <FractalPart>(length, Allocator.Persistent);
            matrices[i]        = new NativeArray <float4x4>(length, Allocator.Persistent);
            matricesBuffers[i] = new ComputeBuffer(length, stride);

            size *= 5;
        }

        FractalPart rootPart = CreatePart(0);

        parts[0][0]            = rootPart;
        rootPart.worldRotation = mul(transform.rotation,
                                     mul(rootPart.rotation, quaternion.RotateY(rootPart.spinAngle))
                                     );
        rootPart.worldPosition = transform.position;

        matrices[0][0] = float4x4.TRS(
            rootPart.worldPosition, rootPart.worldRotation, float3(ObjectScale));

        for (int li = 1; li < parts.Length; li++)
        {
            NativeArray <FractalPart> parentParts   = parts[li - 1];
            NativeArray <FractalPart> levelParts    = parts[li];
            NativeArray <float4x4>    levelMatrices = matrices[li];

            for (int fpi = 0; fpi < levelParts.Length; fpi += 5)
            {
                for (int ci = 0; ci < 5; ci++)
                {
                    levelParts[fpi + ci] = CreatePart(ci);
                }
            }
        }
    }
        //Callback to UI thread
        private async void generateCallback(FractalPart part)
        {
            //Add generated fractal part to the UI
            await main.fractalgenerator.addFractalPartToUIAsync(part);

            //Add log entry with thread number
            log.Text += "\nThread: " + part.getPos() + " is done";
            threadDone++;
            //Check if count of done threads equals amount of threads in generator
            if (threadDone == main.fractalgenerator.getTemplate().getNrOfThreads())
            {
                //When all threads done stop the stopwatch and display the final time
                stopwatch.Stop();
                log.Text += "\n\nTotal time to draw: " + stopwatch.Elapsed.ToString();
            }
        }
Example #11
0
    void Update()
    {
        float       spinAngleDelta = 22.5f * Time.deltaTime;
        FractalPart rootPart       = parts[0][0];

        rootPart.spinAngle    += spinAngleDelta;
        rootPart.worldRotation = rootPart.rotation * Quaternion.Euler(0f, rootPart.spinAngle, 0f);
        parts[0][0]            = rootPart;

        matrices[0][0] = Matrix4x4.TRS(
            rootPart.worldPosition, rootPart.worldRotation, Vector3.one
            );

        float scale = 1f;

        for (int li = 1; li < parts.Length; li++)
        {
            scale *= 0.5f;
            FractalPart[] parentParts   = parts[li - 1];
            FractalPart[] levelParts    = parts[li];
            Matrix4x4[]   levelMatrices = matrices[li];

            for (int fpi = 0; fpi < levelParts.Length; fpi++)
            {
                FractalPart parent = parentParts[fpi / 5];
                FractalPart part   = levelParts[fpi];

                part.spinAngle    += spinAngleDelta;
                part.worldRotation =
                    parent.worldRotation *
                    (part.rotation * Quaternion.Euler(0f, part.spinAngle, 0f));
                part.worldPosition =
                    parent.worldPosition +
                    parent.worldRotation * (1.5f * scale * part.direction);

                levelParts[fpi] = part;

                levelMatrices[fpi] = Matrix4x4.TRS(
                    part.worldPosition, part.worldRotation, scale * Vector3.one
                    );
            }
        }
        for (int i = 0; i < matricesBuffers.Length; i++)
        {
            matricesBuffers[i].SetData(matrices[i]);
        }
    }
Example #12
0
        private void Update()
        {
            float       spinAngleDelta = 0.125f * PI * Time.deltaTime;
            FractalPart rootPart       = parts[0][0];

            rootPart.spinAngle    += spinAngleDelta;
            rootPart.worldRotation = mul(transform.rotation,
                                         mul(rootPart.rotation, quaternion.RotateY(rootPart.spinAngle))
                                         );
            rootPart.worldPosition = transform.position;
            parts[0][0]            = rootPart;
            float    objectScale = transform.lossyScale.x;
            float3x3 r           = float3x3(rootPart.worldRotation) * objectScale;

            matrices[0][0] = float3x4(r.c0, r.c1, r.c2, rootPart.worldPosition);

            float     scale     = objectScale;
            JobHandle jobHandle = default;

            for (int li = 1; li < parts.Length; li++)
            {
                scale    *= 0.5f;
                jobHandle = new UpdateFractalLevelJob {
                    spinAngleDelta = spinAngleDelta,
                    scale          = scale,
                    parents        = parts[li - 1],
                    parts          = parts[li],
                    matrices       = matrices[li]
                }.ScheduleParallel(parts[li].Length, 5, jobHandle);
                // job을 계속 등록.
            }
            jobHandle.Complete();             // 등록된 job을 일괄 계산.

            var bounds = new Bounds(rootPart.worldPosition, 3f * objectScale * Vector3.one);

            bounds.extents = Vector3.one * 0.5f;
            for (int i = 0; i < matricesBuffers.Length; i++)
            {
                ComputeBuffer buffer = matricesBuffers[i];
                buffer.SetData(matrices[i]);
                propertyBlock.SetBuffer(matricesId, buffer);
                Graphics.DrawMeshInstancedProcedural(
                    mesh, 0, material, bounds, buffer.count, propertyBlock
                    );
            }
        }
Example #13
0
    private void Update()
    {
        float       spinAngleDelta = 22.5f * Time.deltaTime;
        FractalPart rootPart       = parts[0][0];

        rootPart.spinAngle    += spinAngleDelta;
        rootPart.worldRotation = transform.rotation * (rootPart.rotation * Quaternion.Euler(0f, rootPart.spinAngle, 0f));
        parts[0][0]            = rootPart; // FractalPart is struct, thus have to reassign to copy the value

        float objectScale = transform.localScale.x;

        matrices[0][0] = Matrix4x4.TRS(rootPart.worldPosition, rootPart.worldRotation, objectScale * Vector3.one);

        float scale = objectScale;

        for (int li = 1; li != depth; ++li)
        {
            scale *= 0.5f;
            FractalPart[] parentParts   = parts[li - 1];
            FractalPart[] levelParts    = parts[li];
            Matrix4x4[]   levelMatrices = matrices[li];
            for (int fpi = 0; fpi < levelParts.Length; fpi++)
            {
                FractalPart parent = parentParts[fpi / 5];
                FractalPart part   = levelParts[fpi];
                part.spinAngle    += spinAngleDelta;
                part.worldRotation = parent.worldRotation * (part.rotation * Quaternion.Euler(0f, part.spinAngle, 0f));
                part.worldPosition = parent.worldPosition + parent.worldRotation * (1.5f * scale * part.direction);
                levelParts[fpi]    = part;

                levelMatrices[fpi] = Matrix4x4.TRS(part.worldPosition, part.worldRotation, scale * Vector3.one);
            }
        }

        Bounds bounds = new Bounds(rootPart.worldPosition, 3f * objectScale * Vector3.one);

        for (int i = 0; i < matricesBuffers.Length; ++i)
        {
            ComputeBuffer buffer = matricesBuffers[i];
            buffer.SetData(matrices[i]);
            propertyBlock.SetBuffer(matricesId, buffer);
            Graphics.DrawMeshInstancedProcedural(mesh, 0, material, bounds, buffer.count, propertyBlock);
        }
    }
Example #14
0
    void Update()
    {
        float spinAngleDelta = 0.125f * PI * Time.deltaTime;

        FractalPart rootPart = parts[0][0];

        rootPart.spinAngle += spinAngleDelta;

        rootPart.worldRotation = mul(transform.rotation,
                                     mul(rootPart.rotation, quaternion.RotateY(rootPart.spinAngle))
                                     );

        parts[0][0] = rootPart;

        float     scale     = ObjectScale;
        JobHandle jobHandle = default;

        for (int li = 1; li < parts.Length; li++)
        {
            scale *= 0.5f;

            jobHandle = new UpdateFractalLevelJob
            {
                spinAngleDelta = spinAngleDelta,
                scale          = scale,
                parents        = parts[li - 1],
                parts          = parts[li],
                matrices       = matrices[li]
            }.ScheduleParallel(parts[li].Length, 1, jobHandle);
        }
        jobHandle.Complete();


        var bounds = new Bounds(Vector3.zero, 3f * ObjectScale * Vector3.one);

        for (int i = 0; i < matricesBuffers.Length; i++)
        {
            ComputeBuffer buffer = matricesBuffers[i];
            buffer.SetData(matrices[i]);
            propertyBlock.SetBuffer(matricesId, buffer);
            material.SetBuffer(matricesId, buffer);
            Graphics.DrawMeshInstancedProcedural(mesh, 0, material, bounds, buffer.count, propertyBlock);
        }
    }
Example #15
0
    // 将Awake改为OnEnable,为了在OnDisable时释放缓冲区
    void OnEnable()
    {
        parts = new FractalPart[depth][];
        matrices = new Matrix4x4[depth][];
        matricesBuffers = new ComputeBuffer[depth];
        // 4x4的矩阵有16个字节
        int stride = 16 * 4;
        for (int i = 0, len = 1; i < depth; ++i, len *= 5)
        {
            parts[i] = new FractalPart[len];
            matrices[i] = new Matrix4x4[len];
            matricesBuffers[i] = new ComputeBuffer(len, stride);
        }

        /*       长度
         *  深度0  1
         *  深度1  5
         *  深度2  25
         *  深度3  125
         */

        // 创建根节点
        parts[0][0] = CreatePart(0);

        // 创建所有子节点
        for (int li = 1; li < depth; li++)
        {
            // 拿到那层的数组
            var levelParts = parts[li];
            for (int fpi = 0; fpi < levelParts.Length; fpi += 5)
            {
                for(int ci = 0; ci < 5; ci++)
                {
                    levelParts[fpi + ci] = CreatePart(ci);
                }
            }
        }

        if (propertyBlock == null)
        {
            propertyBlock = new MaterialPropertyBlock();
        }
    }
Example #16
0
        public void Execute(int i)
        {
            FractalPart parent = parents[i / 5];
            FractalPart part   = parts[i];

            part.spinAngle    += spinAngleDelta;
            part.worldRotation = mul(parent.worldRotation,
                                     mul(part.rotation, quaternion.RotateY(part.spinAngle))
                                     );
            part.worldPosition =
                parent.worldPosition +
                mul(parent.worldRotation, 1.5f * scale * part.direction);

            parts[i] = part;

            matrices[i] = float4x4.TRS(
                part.worldPosition, part.worldRotation, scale * Vector3.one
                );
        }
Example #17
0
            public void Execute(int index)
            {
                FractalPart parent = parents[index / 5];
                FractalPart part   = parts[index];

                part.spinAngle += spinAngleDelta;

                part.worldRotation = mul(parent.worldRotation, mul(part.rotation, quaternion.RotateY(part.spinAngle)));

                part.worldPosition = parent.worldPosition + mul(parent.worldRotation, 1.5f * scale * part.direction);

                parts[index] = part;

                // Bacause there is no TRS method for float3x4, so we have to
                // assemble the matri
                float3x3 r = float3x3(part.worldRotation) * scale;

                matrices[index] = float3x4(r.c0, r.c1, r.c2, part.worldPosition);
            }
Example #18
0
    private void Update()
    {
        float       spinAngleDelta = 0.125f * PI * Time.deltaTime;
        FractalPart rootPart       = parts[0][0];

        rootPart.spinAngle    += spinAngleDelta;
        rootPart.worldRotation = mul(transform.rotation, mul(rootPart.rotation, quaternion.RotateY(rootPart.spinAngle)));
        parts[0][0]            = rootPart; // FractalPart is struct, thus have to reassign to copy the value

        float    objectScale = transform.localScale.x;
        float3x3 r           = float3x3(rootPart.worldRotation) * objectScale;

        matrices[0][0] = float3x4(r.c0, r.c1, r.c2, rootPart.worldPosition);

        float     scale     = objectScale;
        JobHandle jobHandle = default;

        for (int li = 1; li != depth; ++li)
        {
            scale *= 0.5f;

            jobHandle = new UpdateFractalLevelJob()
            {
                spinAngleDelta = spinAngleDelta,
                scale          = scale,
                parents        = parts[li - 1],
                parts          = parts[li],
                matrices       = matrices[li]
            }.ScheduleParallel(parts[li].Length, 10, jobHandle);
        }

        jobHandle.Complete();

        Bounds bounds = new Bounds(rootPart.worldPosition, 3f * objectScale * Vector3.one);

        for (int i = 0; i < matricesBuffers.Length; ++i)
        {
            ComputeBuffer buffer = matricesBuffers[i];
            buffer.SetData(matrices[i]);
            propertyBlock.SetBuffer(matricesId, buffer);
            Graphics.DrawMeshInstancedProcedural(mesh, 0, material, bounds, buffer.count, propertyBlock);
        }
    }
Example #19
0
        public override int[,] calculate(FractalPart fa)
        {
            int w;
            //set max pixel value range from 0-255
            int w_max = 255;

            int[,] pixels = new int[fa.getWidth(), fa.getHeight()];

            double dx = (fa.x2 - fa.x1) / fa.getWidth();
            double dy = (fa.y2 - fa.y1) / fa.getHeight();

            double cr, ci, zr, zi, zr2, zi2, zrt;

            // For every pixel width x height of this FractalPart
            for (int Xcount = 0; Xcount < fa.getWidth(); Xcount++)
            {
                for (int Ycount = 0; Ycount < fa.getHeight(); Ycount++)
                {
                    cr = fa.x1 + dx * Xcount;
                    ci = fa.y1 + dy * Ycount;

                    w   = 0;
                    zr  = 0;
                    zi  = 0;
                    zr2 = 0;
                    zi2 = 0;

                    // Calculate fractal
                    while (((zr2 + zi2) < 4) && (w < w_max))
                    {
                        zrt = zr2 - zi2 + cr;
                        zi  = 2 * zr * zi + ci;
                        zr  = zrt;
                        zr2 = Math.Pow(zr, 2);
                        zi2 = Math.Pow(zi, 2);
                        w++;
                    }
                    pixels[Xcount, Ycount] = (w < w_max) ? w : w_max;
                }
            }
            return(pixels);
        }
Example #20
0
        public override int[,] calculate(FractalPart fa)
        {
            int w;
            //Max pixel value range 0-255
            int w_max = 255;

            int[,] pixels = new int[fa.getWidth(), fa.getHeight()];

            //real and imaginary part of the constant c, determinate shape of the Julia Set
            double cX, cY;
            double zx, zy;

            // The JuliaSet requires a Constant to draw wheras the MandleBrot recalculates this value.
            cX = -0.7;
            cY = -0.27015;

            // Loop through each
            for (int Xcount = 0; Xcount < fa.getWidth(); Xcount++)
            {
                for (int Ycount = 0; Ycount < fa.getHeight(); Ycount++)
                {
                    w = 0;

                    // Sets the actual value.
                    zx = (fa.x2 - fa.x1) * (Xcount - fa.getWidth() / 2) / (0.5 * fa.getWidth());
                    zy = (fa.y2 - fa.y1) * (Ycount - fa.getHeight() / 2) / (0.5 * fa.getHeight());

                    // Calculate w to fill in the pixels.
                    while (zx * zx + (zy * zy) < 4 && w < w_max)
                    {
                        double tmp = zx * zx - zy * zy + cX;
                        zy = 2.0 * zx * zy + cY;
                        zx = tmp;
                        w++;
                    }
                    pixels[Xcount, Ycount] = (w < w_max) ? w : w_max;
                }
            }

            return(pixels);
        }
Example #21
0
    private void Awake()
    {
        parts = new FractalPart[depth][];
        for (int i = 0, length = 1; i < depth; i++, length *= 5)
        {
            parts[i] = new FractalPart[length];
        }

        float scale = 1.0f;

        parts[0][0] = CreatePart(0, 0, scale);
        for (int li = 1; li != depth; ++li)
        {
            scale *= 0.5f;
            FractalPart[] levelParts = parts[li];
            for (int fpi = 0; fpi < levelParts.Length; fpi += 5) // 5 Fractal part is one group
            {
                for (int ci = 0; ci != 5; ++ci)
                {
                    levelParts[fpi + ci] = CreatePart(li, ci, scale);
                }
            }
        }
    }
Example #22
0
    private void Update()
    {
        Quaternion  deltaRotation = Quaternion.Euler(0f, 22.5f * Time.deltaTime, 0f);
        FractalPart rootPart      = parts[0][0];

        rootPart.rotation *= deltaRotation;
        rootPart.transform.localRotation = rootPart.rotation;
        parts[0][0] = rootPart; // FractalPart is struct, thus have to reassign to copy the value

        for (int li = 1; li != depth; ++li)
        {
            FractalPart[] parentParts = parts[li - 1];
            FractalPart[] levelParts  = parts[li];
            for (int fpi = 0; fpi < levelParts.Length; fpi++)
            {
                Transform   parentTransform = parentParts[fpi / 5].transform;
                FractalPart part            = levelParts[fpi];
                part.rotation *= deltaRotation;
                part.transform.localRotation = parentTransform.localRotation * part.rotation;
                part.transform.localPosition = parentTransform.localPosition + parentTransform.localRotation * (1.5f * part.transform.localScale.x * part.direction);
                levelParts[fpi] = part;
            }
        }
    }
Example #23
0
        private void Awake()
        {
            parts = new FractalPart[depth][];
            for (int i = 0, length = 1; i < parts.Length; i++, length *= 5)
            {
                parts[i] = new FractalPart[length];
            }

            float scale = 1f;

            parts[0][0] = CreatePart(0, 0, scale);
            for (int li = 1; li < parts.Length; li++)
            {
                scale *= 0.5f;
                FractalPart[] levelParts = parts[li];
                for (int fpi = 0; fpi < levelParts.Length; fpi += 5)
                {
                    for (int ci = 0; ci < 5; ci++)
                    {
                        levelParts[fpi + ci] = CreatePart(li, ci, scale);
                    }
                }
            }
        }
Example #24
0
 public abstract int[,] calculate(FractalPart fa);
Example #25
0
    private void Update()
    {
        float       spinAngleDelta = 0.125f * PI * Time.deltaTime;
        FractalPart rootPart       = parts[0][0];

        rootPart.spinAngle    += spinAngleDelta;
        rootPart.worldRotation = mul(transform.rotation, mul(rootPart.rotation, quaternion.RotateY(rootPart.spinAngle)));
        parts[0][0]            = rootPart; // FractalPart is struct, thus have to reassign to copy the value

        float    objectScale = transform.localScale.x;
        float3x3 r           = float3x3(rootPart.worldRotation) * objectScale;

        matrices[0][0] = float3x4(r.c0, r.c1, r.c2, rootPart.worldPosition);

        float     scale     = objectScale;
        JobHandle jobHandle = default;

        for (int li = 1; li != depth; ++li)
        {
            scale *= 0.5f;

            jobHandle = new UpdateFractalLevelJob()
            {
                spinAngleDelta = spinAngleDelta,
                scale          = scale,
                parents        = parts[li - 1],
                parts          = parts[li],
                matrices       = matrices[li]
            }.ScheduleParallel(parts[li].Length, 10, jobHandle);
        }

        jobHandle.Complete();

        int    leafIndex = matricesBuffers.Length - 1;
        Bounds bounds    = new Bounds(rootPart.worldPosition, 3f * objectScale * Vector3.one);

        for (int i = 0; i < matricesBuffers.Length; ++i)
        {
            Color colorA, colorB = default;
            Mesh  instanceMesh = null;
            if (i == leafIndex)
            {
                colorA       = leafColorA;
                colorB       = leafColorB;
                instanceMesh = leafMesh;
            }
            else
            {
                float gradientInterpolate = i / (matricesBuffers.Length - 1.0f);
                colorA       = gradientA.Evaluate(gradientInterpolate);
                colorB       = gradientB.Evaluate(gradientInterpolate);
                instanceMesh = mesh;
            }

            ComputeBuffer buffer = matricesBuffers[i];
            buffer.SetData(matrices[i]);
            propertyBlock.SetColor(colorAID, colorA);
            propertyBlock.SetColor(colorBID, colorB);
            propertyBlock.SetBuffer(matricesId, buffer);
            propertyBlock.SetVector(sequenceNumbersId, sequenceNumbers[i]);
            Graphics.DrawMeshInstancedProcedural(instanceMesh, 0, material, bounds, buffer.count, propertyBlock);
        }
    }
Example #26
0
    void Update()
    {
        float       deltaTime = Time.deltaTime;
        FractalPart rootPart  = parts[0][0];

        rootPart.spinAngle    += rootPart.spinVelocity * deltaTime;
        rootPart.worldRotation = mul(transform.rotation,
                                     mul(rootPart.rotation, quaternion.RotateY(rootPart.spinAngle)));
        rootPart.worldPosition = transform.position;
        parts[0][0]            = rootPart;
        float objectScale = transform.lossyScale.x;

        float3x3 r = float3x3(rootPart.worldRotation) * objectScale;

        matrices[0][0] = float3x4(r.c0, r.c1, r.c2, rootPart.worldPosition);

        float scale = objectScale;

        JobHandle jobHandle = default;

        for (int li = 1; li < parts.Length; li++)
        {
            scale    *= 0.5f;
            jobHandle = new UpdateFractalLevelJob
            {
                deltaTime = deltaTime,
                scale     = scale,
                parents   = parts[li - 1],
                parts     = parts[li],
                matrices  = matrices[li]
            }.ScheduleParallel(parts[li].Length, 5, jobHandle);
        }
        jobHandle.Complete();

        var bounds    = new Bounds(Vector3.zero, 3f * objectScale * Vector3.one);
        int leafIndex = matricesBuffers.Length - 1;

        for (int i = 0; i < matricesBuffers.Length; i++)
        {
            ComputeBuffer buffer = matricesBuffers[i];
            buffer.SetData(matrices[i]);

            Color colorA, colorB;
            Mesh  instanceMesh;
            if (i == leafIndex)
            {
                colorA       = leafColorA;
                colorB       = leafColorB;
                instanceMesh = leafMesh;
            }
            else
            {
                float gradientInterpolator = i / (matricesBuffers.Length - 2f);
                colorA       = gradientA.Evaluate(gradientInterpolator);
                colorB       = gradientB.Evaluate(gradientInterpolator);
                instanceMesh = mesh;
            }
            propertyBlock.SetColor(colorAId, colorA);
            propertyBlock.SetColor(colorBId, colorB);
            propertyBlock.SetBuffer(matricesId, buffer);
            propertyBlock.SetVector(sequenceNumbersId, sequenceNumbers[i]);
            Graphics.DrawMeshInstancedProcedural(
                instanceMesh, 0, material, bounds, buffer.count, propertyBlock);
        }
    }