private void AddWallCap( Vector3 near, Vector3 far, float hexOuterRadius, int wrapSize ) { near = HexagonPoint.Perturb( near, hexOuterRadius, wrapSize ); far = HexagonPoint.Perturb( far, hexOuterRadius, wrapSize ); Vector3 center = HexagonPoint.WallLerp(near, far); Vector3 thickness = HexagonPoint.WallThicknessOffset(near, far); Vector3 vertex1; Vector3 vertex2; Vector3 vertex3; Vector3 vertex4; vertex1 = vertex3 = center - thickness; vertex2 = vertex4 = center + thickness; vertex3.y = vertex4.y = center.y + HexagonPoint.wallHeight; walls.AddQuadUnperturbed(vertex1, vertex2, vertex3, vertex4); }
public void AddBridge( Vector3 roadCenter1, Vector3 roadCenter2, float hexOuterRadius, int wrapSize ) { roadCenter1 = HexagonPoint.Perturb( roadCenter1, hexOuterRadius, wrapSize ); roadCenter2 = HexagonPoint.Perturb( roadCenter2, hexOuterRadius, wrapSize ); Transform instance = Instantiate(bridge); instance.localPosition = (roadCenter1 + roadCenter2) * 0.5f; instance.forward = roadCenter2 - roadCenter1; float length = Vector3.Distance(roadCenter1, roadCenter2); instance.localScale = new Vector3 ( 1f, 1f, length * (1f / HexagonPoint.bridgeDesignLength) ); instance.SetParent(_container, false); }
private void TriangulateWaterfallInWater( Vector3 vertex1, Vector3 vertex2, Vector3 vertex3, Vector3 vertex4, float y1, float y2, float waterY, Vector3 indices, float hexOuterRadius, int wrapSize, MapMeshChunkLayer rivers ) { vertex1.y = vertex2.y = y1; vertex3.y = vertex4.y = y2; vertex1 = HexagonPoint.Perturb( vertex1, hexOuterRadius, wrapSize ); vertex2 = HexagonPoint.Perturb( vertex2, hexOuterRadius, wrapSize ); vertex3 = HexagonPoint.Perturb( vertex3, hexOuterRadius, wrapSize ); vertex4 = HexagonPoint.Perturb( vertex4, hexOuterRadius, wrapSize ); float t = (waterY - y2) / (y1 - y2); vertex3 = Vector3.Lerp(vertex3, vertex1, t); vertex4 = Vector3.Lerp(vertex4, vertex2, t); rivers.AddQuadUnperturbed( vertex1, vertex2, vertex3, vertex4 ); rivers.AddQuadUV(0f, 1f, 0.8f, 1f); rivers.AddQuadHexData(indices, _weights1, _weights2); }
/// <summary> /// Add a quad with perturbed corners. /// </summary> /// <param name="firstCorner"> /// The first corner of the quad to be drawn, counter-clockwise. /// </param> /// <param name="secondCorner"> /// The second corner of the quad to be drawn, counter-clockwise. /// </param> /// <param name="thirdCorner"> /// The third corner of the quad to be drawn, counter-clockwise. /// </param> /// <param name="fourthCorner"> /// The fourth corner of the quad to be drawn, counter-clockwise. /// </param> /// <param name="hexOuterRadius"> /// The outer radius (distance from the center to a given corner) of /// the hex which the quad is a part of. /// </param> /// <param name="wrapOffsetX"> /// The offset required to wrap the map along the longitudinal axis. /// This should be equal to the longitudinal size of the plane which /// the hex being drawn is a part of. /// </param> public void AddQuadPerturbed( Vector3 firstCorner, Vector3 secondCorner, Vector3 thirdCorner, Vector3 fourthCorner, float hexOuterRadius, int wrapOffsetX ) { int vertexIndex = _vertices.Count; _vertices.Add( HexagonPoint.Perturb( firstCorner, hexOuterRadius, wrapOffsetX ) ); _vertices.Add( HexagonPoint.Perturb( secondCorner, hexOuterRadius, wrapOffsetX ) ); _vertices.Add( HexagonPoint.Perturb( thirdCorner, hexOuterRadius, wrapOffsetX ) ); _vertices.Add( HexagonPoint.Perturb( fourthCorner, hexOuterRadius, wrapOffsetX ) ); _triangles.Add(vertexIndex); _triangles.Add(vertexIndex + 2); _triangles.Add(vertexIndex + 1); _triangles.Add(vertexIndex + 1); _triangles.Add(vertexIndex + 2); _triangles.Add(vertexIndex + 3); }
private void AddWallWedge( Vector3 near, Vector3 far, Vector3 point, float hexOuterRadius, int wrapSize ) { near = HexagonPoint.Perturb( near, hexOuterRadius, wrapSize ); far = HexagonPoint.Perturb( far, hexOuterRadius, wrapSize ); point = HexagonPoint.Perturb( point, hexOuterRadius, wrapSize ); Vector3 center = HexagonPoint.WallLerp(near, far); Vector3 thickness = HexagonPoint.WallThicknessOffset(near, far); Vector3 vertex1; Vector3 vertex2; Vector3 vertex3; Vector3 vertex4; Vector3 pointTop = point; point.y = center.y; vertex1 = vertex3 = center - thickness; vertex2 = vertex4 = center + thickness; vertex3.y = vertex4.y = pointTop.y = center.y + HexagonPoint.wallHeight; walls.AddQuadUnperturbed(vertex1, point, vertex3, pointTop); walls.AddQuadUnperturbed(point, vertex2, pointTop, vertex4); walls.AddTriangleUnperturbed(pointTop, vertex3, vertex4); }
public void AddSpecialFeature( Hex hex, Vector3 position, float hexOuterRadius, int wrapSize ) { Transform instance = Instantiate(special[hex.SpecialIndex - 1]); instance.localPosition = HexagonPoint.Perturb( position, hexOuterRadius, wrapSize ); RandomHash rootHash = HexagonPoint.SampleHashGrid(position); float e = rootHash.GetValue(4); instance.localRotation = Quaternion.Euler(0f, 360f * e, 0f); instance.SetParent(_container, false); }
private void AddWallSegment( Vector3 nearLeft, Vector3 farLeft, Vector3 nearRight, Vector3 farRight, float hexOuterRadius, int wrapSize, bool addTower = false ) { nearLeft = HexagonPoint.Perturb( nearLeft, hexOuterRadius, wrapSize ); farLeft = HexagonPoint.Perturb( farLeft, hexOuterRadius, wrapSize ); nearRight = HexagonPoint.Perturb( nearRight, hexOuterRadius, wrapSize ); farRight = HexagonPoint.Perturb( farRight, hexOuterRadius, wrapSize ); Vector3 left = HexagonPoint.WallLerp(nearLeft, farLeft); Vector3 right = HexagonPoint.WallLerp(nearRight, farRight); Vector3 leftThicknessOffset = HexagonPoint.WallThicknessOffset(nearLeft, farLeft); Vector3 rightThicknessOffset = HexagonPoint.WallThicknessOffset(nearRight, farRight); float leftTop = left.y + HexagonPoint.wallHeight; float rightTop = right.y + HexagonPoint.wallHeight; Vector3 vertex1; Vector3 vertex2; Vector3 vertex3; Vector3 vertex4; vertex1 = vertex3 = left - leftThicknessOffset; vertex2 = vertex4 = right - rightThicknessOffset; vertex3.y = leftTop; vertex4.y = rightTop; walls.AddQuadUnperturbed(vertex1, vertex2, vertex3, vertex4); Vector3 top1 = vertex3; Vector3 top2 = vertex4; vertex1 = vertex3 = left + leftThicknessOffset; vertex2 = vertex4 = right + rightThicknessOffset; vertex3.y = leftTop; vertex4.y = rightTop; walls.AddQuadUnperturbed(vertex2, vertex1, vertex4, vertex3); walls.AddQuadUnperturbed(top1, top2, vertex3, vertex4); if (addTower) { Transform towerInstance = Instantiate(wallTower); towerInstance.transform.localPosition = (left + right) * 0.5f; Vector3 rightDirection = right - left; rightDirection.y = 0f; towerInstance.transform.right = rightDirection; towerInstance.SetParent(_container, false); } }
public void AddFeature( Hex hex, Vector3 position, float hexOuterRadius, int wrapSize ) { if (hex.IsSpecial) { return; } /* Randomness of rotation is obtained by sampling a Hash * World rather than using Random, so the rotation of objects * will not be changed when the hex is refreshed. */ RandomHash randomHash = HexagonPoint.SampleHashGrid(position); float a = randomHash.GetValue(0); float b = randomHash.GetValue(1); float c = randomHash.GetValue(2); float d = randomHash.GetValue(3); float e = randomHash.GetValue(4); Transform prefab = PickPrefab( urbanCollections, hex.UrbanLevel, a, d ); Transform otherPrefab = PickPrefab( farmCollections, hex.FarmLevel, b, d ); float usedHash = randomHash.GetValue(0); if (prefab) { if (otherPrefab && b < a) { prefab = otherPrefab; usedHash = b; } } else if (otherPrefab) { prefab = otherPrefab; usedHash = b; } otherPrefab = PickPrefab ( plantCollections, hex.PlantLevel, c, d ); if (prefab) { if (otherPrefab && c < usedHash) { prefab = otherPrefab; } } else if (otherPrefab) { prefab = otherPrefab; } else { return; } if (!prefab) { return; } Transform instance = Instantiate(prefab); instance.localPosition = HexagonPoint.Perturb( position, hexOuterRadius, wrapSize ); instance.localRotation = Quaternion.Euler(0f, 360f * e, 0f); instance.SetParent(_container, false); }
protected void TriangulateBoundaryTriangle( Vector3 begin, Color beginWeights, Vector3 left, Color leftWeights, Vector3 boundary, Color boundaryWeights, Vector3 indices, float hexOuterRadius, int wrapSize, MapMeshChunkLayer terrain ) { /* Immediately perturb vertex 2 as an optimization since it is not * being used to derive any other point. */ Vector3 vertex2 = HexagonPoint.Perturb( HexagonPoint.TerraceLerp(begin, left, 1), hexOuterRadius, wrapSize ); Color weight2 = HexagonPoint.TerraceLerp( beginWeights, leftWeights, 1 ); /* Perturb all vertices except the boundary vertex, to avoid moving * the vertex out of alignment with a cliff. vertex2 has already been * perturbed. Handles the Cliff-Slope-Slope and Slope-Cliff-Slope cases * of the Cliff-Slope perturbation problem. */ terrain.AddTriangleUnperturbed( HexagonPoint.Perturb( begin, hexOuterRadius, wrapSize ), vertex2, boundary ); terrain.AddTriangleHexData( indices, beginWeights, weight2, boundaryWeights ); for (int i = 2; i < HexagonPoint.terraceSteps; i++) { /* vertex2 has already been perturbed, need not pertub * vertex1 as it is derived from vertex2. */ Vector3 vertex1 = vertex2; Color weight1 = weight2; vertex2 = HexagonPoint.Perturb( HexagonPoint.TerraceLerp(begin, left, i), hexOuterRadius, wrapSize ); weight2 = HexagonPoint.TerraceLerp( beginWeights, leftWeights, i ); terrain.AddTriangleUnperturbed(vertex1, vertex2, boundary); terrain.AddTriangleHexData( indices, weight1, weight2, boundaryWeights ); } terrain.AddTriangleUnperturbed( vertex2, HexagonPoint.Perturb( left, hexOuterRadius, wrapSize ), boundary ); terrain.AddTriangleHexData(indices, weight2, leftWeights, boundaryWeights); }
private void TriangulateCornerCliffTerraces( Vector3 begin, Hex beginHex, Vector3 left, Hex leftHex, Vector3 right, Hex rightHex, float hexOuterRadius, int wrapSize, MapMeshChunkLayer terrain ) { /* Set boundary distance to 1 elevation level above the bottom-most hex * in the case. */ float boundaryDistance = 1f / (leftHex.elevation - beginHex.elevation); // If boundary distance becomes negative, CCSR and CCSL case will have strange behavior. if (boundaryDistance < 0) { boundaryDistance = -boundaryDistance; } // Must interpolate between the perturbed points, not the original points. Vector3 boundary = Vector3.Lerp( HexagonPoint.Perturb( begin, hexOuterRadius, wrapSize ), HexagonPoint.Perturb( left, hexOuterRadius, wrapSize ), boundaryDistance ); Color boundaryWeights = Color.Lerp( _weights1, _weights2, boundaryDistance ); Vector3 indices; indices.x = beginHex.Index; indices.y = leftHex.Index; indices.z = rightHex.Index; TriangulateBoundaryTriangle( right, _weights3, begin, _weights1, boundary, boundaryWeights, indices, hexOuterRadius, wrapSize, terrain ); // Slope-Cliff-Slope. Triangulate a slope. if (leftHex.GetEdgeType(rightHex) == ElevationEdgeTypes.Slope) { TriangulateBoundaryTriangle( left, _weights2, right, _weights3, boundary, boundaryWeights, indices, hexOuterRadius, wrapSize, terrain ); } // Slope-Cliff-Cliff. Triangulate a cliff. else { /* Add perturbation to all vertices except the boundary vertex * to handle the Slope-Cliff-Cliff case of the Cliff-Slope perturbation * problem. */ terrain.AddTriangleUnperturbed( HexagonPoint.Perturb( left, hexOuterRadius, wrapSize ), HexagonPoint.Perturb( right, hexOuterRadius, wrapSize ), boundary ); terrain.AddTriangleHexData( indices, _weights2, _weights3, boundaryWeights ); } }