Esempio n. 1
0
 Vector3[] ComputeEdgeRelativePosition(HexagonTypeData types, Hexagon[] neighbours, int faceIndex, float height)
 {
     Vector3[] edge = new Vector3[2];
     edge[0] = ComputeVertexRelativePosition(types, neighbours, faceIndex, height);
     edge[1] = ComputeVertexRelativePosition(types, neighbours, (faceIndex + 1) % 6, height);
     return(edge);
 }
Esempio n. 2
0
    void GenerateTop(ref Chunk.MeshData meshData, Vector3 coordinateOffset, HexagonTypeData types, Hexagon[] neighbours)
    {
        // Get referential vertice.
        int verticesOffset = meshData.vertices.Count;

        for (int i = 0; i < positionsLookup.GetLength(0); i++)
        {
            Vector3 vertexRelativePosition;
            if (i != 0 && types[_typeID].SizeMultiplier < 1 - HexagonUtils.FloatEpsilon)
            {
                vertexRelativePosition = ComputeVertexRelativePosition(types, neighbours, i - 1, Height);
            }
            else
            {
                vertexRelativePosition = new Vector3(positionsLookup[i, 0], Height, positionsLookup[i, 1]);
            }

            AddVertex(ref meshData,
                      vertexRelativePosition.Mult(Scale) + coordinateOffset,
                      new Vector2(topUVsLookup[i, 0], topUVsLookup[i, 1]));
        }

        // triangles
        for (int i = 0; i < topTrianglesLookup.GetLength(0); i++)
        {
            meshData.triangles[types[_typeID].TopMaterialIndex].Add(verticesOffset + topTrianglesLookup[i, 0]);
            meshData.triangles[types[_typeID].TopMaterialIndex].Add(verticesOffset + topTrianglesLookup[i, 1]);
            meshData.triangles[types[_typeID].TopMaterialIndex].Add(verticesOffset + topTrianglesLookup[i, 2]);
        }
    }
Esempio n. 3
0
    Vector3 ComputeVertexRelativePosition(HexagonTypeData types, Hexagon[] neighbours, int vertexIndex, float height)
    {
        bool firstNeighbourVisibility  = IsSideVisible(neighbours[(vertexIndex + 5) % 6], types);
        bool secondNeighbourVisibility = IsSideVisible(neighbours[vertexIndex], types);

        if (types[_typeID].SizeMultiplier > 1 - HexagonUtils.FloatEpsilon ||
            (!firstNeighbourVisibility && !secondNeighbourVisibility))
        {
            return(new Vector3(positionsLookup[vertexIndex + 1, 0], height, positionsLookup[vertexIndex + 1, 1]));
        }
        else if (firstNeighbourVisibility && secondNeighbourVisibility)
        {
            return(new Vector3(positionsLookup[vertexIndex + 1, 0] * types[_typeID].SizeMultiplier,
                               height,
                               positionsLookup[vertexIndex + 1, 1] * types[_typeID].SizeMultiplier));
        }
        else if (firstNeighbourVisibility && !secondNeighbourVisibility)
        {
            return(new Vector3(neighbourRelativePosition[(vertexIndex + 5) % 6, 0] + positionsLookup[(vertexIndex + 2) % 6 + 1, 0] * (2 - types[_typeID].SizeMultiplier),
                               height,
                               neighbourRelativePosition[(vertexIndex + 5) % 6, 1] + positionsLookup[(vertexIndex + 2) % 6 + 1, 1] * (2 - types[_typeID].SizeMultiplier)));
        }
        else if (!firstNeighbourVisibility && secondNeighbourVisibility)
        {
            return(new Vector3(neighbourRelativePosition[(vertexIndex + 0) % 6, 0] + positionsLookup[(vertexIndex + 4) % 6 + 1, 0] * (2 - types[_typeID].SizeMultiplier),
                               height,
                               neighbourRelativePosition[(vertexIndex + 0) % 6, 1] + positionsLookup[(vertexIndex + 4) % 6 + 1, 1] * (2 - types[_typeID].SizeMultiplier)));
        }
        throw new Exception();
    }
Esempio n. 4
0
    void GenerateSide(ref Chunk.MeshData meshData, Vector3 coordinateOffset,
                      int faceIndex, Hexagon[] neighbours, HexagonTypeData types)
    {
        float bottomEdgeHeight = Height - types[_typeID].EdgeHeight;

        if (neighbours[faceIndex] != null && bottomEdgeHeight < neighbours[faceIndex].Height)
        {
            // If the bottomEdge go lower than the neighbour hexagon, make them match.
            //bottomEdgeHeight = neighbours[faceIndex].Height;
        }

        // Make Edge
        if (types[_typeID].EdgeHeight > HexagonUtils.FloatEpsilon ||
            types[_typeID].SizeMultiplier < 1 - HexagonUtils.FloatEpsilon)
        {
            Vector3[] topEdgePosition    = ComputeEdgeRelativePosition(types, neighbours, faceIndex, Height);
            Vector3[] bottomEdgePosition = ComputeEdgeRelativePositionBase(faceIndex, bottomEdgeHeight);
            AddSideQuad(ref meshData, coordinateOffset, topEdgePosition, bottomEdgePosition,
                        types[_typeID].EdgeMaterialIndex, 0f);
        }

        // Make Side
        float baseLevel = neighbours[faceIndex] == null ?
                          -10 : neighbours[faceIndex].Height - types[neighbours[faceIndex].TypeID].EdgeHeight;

        Vector3[] topSidePosition  = ComputeEdgeRelativePositionBase(faceIndex, bottomEdgeHeight);
        Vector3[] baseEdgePosition = ComputeEdgeRelativePositionBase(faceIndex, baseLevel);
        // TODO: remove unneeded underneath geometry when a corner don't make the side visible.
        if (baseLevel < bottomEdgeHeight - HexagonUtils.FloatEpsilon)
        {
            AddSideQuad(ref meshData, coordinateOffset, topSidePosition, baseEdgePosition,
                        types[_typeID].SideMaterialIndex,
                        1 - (bottomEdgeHeight - baseLevel) * types[_typeID].SideLoopFrequency);
        }
    }
Esempio n. 5
0
    void OnGUI()
    {
        // Create HexTerrainData
        EditorGUILayout.LabelField("Terrain data");
        EditorGUI.indentLevel++;
        _terrainData = EditorGUILayout.ObjectField("object:", _terrainData, typeof(HexTerrainData), false) as HexTerrainData;
        if (_terrainData != null)
        {
            _terrainName = _terrainData.name;
            _size        = _terrainData.Size;
        }
        EditorGUILayout.Separator();
        GUI.enabled  = _terrainData == null;
        _terrainName = EditorGUILayout.TextField("name: ", _terrainName);
        _size        = EditorGUILayout.IntField("Size: ", _size);
        if (GUILayout.Button("Create Terrain data"))
        {
            _terrainData = MakeHexTerrainData(_terrainName, _size);
        }
        GUI.enabled = true;
        EditorGUI.indentLevel--;

        EditorGUILayout.Space();

        // Create HexagonTypeData
        EditorGUILayout.LabelField("Type data");
        EditorGUI.indentLevel++;
        _typeData = EditorGUILayout.ObjectField("object:", _typeData, typeof(HexagonTypeData), false) as HexagonTypeData;
        if (_typeData != null)
        {
            _typeName = _typeData.name;
        }
        EditorGUILayout.Separator();
        GUI.enabled = _typeData == null;
        _typeName   = EditorGUILayout.TextField("name: ", _typeName);
        if (GUILayout.Button("Create Type data"))
        {
            _typeData = MakeHexType(_typeName);
        }
        GUI.enabled = true;
        EditorGUI.indentLevel--;

        EditorGUILayout.Space();

        // Create Map
        _gameObjectName = EditorGUILayout.TextField("new gameObject name: ", _gameObjectName);
        GUI.enabled     = _typeData != null && _terrainData != null;
        if (GUILayout.Button("Instantiate gameObject"))
        {
            if (MakeHexTerrain(_gameObjectName, _terrainData, _typeData))
            {
                this.Close();
            }
        }
        GUI.enabled = true;
    }
Esempio n. 6
0
    static HexagonTypeData MakeHexType(string name)
    {
        HexagonTypeData types = ScriptableObject.CreateInstance <HexagonTypeData>();

        AssetDatabase.CreateAsset(types, AssetDatabase.GenerateUniqueAssetPath("Assets/" + name + ".asset"));
        EditorUtility.FocusProjectWindow();
        Selection.activeObject = types;
        AssetDatabase.SaveAssets();
        return(types);
    }
Esempio n. 7
0
    static bool MakeHexTerrain(string name, HexTerrainData terrainData, HexagonTypeData typeData)
    {
        GameObject gameObject = new GameObject(name);
        HexTerrain hexTerrain = gameObject.AddComponent <HexTerrain>();

        hexTerrain.HexData = terrainData;
        hexTerrain.Types   = typeData;
        hexTerrain.BuildChunks();
        return(true);
    }
Esempio n. 8
0
    /// <summary>
    /// Add the geometry of this Hexagon inside the MeshData structure of the calling Chunk.
    /// </summary>
    /// <param name="meshData">MeshData structure to be filed </param>
    /// <param name="chunkOffSet">world offset of the parent chunk </param>
    /// <param name="coordinate">2d grid coordinate of this hexa relative to its chunk </param>
    /// <param name="neighbours"> Array containing the 6 neighbours of this hex, some can be null</param>
    public void AddToChunk(ref Chunk.MeshData meshData, Vector3 chunkOffSet, Vector2i coordinate,
                           Hexagon[] neighbours, HexagonTypeData types)
    {
        //TODO: compute top vertex position of this hexagon at start to avoid multiple recomputation.

        // Compute hexagon position.
        Vector3 coordinateOffset = HexagonUtils.ConvertHexaSpaceToOrthonormal(coordinate) + chunkOffSet;

        GenerateTop(ref meshData, coordinateOffset, types, neighbours);
        for (int i = 0; i < 6; i++)
        {
            if (IsSideVisible(neighbours[i], types))
            {
                GenerateSide(ref meshData, coordinateOffset, i, neighbours, types);
            }
        }
    }
Esempio n. 9
0
 bool IsSideVisible(Hexagon neighbour, HexagonTypeData types)
 {
     return(neighbour == null ||
            neighbour.Height < this.Height - HexagonUtils.FloatEpsilon);
 }
Esempio n. 10
0
 /// <summary>Constructor used when the asset is first created.</summary>
 /// <param name="container">HexagonTypeData holding this type.</param>
 public HexagonType(HexagonTypeData container)
 {
     _container = container;
 }