private static List <RingTransform> GenerateRingsRelativeToLast(WormholeSettings settings, Vector3[] verts, Vector3[] normals, Vector2[] uvs, float noiseOffset, Transform parent)
    {
        float noisePosition = noiseOffset;
        float xNoiseSeed    = Random.Range(-1236f, 21756f);
        float yNoiseSeed    = Random.Range(-8775f, 63287f) + xNoiseSeed;
        float zNoiseSeed    = Random.Range(-9849f, 153f) + yNoiseSeed;

        List <RingTransform> rings = new List <RingTransform>();

        Vector3 currentPosition = settings.Origin;
        Vector3 currentForward  = settings.Forward;
        Vector3 currentUp       = settings.Up;

        for (int i = 0; i < settings.Length; i++)
        {
            Quaternion randomQuaternion = Quaternion.Euler(
                (Mathf.PerlinNoise(noisePosition, xNoiseSeed) * 2 - 1) * settings.RotationMax,
                (Mathf.PerlinNoise(noisePosition, yNoiseSeed) * 2 - 1) * settings.RotationMax,
                (Mathf.PerlinNoise(noisePosition, zNoiseSeed) * 2 - 1) * settings.RotationMax
                );

            noisePosition += settings.NoiseSampleInterval;

            currentForward = randomQuaternion * currentForward;
            currentUp      = randomQuaternion * currentUp;

            FillCircle(settings, currentPosition, currentUp, currentForward, verts, normals, uvs, i);

            rings.Add(new RingTransform(currentPosition, Quaternion.FromToRotation(settings.Forward, currentForward), parent));

            currentPosition += currentForward * settings.RingDistanceMultiplier;
        }

        return(rings);
    }
    private static int[] BridgeLoops(WormholeSettings settings)
    {
        int[] tris = new int[(settings.Resolution * (settings.Length - 1)) * trisPerSegment * 3];
        for (int ring = 0; ring < settings.Length - 1; ring++)
        {
            for (int vert = 0; vert < settings.Resolution; vert++)
            {
                // Generating most of the ring
                int vertPos = ring * settings.Resolution + vert;
                int trisPos = vertPos * trisPerSegment * 3;

                tris[trisPos + 0] = GetIndexOnCylinder(vertPos, 0, 0, settings.Resolution);
                tris[trisPos + 1] = GetIndexOnCylinder(vertPos, 1, 1, settings.Resolution);
                tris[trisPos + 2] = GetIndexOnCylinder(vertPos, 1, 0, settings.Resolution);

                tris[trisPos + 3] = GetIndexOnCylinder(vertPos, 0, 0, settings.Resolution);
                tris[trisPos + 4] = GetIndexOnCylinder(vertPos, 0, 1, settings.Resolution);
                tris[trisPos + 5] = GetIndexOnCylinder(vertPos, 1, 1, settings.Resolution);

                tris[trisPos + 6] = GetIndexOnCylinder(vertPos, 0, 0, settings.Resolution);
                tris[trisPos + 7] = GetIndexOnCylinder(vertPos, 1, 0, settings.Resolution);
                tris[trisPos + 8] = GetIndexOnCylinder(vertPos, 1, 1, settings.Resolution);

                tris[trisPos + 9]  = GetIndexOnCylinder(vertPos, 0, 0, settings.Resolution);
                tris[trisPos + 10] = GetIndexOnCylinder(vertPos, 1, 1, settings.Resolution);
                tris[trisPos + 11] = GetIndexOnCylinder(vertPos, 0, 1, settings.Resolution);
            }
        }

        return(tris);
    }
Esempio n. 3
0
    private void Update()
    {
        if (filters != null)
        {
            Random.InitState(seed);
            WormholeSettings holeSettings = (WormholeSettings)settings;

            RingTransform lastRing      = new RingTransform();
            Transform     lastTransform = transform;

            for (int i = 0; i < filters.Length; i++)
            {
                float noiseOffset = noiseStartOffset + holeSettings.NoiseSampleInterval * holeSettings.Length * i;

                filters[i].transform.localPosition = lastTransform.TransformPoint(lastRing.Pos);

                Random.InitState(seed);
                WormholeResult wormhole = WormholeMeshGenerator.GetWormhole(holeSettings, noiseOffset, true, lastRing.Rot, filters[i].transform);
                filters[i].mesh = wormhole.Mesh;
                lastRing        = wormhole.Rings[wormhole.Rings.Count - 1];

                lastTransform = filters[i].transform;
            }
        }
    }
    private static List <RingTransform> GetRings(WormholeSettings settings, float noiseOffset, bool startFlat, Quaternion startRotation, Transform parent, Vector3[] verts, Vector3[] normals, Vector2[] uvs)
    {
        switch (settings.Mode)
        {
        case WormholeSettings.RotationMode.AngleFromAxis:
            return(GenerateRingsRelativeToAxis(settings, verts, normals, uvs, startFlat, noiseOffset, startRotation, parent));

        case WormholeSettings.RotationMode.AnglePerStep:
            return(GenerateRingsRelativeToLast(settings, verts, normals, uvs, noiseOffset, parent));
        }
        return(null);
    }
    private CapsuleCollider CreateNewCapsule(WormholeSettings holeSettings)
    {
        CapsuleCollider collider = new GameObject().AddComponent <CapsuleCollider>();

        collider.radius    = holeSettings.Radius;
        collider.height    = holeSettings.RingDistanceMultiplier + collider.radius * 2;
        collider.center    = Vector3.forward * holeSettings.RingDistanceMultiplier / 2;
        collider.direction = 2;
        collider.isTrigger = true;
        collider.tag       = "Wormhole";

        colliders.Enqueue(collider);
        return(collider);
    }
    private void GenerateSegment(bool takeFromPool = true)
    {
        MeshFilter filter = takeFromPool
            ? filters.Dequeue()
            : Instantiate(filterTemplate, transform);

        WormholeSettings holeSettings = (WormholeSettings)settings;
        float            noiseOffset  = noiseStartOffset + holeSettings.NoiseSampleInterval * holeSettings.Length * i;

        Vector3 globalPos = rings.Count > 0
            ? rings[rings.Count - 1].GlobalPos
            : Vector3.zero;

        Quaternion rot = rings.Count > 0
            ? rings[rings.Count - 1].Rot
            : Quaternion.identity;

        filter.transform.position = globalPos;

        UnityEngine.Random.InitState(seed);
        WormholeResult wormholeResult = WormholeMeshGenerator.GetWormhole(holeSettings, noiseOffset, true, rot, filter.transform);

        filter.mesh = wormholeResult.Mesh;

        i++;
        filters.Enqueue(filter);

        for (int i = 0; i < wormholeResult.Rings.Count - 1; i++)
        {
            Transform colliderTransform = takeFromPool
                ? GetCapsuleFromPool().transform
                : CreateNewCapsule(holeSettings).transform;

            colliderTransform.parent = filter.transform;
            RingTransform ring = wormholeResult.Rings[i];
            colliderTransform.position = ring.GlobalPos;
            colliderTransform.rotation = ring.GlobalRot;
        }

        rings.AddRange(wormholeResult.Rings);
        rings.RemoveAt(rings.Count - holeSettings.Length);

        if (takeFromPool)
        {
            rings.RemoveRange(0, holeSettings.Length - 1);
        }
    }
    internal static WormholeResult GetWormhole(WormholeSettings settings, float noiseOffset, bool startFlat, Quaternion startRotation, Transform parent)
    {
        Vector3[] verts   = new Vector3[settings.Resolution * settings.Length];
        Vector3[] normals = new Vector3[verts.Length];
        Vector2[] uvs     = new Vector2[verts.Length];

        List <RingTransform> rings = GetRings(settings, noiseOffset, startFlat, startRotation, parent, verts, normals, uvs);

        int[] tris = BridgeLoops(settings);

        Mesh mesh = new Mesh()
        {
            vertices  = verts,
            triangles = tris,
            normals   = normals,
            uv        = uvs
        };

        return(new WormholeResult(mesh, rings));
    }
    private static void FillCircle(WormholeSettings settings, Vector3 position, Vector3 up, Vector3 forward, Vector3[] verts, Vector3[] normals, Vector2[] uvs, int ringID)
    {
        Quaternion rotationPerStep = Quaternion.AngleAxis(360f / settings.Resolution, forward);
        int        startingIndex   = ringID * settings.Resolution;

        float uvStep = 1f / settings.Resolution;

        for (int i = 0; i < settings.Resolution; i++)
        {
            int currentIndex = startingIndex + i;

            verts[currentIndex]   = position + up * settings.Radius;
            normals[currentIndex] = -up;


            float uvx = uvStep * i;
            uvx = Mathf.Min(uvx * 2, (uvx - 1) / -1 * 2);

            uvs[currentIndex] = new Vector2(uvx, ringID % 2);

            up = rotationPerStep * up;
        }
    }