Example #1
0
    private GameObject GenerateDisplacement(int faceIndex, int dispInfoId, int modelId)
    {
        var face       = _bsp.Faces[faceIndex];
        var disp_verts = new List <UVector3>();
        var UVs        = new List <UVector2>();
        var UV2s       = new List <UVector2>();
        var cols       = new List <Color>();
        var indices    = new List <int>();
        var normals    = new List <UVector3>();

        var texInfo = _bsp.TextureInfos[face.TexInfo];
        var texData = _bsp.TextureData[texInfo.TexData];

        _bsp.LightmapLayout.GetUvs(faceIndex, out SVector2 lmMin, out SVector2 lmSize);

        var disp = _bsp.DisplacementManager[dispInfoId];

        disp.GetCorners(out SVector3 c0, out SVector3 c1, out SVector3 c2, out SVector3 c3);

        var texScale = new SVector2(1f / Math.Max(texData.Width, 1), 1f / Math.Max(texData.Height, 1));

        var uv00 = GetUv(c0, texInfo.TextureUAxis, texInfo.TextureVAxis) * texScale;
        var uv10 = GetUv(c3, texInfo.TextureUAxis, texInfo.TextureVAxis) * texScale;
        var uv01 = GetUv(c1, texInfo.TextureUAxis, texInfo.TextureVAxis) * texScale;
        var uv11 = GetUv(c2, texInfo.TextureUAxis, texInfo.TextureVAxis) * texScale;

        var subDivMul = 1f / disp.Subdivisions;

        for (var y = 0; y < disp.Subdivisions; ++y)
        {
            var v0 = (y + 0) * subDivMul;
            var v1 = (y + 1) * subDivMul;

            for (var x = 0; x < disp.Size; ++x)
            {
                var u = x * subDivMul;

                var vert1   = disp.GetPosition(x, y + 0).ToUVector();
                var uv1     = ((uv00 * (1f - u) + uv10 * u) * (1f - v0) + (uv01 * (1f - u) + uv11 * u) * v0).ToUVector();
                var uv21    = (new SVector2(u, v0) * lmSize + lmMin).ToUVector();
                var normal1 = disp.GetNormal(x, y + 0).ToUVector();
                var color1  = new Color(disp.GetAlpha(x, y + 0) / 4f, 0, 0, 0);

                disp_verts.Add(vert1);
                UVs.Add(uv1);
                UV2s.Add(uv21);
                normals.Add(normal1);
                cols.Add(color1);

                var vert2   = disp.GetPosition(x, y + 1).ToUVector();
                var uv2     = ((uv00 * (1f - u) + uv10 * u) * (1f - v1) + (uv01 * (1f - u) + uv11 * u) * v1).ToUVector();
                var uv22    = (new SVector2(u, v1) * lmSize + lmMin).ToUVector();
                var normal2 = disp.GetNormal(x, y + 1).ToUVector();
                var color2  = new Color(disp.GetAlpha(x, y + 1) / 4f, 0, 0, 0);

                disp_verts.Add(vert2);
                UVs.Add(uv2);
                UV2s.Add(uv22);
                normals.Add(normal2);
                cols.Add(color2);

                if (x != disp.Size - 1)
                {
                    var j = disp_verts.Count - 2;
                    indices.Add(j);
                    indices.Add(j + 1);
                    indices.Add(j + 2);
                    indices.Add(j + 3);
                    indices.Add(j + 2);
                    indices.Add(j + 1);
                }
            }
        }

        for (int i = 0; i < disp_verts.Count; i++)
        {
            disp_verts[i] *= _options.WorldScale;
        }

        GameObject faceObject = new GameObject("DispFace: " + modelId);

        MeshRenderer mr = faceObject.AddComponent <MeshRenderer>();

        mr.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.On;
        mr.receiveShadows    = true;
        mr.lightmapIndex     = _currentLightmap;

        MeshFilter mf = faceObject.AddComponent <MeshFilter>();

        mf.sharedMesh           = new Mesh();
        mf.sharedMesh.name      = "DispFace " + modelId;
        mf.sharedMesh.vertices  = disp_verts.ToArray();
        mf.sharedMesh.triangles = indices.ToArray();
        mf.sharedMesh.uv        = UVs.ToArray();
        mf.sharedMesh.uv2       = UV2s.ToArray();
        mf.sharedMesh.normals   = normals.ToArray();
        mf.sharedMesh.colors    = cols.ToArray();
        mf.sharedMesh.RecalculateTangents();
        mf.sharedMesh.RecalculateBounds();
        // todo: blend textures on vert R value
        //mf.sharedMesh.colors = cols.ToArray();

        faceObject.gameObject.AddComponent <MeshCollider>();

        var texString    = _bsp.GetTextureString(texData.NameStringTableId);
        var materialPath = "materials/" + texString + ".vmt";

        LoadMaterial(mr, materialPath);

        return(faceObject);
    }
Example #2
0
 public static UnityEngine.Vector2 ToUVector(this SourceUtils.Vector2 vec)
 {
     return(new UnityEngine.Vector2(vec.X, vec.Y));
 }