<commit_before>﻿/* High level class overseeing the mesh generation system. The core algorithm driving mesh generation is Marching Squares. 
 * It turns a grid of 0s (floors) and 1s (walls) into a collection of triangles representing the walls, but with more 
 * structure than simply putting a square at every 1. 
 * 
 * At the moment this class supports Enclosed and Isometric cave types. Isometric caves are designed with an isometric perspective
 * in mind (hence the name) and thus have ceilings that are built over the walls, not the floors. Enclosed caves are completely 
 * closed off caves designed with a 1st person perspective in mind.
 * 
 * For isometric cave generation, the 1s are triangulated into a ceiling, and the 0s are triangulated into a floor. 
 * Outlines are computed and quads are built to connect the ceiling and floor meshes, giving complete 3D 
 * geometry. Optional height maps then give the geometry added variation by translating the height of floors and ceilings. 
 * 
 * Enclosed cave generation is similar, but the ceiling is an inverted copy of the floor: the 1s in the grid are 
 * actually not used at all.
 */

using System;
using UnityEngine;

namespace CaveGeneration.MeshGeneration
{
    public enum CaveType
    {
        Isometric,
        Enclosed
    }

    public static class MeshGenerator
    {
        const int MAX_SIZE = 200;

        /// <summary>
        /// Generates meshes for a 3D cave. Safe to call outside the main thread. Note that the height map
        /// for the floor must have a max height that is at most the min height of the ceiling height map.
        /// </summary>
        /// <param name="grid">Grid specifying walls and floors. Must have length and width at most 200.</param>
        /// <param name="type">Enumerated type with options for what type of cave is being generated.</param>
        /// <exception cref="ArgumentNullException"></exception>
        /// <exception cref="ArgumentException"></exception>
        public static CaveMeshes Generate(WallGrid grid, CaveType type, IHeightMap floorHeightMap, IHeightMap ceilingHeightMap)
        {
            ValidateInput(grid, floorHeightMap, ceilingHeightMap);
            switch (type)
            {
                case CaveType.Isometric:
                    return GenerateIsometric(grid, floorHeightMap, ceilingHeightMap);
                case CaveType.Enclosed:
                    return GenerateEnclosed(grid, floorHeightMap, ceilingHeightMap);
                default:
                    throw new ArgumentException("Unrecognized Cave Type.");
            }
        }

        // In some cases, generating the entire cave is wasteful - these methods give the option
        // of just generating individual pieces. They return meshes directly, and thus must be called on main thread.

        /// <exception cref="ArgumentNullException"></exception>
        /// <exception cref="ArgumentException"></exception>
        public static Mesh GenerateFloorMesh(WallGrid grid, IHeightMap floorHeightMap)
        {
            ValidateGrid(grid);

            if (floorHeightMap == null)
                throw new ArgumentNullException("floorHeightMap");

            MeshData floor = MeshBuilder.BuildFloor(grid, floorHeightMap);
            return floor.CreateMesh();
        }

        /// <exception cref="ArgumentNullException"></exception>
        /// <exception cref="ArgumentException"></exception>
        public static Mesh GenerateIsometricCeiling(WallGrid grid, IHeightMap ceilingHeightMap)
        {
            ValidateGrid(grid);

            if (ceilingHeightMap == null)
                throw new ArgumentNullException("ceilingHeightMap");

            MeshData ceiling = MeshBuilder.BuildCeiling(grid, ceilingHeightMap);
            return ceiling.CreateMesh();
        }

        /// <exception cref="ArgumentNullException"></exception>
        /// <exception cref="ArgumentException"></exception>
        public static Mesh GenerateEnclosedCeiling(WallGrid grid, IHeightMap ceilingHeightMap)
        {
            ValidateGrid(grid);

            if (ceilingHeightMap == null)
                throw new ArgumentNullException("ceilingHeightMap");

            MeshData ceiling = MeshBuilder.BuildEnclosure(grid, ceilingHeightMap);
            return ceiling.CreateMesh();
        }

        /// <exception cref="ArgumentNullException"></exception>
        /// <exception cref="ArgumentException"></exception>
        public static Mesh GenerateWallMesh(WallGrid grid, IHeightMap floorHeightMap, IHeightMap ceilingHeightMap)
        {
            ValidateInput(grid, floorHeightMap, ceilingHeightMap);
            MeshData walls = MeshBuilder.BuildWalls(grid, floorHeightMap, ceilingHeightMap);
            return walls.CreateMesh();
        }

        static CaveMeshes GenerateIsometric(WallGrid grid, IHeightMap floorHeightMap, IHeightMap ceilingHeightMap)
        {
            MeshData floor   = MeshBuilder.BuildFloor(grid, floorHeightMap);
            MeshData ceiling = MeshBuilder.BuildCeiling(grid, ceilingHeightMap);
            MeshData wall    = MeshBuilder.BuildWalls(grid, floorHeightMap, ceilingHeightMap);
            return new CaveMeshes(floor, ceiling, wall);<commit_msg>Fixed wall-ceiling mixup<commit_after>﻿/* High level class overseeing the mesh generation system. The core algorithm driving mesh generation is Marching Squares. 
 * It turns a grid of 0s (floors) and 1s (walls) into a collection of triangles representing the walls, but with more 
 * structure than simply putting a square at every 1. 
 * 
 * At the moment this class supports Enclosed and Isometric cave types. Isometric caves are designed with an isometric perspective
 * in mind (hence the name) and thus have ceilings that are built over the walls, not the floors. Enclosed caves are completely 
 * closed off caves designed with a 1st person perspective in mind.
 * 
 * For isometric cave generation, the 1s are triangulated into a ceiling, and the 0s are triangulated into a floor. 
 * Outlines are computed and quads are built to connect the ceiling and floor meshes, giving complete 3D 
 * geometry. Optional height maps then give the geometry added variation by translating the height of floors and ceilings. 
 * 
 * Enclosed cave generation is similar, but the ceiling is an inverted copy of the floor: the 1s in the grid are 
 * actually not used at all.
 */

using System;
using UnityEngine;

namespace CaveGeneration.MeshGeneration
{
    public enum CaveType
    {
        Isometric,
        Enclosed
    }

    public static class MeshGenerator
    {
        const int MAX_SIZE = 200;

        /// <summary>
        /// Generates meshes for a 3D cave. Safe to call outside the main thread. Note that the height map
        /// for the floor must have a max height that is at most the min height of the ceiling height map.
        /// </summary>
        /// <param name="grid">Grid specifying walls and floors. Must have length and width at most 200.</param>
        /// <param name="type">Enumerated type with options for what type of cave is being generated.</param>
        /// <exception cref="ArgumentNullException"></exception>
        /// <exception cref="ArgumentException"></exception>
        public static CaveMeshes Generate(WallGrid grid, CaveType type, IHeightMap floorHeightMap, IHeightMap ceilingHeightMap)
        {
            ValidateInput(grid, floorHeightMap, ceilingHeightMap);
            switch (type)
            {
                case CaveType.Isometric:
                    return GenerateIsometric(grid, floorHeightMap, ceilingHeightMap);
                case CaveType.Enclosed:
                    return GenerateEnclosed(grid, floorHeightMap, ceilingHeightMap);
                default:
                    throw new ArgumentException("Unrecognized Cave Type.");
            }
        }

        // In some cases, generating the entire cave is wasteful - these methods give the option
        // of just generating individual pieces. They return meshes directly, and thus must be called on main thread.

        /// <exception cref="ArgumentNullException"></exception>
        /// <exception cref="ArgumentException"></exception>
        public static Mesh GenerateFloorMesh(WallGrid grid, IHeightMap floorHeightMap)
        {
            ValidateGrid(grid);

            if (floorHeightMap == null)
                throw new ArgumentNullException("floorHeightMap");

            MeshData floor = MeshBuilder.BuildFloor(grid, floorHeightMap);
            return floor.CreateMesh();
        }

        /// <exception cref="ArgumentNullException"></exception>
        /// <exception cref="ArgumentException"></exception>
        public static Mesh GenerateIsometricCeiling(WallGrid grid, IHeightMap ceilingHeightMap)
        {
            ValidateGrid(grid);

            if (ceilingHeightMap == null)
                throw new ArgumentNullException("ceilingHeightMap");

            MeshData ceiling = MeshBuilder.BuildCeiling(grid, ceilingHeightMap);
            return ceiling.CreateMesh();
        }

        /// <exception cref="ArgumentNullException"></exception>
        /// <exception cref="ArgumentException"></exception>
        public static Mesh GenerateEnclosedCeiling(WallGrid grid, IHeightMap ceilingHeightMap)
        {
            ValidateGrid(grid);

            if (ceilingHeightMap == null)
                throw new ArgumentNullException("ceilingHeightMap");

            MeshData ceiling = MeshBuilder.BuildEnclosure(grid, ceilingHeightMap);
            return ceiling.CreateMesh();
        }

        /// <exception cref="ArgumentNullException"></exception>
        /// <exception cref="ArgumentException"></exception>
        public static Mesh GenerateWallMesh(WallGrid grid, IHeightMap floorHeightMap, IHeightMap ceilingHeightMap)
        {
            ValidateInput(grid, floorHeightMap, ceilingHeightMap);
            MeshData walls = MeshBuilder.BuildWalls(grid, floorHeightMap, ceilingHeightMap);
            return walls.CreateMesh();
        }

        static CaveMeshes GenerateIsometric(WallGrid grid, IHeightMap floorHeightMap, IHeightMap ceilingHeightMap)
        {
            MeshData floor   = MeshBuilder.BuildFloor(grid, floorHeightMap);
            MeshData ceiling = MeshBuilder.BuildCeiling(grid, ceilingHeightMap);
            MeshData wall    = MeshBuilder.BuildWalls(grid, floorHeightMap, ceilingHeightMap);
            return new CaveMeshes(floor, wall, ceiling);
{'fraction_non_alphanumeric': 0.07384468794664126, 'fraction_numerical': 0.0028585040495474035, 'mean_word_length': 2.693173821252639, 'pattern_counts': {'":': 0, '<': 55, '<?xml version=': 0, '>': 55, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6263387', 'n_tokens_mistral': 2571, 'n_tokens_neox': 2402, 'n_words': 913}