Esempio n. 1
0
        /// <summary>
        /// Tries to parse a key value line.
        /// </summary>
        /// <param name="line">The line (e.g. '"editorversion" "400"').</param>
        /// <param name="key">The key that was found.</param>
        /// <param name="value">The value that was found.</param>
        /// <returns>True if successful else false.</returns>
        private bool TryParsekeyValue(string line, out string key, out object value)
        {
            key   = "";
            value = null;

            if (!line.Contains('"'))
            {
                return(false);
            }
            if (line.Count(c => c == '"') != 4)
            {
                return(false);                                // fixes 'ep1_c17_03.vmf' "rulescript" with newline in the value.
            }
            int idx = line.IndexOf('"', 1);

            key = line.Substring(1, idx - 1);
            string rawvalue = line.Substring(idx + 3, line.Length - idx - 4);

            if (rawvalue.Length == 0)
            {
                return(false);
            }

            string rawvalue_string = rawvalue;

            rawvalue = rawvalue.Replace("--", "-");                                         // fixes 'd2_coast_05.vmf' with "-8 --64 -64" double negative.
            rawvalue = System.Text.RegularExpressions.Regex.Replace(rawvalue, @"\s+", " "); // fixes 'd2_prison_07.vmf' having two spaces in a vector declaration.

            int   vi;
            float vf;

            // detect plane definition.
            if (rawvalue[0] == '(')
            {
                string[]   values = rawvalue.Replace("(", "").Replace(")", "").Split(' ');
                VmfVector3 p1     = new VmfVector3(float.Parse(values[0], CultureInfo.InvariantCulture), float.Parse(values[1], CultureInfo.InvariantCulture), float.Parse(values[2], CultureInfo.InvariantCulture));
                VmfVector3 p2     = new VmfVector3(float.Parse(values[3], CultureInfo.InvariantCulture), float.Parse(values[4], CultureInfo.InvariantCulture), float.Parse(values[5], CultureInfo.InvariantCulture));
                VmfVector3 p3     = new VmfVector3(float.Parse(values[6], CultureInfo.InvariantCulture), float.Parse(values[7], CultureInfo.InvariantCulture), float.Parse(values[8], CultureInfo.InvariantCulture));
                value = new VmfPlane(p1, p2, p3);
                return(true);
            }
            // detect uv definition.
            else if (rawvalue[0] == '[' && rawvalue[rawvalue.Length - 1] != ']')
            {
                string[] values = rawvalue.Replace("[", "").Replace("]", "").Split(' ');
                value = new VmfAxis(new VmfVector3(float.Parse(values[0], CultureInfo.InvariantCulture), float.Parse(values[1], CultureInfo.InvariantCulture), float.Parse(values[2], CultureInfo.InvariantCulture)), float.Parse(values[3], CultureInfo.InvariantCulture), float.Parse(values[4], CultureInfo.InvariantCulture));
                return(true);
            }
            // detect vector3 definition.
            else if (rawvalue.Count(c => c == ' ') == 2 && rawvalue.All(c => " -.0123456789".Contains(c)))
            {
                string[] values = rawvalue.Split(' ');
                value = new VmfVector3(float.Parse(values[0], CultureInfo.InvariantCulture), float.Parse(values[1], CultureInfo.InvariantCulture), float.Parse(values[2], CultureInfo.InvariantCulture));
                return(true);
            }
            // detect vector4 definition.
            else if (rawvalue.Count(c => c == ' ') == 3 && rawvalue.All(c => " -.0123456789".Contains(c)))
            {
                string[] values = rawvalue.Split(' ');
                value = new VmfVector4(float.Parse(values[0], CultureInfo.InvariantCulture), float.Parse(values[1], CultureInfo.InvariantCulture), float.Parse(values[2], CultureInfo.InvariantCulture), float.Parse(values[3], CultureInfo.InvariantCulture));
                return(true);
            }
            // detect alternate vector3 definition.
            else if (rawvalue.Count(c => c == ' ') == 2 && rawvalue.All(c => " e-.0123456789[]".Contains(c))) // "e" exponent occurs here fixing 'ep2_outland_07_barn.vmf'.
            {
                string[] values = rawvalue.Replace("[", "").Replace("]", "").Split(' ');
                value = new VmfVector3(float.Parse(values[0], CultureInfo.InvariantCulture), float.Parse(values[1], CultureInfo.InvariantCulture), float.Parse(values[2], CultureInfo.InvariantCulture));
                return(true);
            }
            // detect floating point value.
            else if (rawvalue.Contains('.') && float.TryParse(rawvalue, out vf))
            {
                value = vf;
                return(true);
            }
            // detect integer value.
            else if (Int32.TryParse(rawvalue, out vi))
            {
                value = vi;
                return(true);
            }
            // probably a string value.
            else
            {
                value = rawvalue_string;
                return(true);
            }
        }
        private static void BuildDisplacementSurface(ChiselBrush go, VmfSolidSide side, ChiselSurface surface, List <Vector3> vertices, Plane plane)
        {
            // create a new game object for the displacement.
            GameObject dgo = new GameObject("Displacement");

            dgo.transform.parent = go.transform;
            MeshRenderer meshRenderer = dgo.AddComponent <MeshRenderer>();
            MeshFilter   meshFilter   = dgo.AddComponent <MeshFilter>();
            MeshCollider meshCollider = dgo.AddComponent <MeshCollider>();

            // create a mesh.
            Mesh mesh = new Mesh();

            mesh.name = "Displacement";

            List <Vector3> meshVertices  = new List <Vector3>();
            List <Vector2> meshUVs       = new List <Vector2>();
            List <int>     meshTriangles = new List <int>();

            int power5 = 5;
            int power4 = 4;

            if (side.Displacement.Power == 2)
            {
                power5 = 5;
                power4 = 4;
            }
            if (side.Displacement.Power == 3)
            {
                power5 = 9;
                power4 = 8;
            }
            if (side.Displacement.Power == 4)
            {
                power5 = 17;
                power4 = 16;
            }

            // rotate vertices until we have the start position in the bottom left corner.
            VmfVector3 vmfStartPosition = side.Displacement.StartPosition;
            Vector3    startPosition    = new Vector3(vmfStartPosition.X, vmfStartPosition.Z, vmfStartPosition.Y) * inchesInMeters;

            for (int i = 0; i < 4; i++)
            {
                var first = vertices[0];
                if (Vector3.Distance(first, startPosition) < 0.01f)
                {
                    break;
                }
                vertices.RemoveAt(0);
                vertices.Add(first);
            }

            var first2 = vertices[0];

            vertices.RemoveAt(0);
            vertices.Add(first2);

            // create all of the vertices:
            for (int z = 0; z < power5; z++)
            {
                for (int x = 0; x < power5; x++)
                {
                    // calculate vertex position (grid formation):
                    Vector3 a     = Vector3.Lerp(vertices[2], vertices[3], (1.0f / power4) * z);
                    Vector3 cross = Vector3.Lerp(vertices[1], vertices[0], (1.0f / power4) * z);
                    Vector3 b     = Vector3.Lerp(a, cross, (1.0f / power4) * x);

                    // calculate UVs:
                    var localToPlaneSpace = (Matrix4x4)MathExtensions.GenerateLocalToPlaneSpaceMatrix(new float4(plane.normal, plane.distance));
                    var uvmatrix          = surface.surfaceDescription.UV0.ToMatrix();
                    uvmatrix *= localToPlaneSpace;
                    meshUVs.Add(uvmatrix.MultiplyPoint(b));

                    // calculate offsets:
                    VmfVector3 vmfOffset = side.Displacement.Offsets[power4 - z][x];
                    Vector3    offset    = new Vector3(vmfOffset.X * inchesInMeters, vmfOffset.Z * inchesInMeters, vmfOffset.Y * inchesInMeters);
                    b += offset;

                    // calculate normal to move the vertex along (displacement):
                    VmfVector3 vmfNormal = side.Displacement.Normals[power4 - z][x];
                    Vector3    normal    = new Vector3(vmfNormal.X, vmfNormal.Z, vmfNormal.Y);

                    //normal = Vector3.Project(normal, plane.normal);
                    b += plane.normal * side.Displacement.Elevation * inchesInMeters;
                    b += normal * side.Displacement.Distances[power4 - z][x] * inchesInMeters;

                    meshVertices.Add(b);
                }
            }

            // create the triangles in the same chessboard style as hammer:
            int tri = 0;

            for (int x = 0; x < (power4 * power4); x++)
            {
                tri = x + (x / power4);

                if (tri % 2 == 0)
                {
                    meshTriangles.Add(0 + tri);
                    meshTriangles.Add(power5 + 1 + tri);
                    meshTriangles.Add(power5 + tri);

                    meshTriangles.Add(0 + tri);
                    meshTriangles.Add(1 + tri);
                    meshTriangles.Add(power5 + 1 + tri);
                }
                else
                {
                    meshTriangles.Add(0 + tri);
                    meshTriangles.Add(1 + tri);
                    meshTriangles.Add(power5 + tri);

                    meshTriangles.Add(1 + tri);
                    meshTriangles.Add(power5 + 1 + tri);
                    meshTriangles.Add(power5 + tri);
                }
            }

            mesh.SetVertices(meshVertices);
            mesh.SetUVs(0, meshUVs);
            mesh.SetTriangles(meshTriangles, 0);

            // center the mesh.
            {
                mesh.RecalculateBounds();
                Vector3 meshCenter = mesh.bounds.center;
                for (int i = 0; i < meshVertices.Count; i++)
                {
                    meshVertices[i] -= meshCenter;
                }
                mesh.SetVertices(meshVertices);
                mesh.RecalculateBounds();
                dgo.transform.position = meshCenter;
            }

            mesh.RecalculateNormals();
            mesh.RecalculateTangents();

            meshFilter.sharedMesh       = mesh;
            meshCollider.sharedMesh     = mesh;
            meshRenderer.sharedMaterial = surface.brushMaterial.RenderMaterial;
        }