Esempio n. 1
0
        /// <summary>
        /// Processes a <see cref="DisplacementInfo"/> object into a state where it can be output into a file that Hammer can read.
        /// For Source engine forks only.
        /// </summary>
        /// <param name="displacement">The <see cref="DisplacementInfo"/> object to process.</param>
        /// <returns>A <see cref="MAPDisplacement"/> object to be added to a <see cref="MAPBrushSide"/>.</returns>
        private MAPDisplacement ProcessDisplacement(DisplacementInfo displacement)
        {
            int      power         = displacement.power;
            int      first         = displacement.dispVertStart;
            Vector3d start         = displacement.startPosition;
            int      numVertsInRow = (int)Math.Pow(2, power) + 1;

            Vector3d[,] normals = new Vector3d[numVertsInRow, numVertsInRow];
            float[,] distances  = new float[numVertsInRow, numVertsInRow];
            float[,] alphas     = new float[numVertsInRow, numVertsInRow];
            for (int i = 0; i < numVertsInRow; ++i)
            {
                for (int j = 0; j < numVertsInRow; ++j)
                {
                    normals[i, j]   = _bsp.dispVerts[first + (i * numVertsInRow) + j].normal;
                    distances[i, j] = _bsp.dispVerts[first + (i * numVertsInRow) + j].dist;
                    alphas[i, j]    = _bsp.dispVerts[first + (i * numVertsInRow) + j].alpha;
                }
            }

            return(new MAPDisplacement()
            {
                power = power,
                start = start,
                normals = normals,
                distances = distances,
                alphas = alphas
            });
        }
        /// <summary>
        /// Converts a hammer displacement to an obj object.
        /// </summary>
        /// <param name="displacementPlane">The clipping plane containing the displacement.</param>
        /// <param name="vertices">The vertices of the brush.</param>
        /// <returns>A newly created obj object.</returns>
        public static ObjObject Convert(DisplacementClippingPlane displacementPlane, IEnumerable <Vector> vertices)
        {
            Vector[] verticesInPlane = vertices.Where(x => x.OnPlane(displacementPlane)).ToArray();

            if (verticesInPlane.Length != 4)
            {
                Console.WriteLine("Error - Not enough vertices for displacement.");
                return(new ObjObject(Array.Empty <Vector>(), Array.Empty <Face>()));
            }

            DisplacementInfo dispInfo = displacementPlane.DisplacementInfo;

            Grid <Vector> grid = CreateGrid(verticesInPlane, dispInfo.Dimensions);

            grid = ApplyOffsets(grid, dispInfo.Offsets);
            grid = ApplyDistances(grid, dispInfo.Normals, dispInfo.Elevation, dispInfo.Distances);
            return(ObjFromGrid(grid, displacementPlane.Texture.Name));
        }
Esempio n. 3
0
#pragma warning restore RECS0018 // Comparison of floating point numbers with equality operator

        private void Read(DisplacementInfo dispInfo, TextureInfo texInfo)
        {
            var vertices      = map.Lumps.GetDisplacementVertices();
            var triangles     = map.Lumps.GetDisplacementTriangles();
            var texData       = map.Lumps.GetTextureData()[texInfo.TextureData];
            var textureOffset = map.Lumps.GetTextureDataStringTable()[texData.NameStringTableId];
            var textureName   = map.Lumps.GetTextureDataString()[textureOffset];

            var vertCount = ((1 << (dispInfo.Power)) + 1) * ((1 << (dispInfo.Power)) + 1);
            var triCount  = (1 << (dispInfo.Power)) * (1 << (dispInfo.Power)) * 2;

            for (var i = dispInfo.DisplacementVertexStart; i < dispInfo.DisplacementVertexStart + vertCount; i++)
            {
                /*this.vertices.Add(new Vertex
                 * {
                 *  Position = vertices[i].Vector
                 * });*/

                //var indices = GetIndices(textureName);
                // indices.Add((uint)i);
            }
        }
        /// <summary>
        /// Builds a Displacement <see cref="Mesh"/> from the <see cref="DisplacementInfo"/> referenced by
        /// <paramref name="face"/>, with UVs calculated from <see cref="Face.textureInfo"/> using
        /// <paramref name="dims"/> as the <see cref="Texture2D"/> width and height.
        /// </summary>
        /// <param name="bsp">The <see cref="BSP"/> object which <paramref name="face"/> came from.</param>
        /// <param name="face">A face referencing a <see cref="DisplacementInfo"/> and a <see cref="TextureInfo"/>.</param>
        /// <param name="dims">The dimensions of the <see cref="Texture2D"/> to map onto the resulting <see cref="Mesh"/>.</param>
        /// <returns>The <see cref="Mesh"/> created from the <see cref="DisplacementInfo"/>.</returns>
        public static Mesh CreateDisplacementMesh(BSP bsp, Face face, Vector2 dims)
        {
            Mesh mesh = null;

            if (face.numEdges > 0)
            {
                mesh = LoadVerticesFromEdges(bsp, face);
            }
            else
            {
                Debug.LogWarning("Cannot create displacement, face contains no edges.");
                return(null);
            }

            Vector3[] faceCorners   = mesh.vertices;
            int[]     faceTriangles = mesh.triangles;
            if (faceCorners.Length != 4 || faceTriangles.Length != 6)
            {
                Debug.LogWarning("Cannot create displacement mesh because " + faceCorners.Length + " corners and " + faceTriangles.Length + " triangle indices.");
                return(null);
            }

            DisplacementInfo displacementInfo = bsp.dispInfos[face.displacement];
            int numSideTriangles = (int)Mathf.Pow(2, displacementInfo.power);

            DisplacementVertex[] displacementVertices = bsp.dispVerts.GetVerticesInDisplacement(displacementInfo.dispVertStart, displacementInfo.power);

            Vector3[] corners = new Vector3[4];
            Vector3   start   = displacementInfo.startPosition.SwizzleYZ() * inch2MeterScale;

            if ((faceCorners[faceTriangles[0]] - start).sqrMagnitude < .01f)
            {
                corners[0] = faceCorners[faceTriangles[0]];
                corners[1] = faceCorners[faceTriangles[1]];
                corners[2] = faceCorners[faceTriangles[5]];
                corners[3] = faceCorners[faceTriangles[4]];
            }
            else if ((faceCorners[faceTriangles[1]] - start).sqrMagnitude < .01f)
            {
                corners[0] = faceCorners[faceTriangles[1]];
                corners[1] = faceCorners[faceTriangles[4]];
                corners[2] = faceCorners[faceTriangles[0]];
                corners[3] = faceCorners[faceTriangles[5]];
            }
            else if ((faceCorners[faceTriangles[5]] - start).sqrMagnitude < .01f)
            {
                corners[0] = faceCorners[faceTriangles[5]];
                corners[1] = faceCorners[faceTriangles[0]];
                corners[2] = faceCorners[faceTriangles[4]];
                corners[3] = faceCorners[faceTriangles[1]];
            }
            else if ((faceCorners[faceTriangles[4]] - start).sqrMagnitude < .01f)
            {
                corners[0] = faceCorners[faceTriangles[4]];
                corners[1] = faceCorners[faceTriangles[5]];
                corners[2] = faceCorners[faceTriangles[1]];
                corners[3] = faceCorners[faceTriangles[0]];
            }
            else
            {
                Debug.LogWarning("Cannot create displacement mesh because start position isn't one of the face corners.\n" +
                                 "Start position: " + start + "\n" +
                                 "Corners: " + faceCorners[faceTriangles[0]] + " " + faceCorners[faceTriangles[1]] + " " + faceCorners[faceTriangles[5]] + " " + faceCorners[faceTriangles[4]]);
                return(null);
            }

            Vector3[] offsets = new Vector3[displacementVertices.Length];
            for (int i = 0; i < displacementVertices.Length; ++i)
            {
                offsets[i] = displacementVertices[i].normal.SwizzleYZ() * displacementVertices[i].dist * inch2MeterScale;
            }
            Vector2[] uv  = new Vector2[4];
            Vector2[] uv2 = new Vector2[4];

            mesh.vertices = corners;
            mesh.uv       = uv;
            mesh.uv2      = uv2;
            mesh.CalculateUVs(bsp.GetTextureInfo(face), dims);
            mesh.CalculateTerrainVertices(offsets, numSideTriangles);
            mesh.triangles = BuildDisplacementTriangles(numSideTriangles);
            mesh.NegateVs();
            mesh.RecalculateNormals();
            mesh.RecalculateBounds();

            return(mesh);
        }
 /// <summary>
 /// Initializes a new instance of the <see cref="DisplacementClippingPlane" /> class.
 /// </summary>
 /// <param name="v1">The first vector.</param>
 /// <param name="v2">The second vector.</param>
 /// <param name="v3">The third vector.</param>
 /// <param name="texture">The texture.</param>
 /// <param name="displacement">The displacement info.</param>
 public DisplacementClippingPlane(Vector v1, Vector v2, Vector v3, PlaneTexture texture, DisplacementInfo displacement)
     : base(v1, v2, v3, texture)
     => DisplacementInfo = displacement;