Ejemplo n.º 1
0
        private void RefreshTexStatus()
        {
            allTexStatus.Clear();
            string[] arrStrPath = Directory.GetFiles(Application.dataPath + "/Resources/atlas/UI/", "*.png", SearchOption.AllDirectories);
            for (int i = 0; i < arrStrPath.Length; ++i)
            {
                string strTempPath = arrStrPath[i].Replace(@"\", "/");
                strTempPath = strTempPath.Substring(strTempPath.IndexOf("Assets"));
                TextureImporter textureImporter = AssetImporter.GetAtPath(strTempPath) as TextureImporter;
                if (textureImporter != null)
                {
                    TextureEditor.ETextureCompress f = TextureEditor.ETextureCompress.Compress;
                    TextureEditor.ETextureSize     s = TextureEditor.ETextureSize.Original;
                    bool isAtlas = TextureEditor.IsAtlas(strTempPath);
                    TextureEditor.GetTexFormat(isAtlas, textureImporter.userData, out f, out s);

                    if (!TextureEditor.IsDefaultFormat(isAtlas, f, s))
                    {
                        TexInfo tf = new TexInfo();
                        tf.path      = strTempPath;
                        tf.srcFormat = f;
                        tf.alphaSize = s;
                        tf.isAtlas   = isAtlas;
                        allTexStatus.Add(tf);
                    }
                }
            }
            allTexStatus.Sort(CompareNewMsg);
        }
Ejemplo n.º 2
0
        public bool Add(TexInfo info, bool isReplace = false)
        {
            if (info == null)
            {
                return(false);
            }

            if (string.IsNullOrEmpty(info.name))
            {
                return(false);
            }

            var texMaps = GetOrCreateMaps();

            if (texMaps.ContainsKey(info.name))
            {
                if (isReplace)
                {
                    texMaps[info.name] = info;
                    return(true);
                }
                return(false);
            }

            texMaps.Add(info.name, info);

            return(true);
        }
Ejemplo n.º 3
0
        void OnGUI()
        {
            if (_labelstyle == null)
            {
                _labelstyle          = new GUIStyle(EditorStyles.boldLabel);
                _labelstyle.fontSize = 11;
            }

            if (_labelstyle_1 == null)
            {
                _labelstyle_1           = new GUIStyle(EditorStyles.boldLabel);
                _labelstyle_1.fontStyle = FontStyle.BoldAndItalic;
                _labelstyle_1.fontSize  = 11;
            }

            EditorGUILayout.Space();
            GUILayout.Label("UI Texture Stats:", _labelstyle);
            if (GUILayout.Button("SetDefault", GUILayout.MaxWidth(80)))
            {
                SetDefaultAlpha();
            }
            EditorGUILayout.Space();

            scrollPosition = GUILayout.BeginScrollView(scrollPosition, false, false);
            for (int i = 0; i < allTexStatus.Count; ++i)
            {
                TexInfo tf = allTexStatus[i];
                GUILayout.BeginHorizontal();
                GUILayout.Label(tf.path);
                EditorGUILayout.EnumPopup("压缩", tf.srcFormat);
                EditorGUILayout.EnumPopup("Alpha缩放", tf.alphaSize);
                GUILayout.EndHorizontal();
            }
            EditorGUILayout.EndScrollView();
        }
Ejemplo n.º 4
0
    // The inspiration for this is the BSPSource source code. It's not a direct copy but does essentially
    // the same thing as the algorithm to "create a prism back", and isn't as neatly written.
    public static MAPBrush createBrushFromWind(Vector3D[] froms, Vector3D[] tos, string texture, string backtex, TexInfo scaling)
    {
        Vector3D[]     planepts = new Vector3D[3];
        MAPBrushSide[] sides    = new MAPBrushSide[froms.Length + 2];      // Each edge, plus a front and back side
        planepts[0] = froms[0];
        planepts[1] = tos[0];
        planepts[2] = tos[1];
        Plane    plane         = new Plane(planepts);
        Vector3D reverseNormal = plane.Normal;

        sides[0] = new MAPBrushSide(planepts, texture, scaling.SAxis.Point, scaling.SShift, scaling.TAxis.Point, scaling.TShift, 0, 1, 1, 0, "wld_lightmap", 16, 0);

        Vector3D[] backplanepts = new Vector3D[3];
        backplanepts[0] = froms[0] - (reverseNormal);
        backplanepts[1] = tos[1] - (reverseNormal);
        backplanepts[2] = tos[0] - (reverseNormal);
        Plane backplane = new Plane(backplanepts);

        Vector3D[] backaxes = TexInfo.textureAxisFromPlane(backplane);
        sides[1] = new MAPBrushSide(backplane, backtex, backaxes[0].Point, 0, backaxes[1].Point, 0, 0, 1, 1, 0, "wld_lightmap", 16, 0);

        for (int i = 0; i < froms.Length; i++)
        {
            // each edge
            Vector3D[] sideplanepts = new Vector3D[3];
            sideplanepts[0] = froms[i];
            sideplanepts[1] = tos[i];
            sideplanepts[2] = froms[i] + (reverseNormal);
            Plane      sideplane = new Plane(sideplanepts);
            Vector3D[] sideaxes  = TexInfo.textureAxisFromPlane(sideplane);
            sides[i + 2] = new MAPBrushSide(sideplane, backtex, sideaxes[0].Point, 0, sideaxes[1].Point, 0, 0, 1, 1, 0, "wld_lightmap", 16, 0);
        }

        return(new MAPBrush(sides, 0, 0, false));
    }
Ejemplo n.º 5
0
        private TexInfo CreateDefaultTexInfo()
        {
            TexInfo defaultTexInfo = new TexInfo();

            defaultTexInfo.name = DEFAULT_KEY;
            var smr = gameObject.GetComponent <SkinnedMeshRenderer>();

            if (smr != null)
            {
                Material[] materials = smr.sharedMaterials;

                if (materials != null)
                {
                    MaterialPropertyBlock materialPropertyBlock = new MaterialPropertyBlock();
                    for (int i = 0; i < materials.Length; ++i)
                    {
                        materialPropertyBlock.Clear();
                        smr.GetPropertyBlock(materialPropertyBlock, i);

                        defaultTexInfo.mainTex = materialPropertyBlock.GetTexture("_MainTex");
                        defaultTexInfo.flowTex = materialPropertyBlock.GetTexture("_FlowTex");
                        break;
                    }
                }
            }

            return(defaultTexInfo);
        }
Ejemplo n.º 6
0
        protected override void OnUpdate(DX11RenderContext context)
        {
            //Grab a temp target if enabled

            TexInfo ti = this.rtm.GetRenderTarget(context);

            if (ti.w != this.width || ti.h != this.height || !this.targets.ContainsKey(context) || this.invalidate ||
                ti.format != this.format)
            {
                this.invalidate = false;
                this.width      = ti.w;
                this.height     = ti.h;
                this.format     = ti.format;

                this.depthmanager.NeedReset = true;

                if (targets.ContainsKey(context))
                {
                    context.ResourcePool.Unlock(targets[context]);
                }

                if (targetresolve.ContainsKey(context))
                {
                    context.ResourcePool.Unlock(targetresolve[context]);
                }

                int aacount   = Convert.ToInt32(this.FInAASamplesPerPixel[0].Name);
                int aaquality = 0;

                if (aacount > 1)
                {
                    List <SampleDescription> sds = context.GetMultisampleFormatInfo(ti.format);
                    int maxlevels = sds[sds.Count - 1].Count;

                    if (aacount > maxlevels)
                    {
                        FHost.Log(TLogType.Warning, "Multisample count too high for this format, reverted to: " + maxlevels);
                        aacount = maxlevels;
                    }

                    DX11RenderTarget2D temptarget        = context.ResourcePool.LockRenderTarget(this.width, this.height, ti.format, new SampleDescription(aacount, aaquality), this.FInDoMipMaps[0], this.FInMipLevel[0]).Element;
                    DX11RenderTarget2D temptargetresolve = context.ResourcePool.LockRenderTarget(this.width, this.height, ti.format, new SampleDescription(1, 0), this.FInDoMipMaps[0], this.FInMipLevel[0]).Element;

                    targets[context]       = temptarget;
                    targetresolve[context] = temptargetresolve;

                    this.FOutBuffers[0][context]   = temptargetresolve;
                    this.FOutAABuffers[0][context] = temptarget;
                }
                else
                {
                    //Bind both texture as same output
                    DX11RenderTarget2D temptarget = context.ResourcePool.LockRenderTarget(this.width, this.height, ti.format, new SampleDescription(aacount, aaquality), this.FInDoMipMaps[0], this.FInMipLevel[0]).Element;
                    targets[context] = temptarget;

                    this.FOutBuffers[0][context]   = temptarget;
                    this.FOutAABuffers[0][context] = temptarget;
                }
            }
        }
Ejemplo n.º 7
0
        private void FindTexs(string pathInfo)
        {
            m_FormatMap.Clear();
            m_SizeMap.Clear();
            m_TexMap.Clear();
            m_TexMatMap.Clear();
            m_TexInfo    = null;
            m_TexMat     = null;
            m_Tex        = null;
            m_TotalSize  = 0;
            m_TotalCount = 0;
            EditorUtility.UnloadUnusedAssetsImmediate();
            string[] parsePath = pathInfo.Split('=');
            string   paths     = parsePath[0];
            string   findType  = parsePath[1];
            string   scanMat   = parsePath[2];

            string[] pathList = paths.Split('|');

            if (scanMat == "1")
            {
                for (int i = 0; i < pathList.Length; ++i)
                {
                    string subPath = pathList[i];
                    FindMat(subPath);
                }
            }
            bool findTex          = false;
            bool findDependencies = false;

            if (findType == "0")
            {
                findTex = true;
            }
            else if (findType == "1")
            {
                findDependencies = true;
            }
            else if (findType == "2")
            {
                findTex          = true;
                findDependencies = true;
            }
            for (int i = 0; i < pathList.Length; ++i)
            {
                string subPath = pathList[i];
                if (findTex)
                {
                    ScanTex(subPath, "*.png");
                    ScanTex(subPath, "*.tga");
                }

                if (findDependencies)
                {
                    ScanPrefab(subPath);
                }
            }
            m_TexMap.Clear();
        }
Ejemplo n.º 8
0
    public Texture(byte[] data, mapType type) : base(data)
    {
        switch (type)
        {
        case mapType.TYPE_NIGHTFIRE:
            name = DataReader.readNullTerminatedString(new byte[] { data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7], data[8], data[9], data[10], data[11], data[12], data[13], data[14], data[15], data[16], data[17], data[18], data[19], data[20], data[21], data[22], data[23], data[24], data[25], data[26], data[27], data[28], data[29], data[30], data[31], data[32], data[33], data[34], data[35], data[36], data[37], data[38], data[39], data[40], data[41], data[42], data[43], data[44], data[45], data[46], data[47], data[48], data[49], data[50], data[51], data[52], data[53], data[54], data[55], data[56], data[57], data[58], data[59], data[60], data[61], data[62], data[63] });
            break;

        case mapType.TYPE_QUAKE:
            name = DataReader.readNullTerminatedString(new byte[] { data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7], data[8], data[9], data[10], data[11], data[12], data[13], data[14], data[15] });
            break;

        case mapType.TYPE_QUAKE2:
        case mapType.TYPE_SOF:
        case mapType.TYPE_DAIKATANA:
            texAxes = new TexInfo(DataReader.readPoint3F(data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7], data[8], data[9], data[10], data[11]), DataReader.readFloat(data[12], data[13], data[14], data[15]), DataReader.readPoint3F(data[16], data[17], data[18], data[19], data[20], data[21], data[22], data[23], data[24], data[25], data[26], data[27]), DataReader.readFloat(data[28], data[29], data[30], data[31]), -1, -1);
            flags   = new byte[] { data[32], data[33], data[34], data[35] };
            name    = DataReader.readNullTerminatedString(new byte[] { data[40], data[41], data[42], data[43], data[44], data[45], data[46], data[47], data[48], data[49], data[50], data[51], data[52], data[53], data[54], data[55], data[56], data[57], data[58], data[59], data[60], data[61], data[62], data[63], data[64], data[65], data[66], data[67], data[68], data[69], data[70], data[71] });
            break;

        case mapType.TYPE_MOHAA:
            mask = DataReader.readNullTerminatedString(new byte[] { data[76], data[77], data[78], data[79], data[80], data[81], data[82], data[83], data[84], data[85], data[86], data[87], data[88], data[89], data[90], data[91], data[92], data[93], data[94], data[95], data[96], data[97], data[98], data[99], data[100], data[101], data[102], data[103], data[104], data[105], data[106], data[107], data[108], data[109], data[110], data[111], data[112], data[113], data[114], data[115], data[116], data[117], data[118], data[119], data[120], data[121], data[122], data[123], data[124], data[125], data[126], data[127], data[128], data[129], data[130], data[131], data[132], data[133], data[134], data[135], data[136], data[137], data[138], data[139] });
            goto case mapType.TYPE_STEF2;

        case mapType.TYPE_STEF2:
        case mapType.TYPE_STEF2DEMO:
        case mapType.TYPE_RAVEN:
        case mapType.TYPE_QUAKE3:
        case mapType.TYPE_COD:
        case mapType.TYPE_COD2:
        case mapType.TYPE_COD4:
        case mapType.TYPE_FAKK:
            name     = DataReader.readNullTerminatedString(new byte[] { data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7], data[8], data[9], data[10], data[11], data[12], data[13], data[14], data[15], data[16], data[17], data[18], data[19], data[20], data[21], data[22], data[23], data[24], data[25], data[26], data[27], data[28], data[29], data[30], data[31], data[32], data[33], data[34], data[35], data[36], data[37], data[38], data[39], data[40], data[41], data[42], data[43], data[44], data[45], data[46], data[47], data[48], data[49], data[50], data[51], data[52], data[53], data[54], data[55], data[56], data[57], data[58], data[59], data[60], data[61], data[62], data[63] });
            flags    = new byte[] { data[64], data[65], data[66], data[67] };
            contents = new byte[] { data[68], data[69], data[70], data[71] };
            break;

        case mapType.TYPE_SOURCE17:
        case mapType.TYPE_SOURCE18:
        case mapType.TYPE_SOURCE19:
        case mapType.TYPE_SOURCE20:
        case mapType.TYPE_SOURCE21:
        case mapType.TYPE_SOURCE22:
        case mapType.TYPE_SOURCE23:
        case mapType.TYPE_SOURCE27:
        case mapType.TYPE_TACTICALINTERVENTION:
        case mapType.TYPE_VINDICTUS:
        case mapType.TYPE_DMOMAM:
            name = DataReader.readString(data);
            break;

        case mapType.TYPE_SIN:
            texAxes = new TexInfo(DataReader.readPoint3F(data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7], data[8], data[9], data[10], data[11]), DataReader.readFloat(data[12], data[13], data[14], data[15]), DataReader.readPoint3F(data[16], data[17], data[18], data[19], data[20], data[21], data[22], data[23], data[24], data[25], data[26], data[27]), DataReader.readFloat(data[28], data[29], data[30], data[31]), -1, -1);
            flags   = new byte[] { data[32], data[33], data[34], data[35] };
            name    = DataReader.readNullTerminatedString(new byte[] { data[36], data[37], data[38], data[39], data[40], data[41], data[42], data[43], data[44], data[45], data[46], data[47], data[48], data[49], data[50], data[51], data[52], data[53], data[54], data[55], data[56], data[57], data[58], data[59], data[60], data[61], data[62], data[63], data[64], data[65], data[66], data[67], data[68], data[69], data[70], data[71], data[72], data[73], data[74], data[75], data[76], data[77], data[78], data[79], data[80], data[81], data[82], data[83], data[84], data[85], data[86], data[87], data[88], data[89], data[90], data[91], data[92], data[93], data[94], data[95], data[96], data[97], data[98], data[99] });
            break;
        }
    }
Ejemplo n.º 9
0
        private static void OnLoad(UnityEngine.Object asset, System.Object obj)
        {
            TempLoad tl = (TempLoad)obj;

            try
            {
                Texture2D tex = (Texture2D)asset;

                TexInfo texInfo = new TexInfo();
                texInfo.tex          = tex;
                texInfo.w            = (short)tex.width;
                texInfo.h            = (short)tex.height;
                tl.texInfo[tl.index] = texInfo;

                bool    over = true;
                int     i, count;
                TexInfo ti;
                for (i = 0, count = tl.texInfo.Length; i < count; i++)
                {
                    ti = tl.texInfo[i];
                    if (ti == null)
                    {
                        over = false;
                        break;
                    }
                }
                tl.over = over;

                if (over)
                {
                    if (tl.autoTemp)
                    {
                        PackCombineTexture(tl);
                    }
                    else
                    {
                        Texture2D texture = new Texture2D(1, 1);

                        Rect[] rect = CreateTex(texture, tl.texInfo);

                        ProcessCombine(tl, texture, rect);
                    }
                }
            }
            catch (System.Exception e)
            {
                for (int i = 0; i < tl.meshList.Count; i++)
                {
                    Object.Destroy(tl.meshList[i]);
                }
                if (tl.endCombine != null)
                {
                    tl.endCombine(null, tl.plus, tl.sub, tl.endParam);
                }

                Debug.LogError("combine load e->" + asset.name + "^" + e.ToString());
            }
        }
Ejemplo n.º 10
0
	public Texture(byte[] data, mapType type):base(data) {
		switch (type) {
			case mapType.TYPE_NIGHTFIRE: 
				name = DataReader.readNullTerminatedString(new byte[]{data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7], data[8], data[9], data[10], data[11], data[12], data[13], data[14], data[15], data[16], data[17], data[18], data[19], data[20], data[21], data[22], data[23], data[24], data[25], data[26], data[27], data[28], data[29], data[30], data[31], data[32], data[33], data[34], data[35], data[36], data[37], data[38], data[39], data[40], data[41], data[42], data[43], data[44], data[45], data[46], data[47], data[48], data[49], data[50], data[51], data[52], data[53], data[54], data[55], data[56], data[57], data[58], data[59], data[60], data[61], data[62], data[63]});
				break;
			case mapType.TYPE_QUAKE: 
				name = DataReader.readNullTerminatedString(new byte[]{data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7], data[8], data[9], data[10], data[11], data[12], data[13], data[14], data[15]});
				break;
			case mapType.TYPE_QUAKE2: 
			case mapType.TYPE_SOF: 
			case mapType.TYPE_DAIKATANA: 
				texAxes = new TexInfo(DataReader.readPoint3F(data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7], data[8], data[9], data[10], data[11]), DataReader.readFloat(data[12], data[13], data[14], data[15]), DataReader.readPoint3F(data[16], data[17], data[18], data[19], data[20], data[21], data[22], data[23], data[24], data[25], data[26], data[27]), DataReader.readFloat(data[28], data[29], data[30], data[31]), - 1, - 1);
				flags = new byte[]{data[32], data[33], data[34], data[35]};
				name = DataReader.readNullTerminatedString(new byte[]{data[40], data[41], data[42], data[43], data[44], data[45], data[46], data[47], data[48], data[49], data[50], data[51], data[52], data[53], data[54], data[55], data[56], data[57], data[58], data[59], data[60], data[61], data[62], data[63], data[64], data[65], data[66], data[67], data[68], data[69], data[70], data[71]});
				break;
			case mapType.TYPE_MOHAA: 
				mask = DataReader.readNullTerminatedString(new byte[]{data[76], data[77], data[78], data[79], data[80], data[81], data[82], data[83], data[84], data[85], data[86], data[87], data[88], data[89], data[90], data[91], data[92], data[93], data[94], data[95], data[96], data[97], data[98], data[99], data[100], data[101], data[102], data[103], data[104], data[105], data[106], data[107], data[108], data[109], data[110], data[111], data[112], data[113], data[114], data[115], data[116], data[117], data[118], data[119], data[120], data[121], data[122], data[123], data[124], data[125], data[126], data[127], data[128], data[129], data[130], data[131], data[132], data[133], data[134], data[135], data[136], data[137], data[138], data[139]});
				goto case mapType.TYPE_STEF2;
			case mapType.TYPE_STEF2: 
			case mapType.TYPE_STEF2DEMO: 
			case mapType.TYPE_RAVEN: 
			case mapType.TYPE_QUAKE3: 
			case mapType.TYPE_COD: 
			case mapType.TYPE_COD2: 
			case mapType.TYPE_COD4: 
			case mapType.TYPE_FAKK: 
				name = DataReader.readNullTerminatedString(new byte[]{data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7], data[8], data[9], data[10], data[11], data[12], data[13], data[14], data[15], data[16], data[17], data[18], data[19], data[20], data[21], data[22], data[23], data[24], data[25], data[26], data[27], data[28], data[29], data[30], data[31], data[32], data[33], data[34], data[35], data[36], data[37], data[38], data[39], data[40], data[41], data[42], data[43], data[44], data[45], data[46], data[47], data[48], data[49], data[50], data[51], data[52], data[53], data[54], data[55], data[56], data[57], data[58], data[59], data[60], data[61], data[62], data[63]});
				flags = new byte[]{data[64], data[65], data[66], data[67]};
				contents = new byte[]{data[68], data[69], data[70], data[71]};
				break;
			case mapType.TYPE_SOURCE17: 
			case mapType.TYPE_SOURCE18: 
			case mapType.TYPE_SOURCE19: 
			case mapType.TYPE_SOURCE20: 
			case mapType.TYPE_SOURCE21: 
			case mapType.TYPE_SOURCE22: 
			case mapType.TYPE_SOURCE23: 
			case mapType.TYPE_SOURCE27: 
			case mapType.TYPE_TACTICALINTERVENTION: 
			case mapType.TYPE_VINDICTUS: 
			case mapType.TYPE_DMOMAM: 
				name = DataReader.readString(data);
				break;
			case mapType.TYPE_SIN: 
				texAxes = new TexInfo(DataReader.readPoint3F(data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7], data[8], data[9], data[10], data[11]), DataReader.readFloat(data[12], data[13], data[14], data[15]), DataReader.readPoint3F(data[16], data[17], data[18], data[19], data[20], data[21], data[22], data[23], data[24], data[25], data[26], data[27]), DataReader.readFloat(data[28], data[29], data[30], data[31]), - 1, - 1);
				flags = new byte[]{data[32], data[33], data[34], data[35]};
				name = DataReader.readNullTerminatedString(new byte[]{data[36], data[37], data[38], data[39], data[40], data[41], data[42], data[43], data[44], data[45], data[46], data[47], data[48], data[49], data[50], data[51], data[52], data[53], data[54], data[55], data[56], data[57], data[58], data[59], data[60], data[61], data[62], data[63], data[64], data[65], data[66], data[67], data[68], data[69], data[70], data[71], data[72], data[73], data[74], data[75], data[76], data[77], data[78], data[79], data[80], data[81], data[82], data[83], data[84], data[85], data[86], data[87], data[88], data[89], data[90], data[91], data[92], data[93], data[94], data[95], data[96], data[97], data[98], data[99]});
				break;
		}
	}
        protected override void OnUpdate(DX11RenderContext context)
        {
            //Grab a temp target if enabled

            TexInfo ti = this.rtm.GetRenderTarget(context);

            if (ti.w != this.width || ti.h != this.height || !this.targets.ContainsKey(context) || this.FInAASamplesPerPixel.IsChanged)
            {
                this.width  = ti.w;
                this.height = ti.h;

                this.depthmanager.NeedReset = true;

                if (targets.ContainsKey(context))
                {
                    context.ResourcePool.Unlock(targets[context]);
                }

                if (targetresolve.ContainsKey(context))
                {
                    context.ResourcePool.Unlock(targetresolve[context]);
                }

                int aacount   = Convert.ToInt32(this.FInAASamplesPerPixel[0].Name);
                int aaquality = 0;

                if (aacount > 1)
                {
                    DX11RenderTarget2D temptarget        = context.ResourcePool.LockRenderTarget(this.width, this.height, ti.format, new SampleDescription(aacount, aaquality), this.FInDoMipMaps[0], this.FInMipLevel[0]).Element;
                    DX11RenderTarget2D temptargetresolve = context.ResourcePool.LockRenderTarget(this.width, this.height, ti.format, new SampleDescription(1, 0), this.FInDoMipMaps[0], this.FInMipLevel[0]).Element;

                    targets[context]       = temptarget;
                    targetresolve[context] = temptargetresolve;

                    this.FOutBuffers[0][context]   = temptargetresolve;
                    this.FOutAABuffers[0][context] = temptarget;
                }
                else
                {
                    //Bind both texture as same output
                    DX11RenderTarget2D temptarget = context.ResourcePool.LockRenderTarget(this.width, this.height, ti.format, new SampleDescription(aacount, aaquality), this.FInDoMipMaps[0], this.FInMipLevel[0]).Element;
                    targets[context] = temptarget;

                    this.FOutBuffers[0][context]   = temptarget;
                    this.FOutAABuffers[0][context] = temptarget;
                }
            }
        }
Ejemplo n.º 12
0
    private void LoadTextures(IEnumerable <string> matFilenames)
    {
        var textures = new Dictionary <string, Texture2D[]>();

        foreach (var matFilename in matFilenames)
        {
            if (textures.ContainsKey(matFilename.ToLower()))
            {
                Debug.LogWarning("Texture " + matFilename + " defined twice.");
                continue;
            }
            var mat     = new MAT();
            var matPath = @"3do\mat\" + matFilename;
            if (!_gobManager.Exists(matPath))
            {
                matPath = @"mat\" + matFilename;
            }

            mat.ParseMat(_cmp, _gobManager.GetStream(matPath));
            textures.Add(matFilename.ToLower(), new[] { mat.Textures[0] });
        }

        var rects = Atlas.PackTextures(textures.Values.SelectMany(x => x).ToArray(), 0);

        var rectsOffset = 0;

        foreach (var matFilename in textures.Keys)
        {
            var numTextures = textures[matFilename].Length;
            var subrects    = new Rect[numTextures];

            Array.Copy(rects, rectsOffset, subrects, 0, subrects.Length);

            var sizes = new List <Vector2>();
            foreach (var texture2D in textures[matFilename])
            {
                sizes.Add(new Vector2(texture2D.width, texture2D.height));
            }

            _materialLookup[matFilename] = new TexInfo
            {
                Rects = subrects,
                Sizes = sizes.ToArray()
            };

            rectsOffset += numTextures;
        }
    }
Ejemplo n.º 13
0
        private Dictionary <string, TexInfo> GetOrCreateMaps()
        {
            if (m_texInfoMap == null)
            {
                m_texInfoMap = new Dictionary <string, TexInfo>();
                if (texInfoList != null)
                {
                    foreach (var texInfo in texInfoList)
                    {
                        if (!m_texInfoMap.ContainsKey(texInfo.name))
                        {
                            m_texInfoMap.Add(texInfo.name, texInfo);
                        }
                    }
                }

                m_curTexInfo = CreateDefaultTexInfo();
                m_texInfoMap.Add(m_curTexInfo.name, m_curTexInfo);
            }
            return(m_texInfoMap);
        }
        public List <TexInfo> ReadTexInfo(BinaryReader reader, BspHeader header)
        {
            List <TexInfo> infos = new List <TexInfo>();

            var entry    = header.GetLump(Lumps.TEXTURES);
            int numInfos = entry.Length / 76;

            Debug.Log(numInfos + " Texture Infos");
            reader.BaseStream.Seek(entry.Offset, SeekOrigin.Begin);
            for (int i = 0; i < numInfos; i++)
            {
                var info = new TexInfo();

                float ux = reader.ReadSingle();
                float uy = reader.ReadSingle();
                float uz = reader.ReadSingle();
                info.uAxis   = new Vector3(-ux, uz, -uy);
                info.uOffset = reader.ReadSingle();                // * QUAKE_TO_UNITY_CONVERSION_SCALE; // * scale??
                float vx = reader.ReadSingle();
                float vy = reader.ReadSingle();
                float vz = reader.ReadSingle();
                info.vAxis   = new Vector3(-vx, vz, -vy);
                info.vOffset = reader.ReadSingle();                // * QUAKE_TO_UNITY_CONVERSION_SCALE; // * scale??

                info.flags = reader.ReadUInt32();
                info.value = reader.ReadUInt32();
                info.name  = new string(reader.ReadChars(32));
                int pos = info.name.IndexOf('\0');
                if (pos >= 0)
                {
                    info.name = info.name.Substring(0, pos);
                }
                info.nextTexInfo = reader.ReadUInt32();

                infos.Add(info);
            }

            return(infos);
        }
Ejemplo n.º 15
0
        public string Change(string name)
        {
            var texMaps = GetOrCreateMaps();

            if (texMaps.ContainsKey(name))
            {
                var oldTexInfo = m_curTexInfo;
                var newTexInfo = texMaps[name];

                var smr = gameObject.GetComponent <SkinnedMeshRenderer>();
                if (smr != null)
                {
                    Material[] materials = smr.sharedMaterials;
                    if (materials != null)
                    {
                        MaterialPropertyBlock materialPropertyBlock = new MaterialPropertyBlock();
                        for (int i = 0; i < materials.Length; i++)
                        {
                            materialPropertyBlock.Clear();
                            smr.GetPropertyBlock(materialPropertyBlock, i);

                            materialPropertyBlock.SetTexture("_MainTex", newTexInfo.mainTex);
                            if (newTexInfo.flowTex)
                            {
                                materialPropertyBlock.SetTexture("_FlowTex", newTexInfo.flowTex);
                            }

                            smr.SetPropertyBlock(materialPropertyBlock, i);
                        }

                        m_curTexInfo = newTexInfo;
                        return(oldTexInfo.name);
                    }
                }
            }

            return(m_curTexInfo.name);
        }
	// METHODS
	
	// Attempt to turn the BSP into a .MAP file
	public virtual Entities decompile() {
		DecompilerThread.OnMessage(this, "Decompiling...");
		// In the decompiler, it is not necessary to copy all entities to a new object, since
		// no writing is ever done back to the BSP file.
		mapFile = BSPObject.Entities;
		//int numAreaPortals=0;
		int numTotalItems = 0;
		int onePercent = (int)((BSPObject.Brushes.Count + BSPObject.Entities.Count)/100);
		if(onePercent < 1) {
			onePercent = 1;
		}
		int originalNumEntities = BSPObject.Entities.Count; // Need to keep track of this in this algorithm, since I create more entities on the fly
		for (int i = 0; i < originalNumEntities; i++) {
			// For each entity
			//DecompilerThread.OnMessage(this, "Entity " + i + ": " + mapFile[i]["classname"]);
			// getModelNumber() returns 0 for worldspawn, the *# for brush based entities, and -1 for everything else
			int currentModel = mapFile[i].ModelNumber;
			if (currentModel > - 1) { // If this is still -1 then it's strictly a point-based entity. Move on to the next one.
				Leaf[] leaves = BSPObject.getLeavesInModel(currentModel);
				int numLeaves = leaves.Length;
				bool[] brushesUsed = new bool[BSPObject.Brushes.Count]; // Keep a list of brushes already in the model, since sometimes the leaves lump references one brush several times
				numBrshs = 0; // Reset the brush count for each entity
				for (int j = 0; j < numLeaves; j++) {
					// For each leaf in the bunch
					Leaf currentLeaf = leaves[j];
					int firstMarkBrushIndex = currentLeaf.FirstMarkBrush;
					int numBrushIndices = currentLeaf.NumMarkBrushes;
					if (numBrushIndices > 0) {
						// A lot of leaves reference no brushes. If this is one, this iteration of the j loop is finished
						for (int k = 0; k < numBrushIndices; k++) {
							// For each brush referenced
							long currentBrushIndex = BSPObject.MarkBrushes[firstMarkBrushIndex + k];
							if (!brushesUsed[(int) currentBrushIndex]) {
								// If the current brush has NOT been used in this entity
								//Console.Write("Brush " + numBrshs);
								brushesUsed[(int) currentBrushIndex] = true;
								Brush brush = BSPObject.Brushes[(int) currentBrushIndex];
								decompileBrush(brush, i); // Decompile the brush
								numBrshs++;
								numTotalItems++;
								if(numTotalItems%onePercent == 0) {
									parent.OnProgress(this, numTotalItems/(double)(BSPObject.Brushes.Count + BSPObject.Entities.Count));
								}
							}
						}
					}
				}
			}
			numTotalItems++; // This entity
			if(numTotalItems%onePercent == 0) {
				parent.OnProgress(this, numTotalItems/(double)(BSPObject.Brushes.Count + BSPObject.Entities.Count));
			}
		}
		// Find displacement faces and generate brushes for them
		for (int i = 0; i < BSPObject.Faces.Count; i++) {
			Face face = BSPObject.Faces[i];
			if (face.Displacement > - 1)
			{
				SourceDispInfo disp = BSPObject.DispInfos[face.Displacement];
				TexInfo currentTexInfo;
				if (face.Texture > - 1)
				{
					currentTexInfo = BSPObject.TexInfo[face.Texture];
				}
				else
				{
					Vector3D[] axes = TexInfo.textureAxisFromPlane(BSPObject.Planes[face.Plane]);
					currentTexInfo = new TexInfo(axes[0], 0, axes[1], 0, 0, BSPObject.findTexDataWithTexture("tools/toolsclip"));
				}
				SourceTexData currentTexData = BSPObject.TexDatas[currentTexInfo.Texture];
				string texture = BSPObject.Textures.getTextureAtOffset((uint)BSPObject.TexTable[currentTexData.StringTableIndex]);
				double[] textureU = new double[3];
				double[] textureV = new double[3];
				// Get the lengths of the axis vectors
				double SAxisLength = System.Math.Sqrt(System.Math.Pow((double) currentTexInfo.SAxis.X, 2) + System.Math.Pow((double) currentTexInfo.SAxis.Y, 2) + System.Math.Pow((double) currentTexInfo.SAxis.Z, 2));
				double TAxisLength = System.Math.Sqrt(System.Math.Pow((double) currentTexInfo.TAxis.X, 2) + System.Math.Pow((double) currentTexInfo.TAxis.Y, 2) + System.Math.Pow((double) currentTexInfo.TAxis.Z, 2));
				// In compiled maps, shorter vectors=longer textures and vice versa. This will convert their lengths back to 1. We'll use the actual scale values for length.
				double texScaleU = (1 / SAxisLength); // Let's use these values using the lengths of the U and V axes we found above.
				double texScaleV = (1 / TAxisLength);
				textureU[0] = ((double) currentTexInfo.SAxis.X / SAxisLength);
				textureU[1] = ((double) currentTexInfo.SAxis.Y / SAxisLength);
				textureU[2] = ((double) currentTexInfo.SAxis.Z / SAxisLength);
				//UPGRADE_WARNING: Data types in Visual C# might be different.  Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextSettingsIndex'&keyword='jlca1042'"
				double textureShiftU = (double) currentTexInfo.SShift;
				textureV[0] = ((double) currentTexInfo.TAxis.X / TAxisLength);
				textureV[1] = ((double) currentTexInfo.TAxis.Y / TAxisLength);
				textureV[2] = ((double) currentTexInfo.TAxis.Z / TAxisLength);
				//UPGRADE_WARNING: Data types in Visual C# might be different.  Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextSettingsIndex'&keyword='jlca1042'"
				double textureShiftV = (double) currentTexInfo.TShift;
				
				if (face.NumEdges != 4)
				{
					DecompilerThread.OnMessage(this, "Displacement face with " + face.NumEdges + " edges!");
				}
				
				// Turn vertices and edges into arrays of vectors
				Vector3D[] froms = new Vector3D[face.NumEdges];
				Vector3D[] tos = new Vector3D[face.NumEdges];
				for (int j = 0; j < face.NumEdges; j++)
				{
					if (BSPObject.SurfEdges[face.FirstEdge + j] > 0)
					{
						froms[j] = BSPObject.Vertices[BSPObject.Edges[(int)BSPObject.SurfEdges[face.FirstEdge + j]].FirstVertex].Vector;
						tos[j] = BSPObject.Vertices[BSPObject.Edges[(int)BSPObject.SurfEdges[face.FirstEdge + j]].SecondVertex].Vector;
					}
					else
					{
						tos[j] = BSPObject.Vertices[BSPObject.Edges[(int) BSPObject.SurfEdges[face.FirstEdge + j] * (- 1)].FirstVertex].Vector;
						froms[j] = BSPObject.Vertices[BSPObject.Edges[(int) BSPObject.SurfEdges[face.FirstEdge + j] * (- 1)].SecondVertex].Vector;
					}
				}
				
				MAPBrush displacementBrush = MAPBrush.createBrushFromWind(froms, tos, texture, "TOOLS/TOOLSNODRAW", currentTexInfo);
				
				MAPDisplacement mapdisp = new MAPDisplacement(disp, BSPObject.DispVerts.getVertsInDisp(disp.DispVertStart, disp.Power));
				displacementBrush[0].Displacement = mapdisp;
				mapFile[0].Brushes.Add(displacementBrush);
			}
		}
		for (int i = 0; i < BSPObject.StaticProps.Count; i++)
		{
			Entity newStaticProp = new Entity("prop_static");
			SourceStaticProp currentProp = BSPObject.StaticProps[i];
			newStaticProp["model"] = BSPObject.StaticProps.Dictionary[currentProp.DictionaryEntry];
			newStaticProp["skin"] = currentProp.Skin + "";
			newStaticProp["origin"] = currentProp.Origin.X + " " + currentProp.Origin.Y + " " + currentProp.Origin.Z;
			newStaticProp["angles"] = currentProp.Angles.X + " " + currentProp.Angles.Y + " " + currentProp.Angles.Z;
			newStaticProp["solid"] = currentProp.Solidity + "";
			newStaticProp["fademindist"] = currentProp.MinFadeDist + "";
			newStaticProp["fademaxdist"] = currentProp.MaxFadeDist + "";
			newStaticProp["fadescale"] = currentProp.ForcedFadeScale + "";
			if (currentProp.Targetname != null)
			{
				newStaticProp["targetname"] = currentProp.Targetname;
			}
			mapFile.Add(newStaticProp);
		}
		for (int i = 0; i < BSPObject.Cubemaps.Count; i++)
		{
			Entity newCubemap = new Entity("env_cubemap");
			SourceCubemap currentCube = BSPObject.Cubemaps[i];
			newCubemap["origin"] = currentCube.Origin.X + " " + currentCube.Origin.Y + " " + currentCube.Origin.Z;
			newCubemap["cubemapsize"] = currentCube.Size + "";
			mapFile.Add(newCubemap);
		}
		if (!Settings.skipPlaneFlip)
		{
			DecompilerThread.OnMessage(this, "Num simple corrected brushes: " + numSimpleCorrects);
			DecompilerThread.OnMessage(this, "Num advanced corrected brushes: " + numAdvancedCorrects);
			DecompilerThread.OnMessage(this, "Num good brushes: " + numGoodBrushes);
		}
		parent.OnProgress(this, 1.0);
		return mapFile;
	}
	// -decompileBrush38(Brush, int, boolean)
	// Decompiles the Brush and adds it to entitiy #currentEntity as .MAP data.
	private void decompileBrush(Brush brush, int currentEntity)
	{
		Vector3D origin = mapFile[currentEntity].Origin;
		int firstSide = brush.FirstSide;
		int numSides = brush.NumSides;
		MAPBrushSide[] brushSides = new MAPBrushSide[numSides];
		bool isDetail = false;
		if (currentEntity == 0 && !Settings.noDetail && (brush.Contents[3] & ((sbyte) 1 << 3)) != 0)
		{
			isDetail = true;
		}
		MAPBrush mapBrush = new MAPBrush(numBrshs, currentEntity, isDetail);
		if (currentEntity == 0 && !Settings.noWater && (brush.Contents[0] & ((sbyte) 1 << 5)) != 0)
		{
			mapBrush.Water = true;
		}
		//DecompilerThread.OnMessage(this, ": " + numSides + " sides, detail: " + isDetail);
		for (int i = 0; i < numSides; i++)
		{
			// For each side of the brush
			BrushSide currentSide = BSPObject.BrushSides[firstSide + i];
			if (currentSide.isBevel() == 0)
			{
				// Bevel sides are evil
				Vector3D[] plane = new Vector3D[3]; // Three points define a plane. All I have to do is find three points on that plane.
				Plane currentPlane = BSPObject.Planes[currentSide.Plane]; // To find those three points, I must extrapolate from planes until I find a way to associate faces with brushes
				bool isDuplicate = false; /* TODO: We sure don't want duplicate planes (though this is already handled by the MAPBrush class). Make sure neither checked side is bevel.
				for(int j=i+1;j<numSides;j++) { // For each subsequent side of the brush
				if(currentPlane.equals(BSPObject.Planes.getPlane(BSPObject.getBrushSides()[firstSide+j).getPlane()))) {
				DecompilerThread.OnMessage(this, "WARNING: Duplicate planes in a brush, sides "+i+" and "+j,Settings.VERBOSITY_WARNINGS);
				isDuplicate=true;
				}
				}*/
				if (!isDuplicate)
				{
					TexInfo currentTexInfo = null;
					string texture = "tools/toolsclip";
					if (currentSide.Texture > - 1)
					{
						currentTexInfo = BSPObject.TexInfo[currentSide.Texture];
					}
					else
					{
						int dataIndex = BSPObject.findTexDataWithTexture("tools/toolsclip");
						if (dataIndex >= 0)
						{
							currentTexInfo = new TexInfo(new Vector3D(0, 0, 0), 0, new Vector3D(0, 0, 0), 0, 0, dataIndex);
						}
					}
					if (currentTexInfo != null)
					{
						SourceTexData currentTexData;
						if (currentTexInfo.Texture >= 0)
						{
							// I've only found one case where this is a problem: c2a3a in HL Source. Don't know why.
							currentTexData = BSPObject.TexDatas[currentTexInfo.Texture];
							texture = BSPObject.Textures.getTextureAtOffset((uint)BSPObject.TexTable[currentTexData.StringTableIndex]);
						}
						else
						{
							texture = "tools/toolsskip";
						}
					}
					double[] textureU = new double[3];
					double[] textureV = new double[3];
					double textureShiftU = 0;
					double textureShiftV = 0;
					double texScaleU = 1;
					double texScaleV = 1;
					// Get the lengths of the axis vectors
					if ((texture.Length > 6 && texture.Substring(0, (6) - (0)).ToUpper().Equals("tools/".ToUpper())) || currentTexInfo == null)
					{
						// Tools textured faces do not maintain their own texture axes. Therefore, an arbitrary axis is
						// used in the compiled map. When decompiled, these axes might smear the texture on the face. Fix that.
						Vector3D[] axes = TexInfo.textureAxisFromPlane(currentPlane);
						textureU = axes[0].Point;
						textureV = axes[1].Point;
					}
					else
					{
						double SAxisLength = System.Math.Sqrt(System.Math.Pow((double) currentTexInfo.SAxis.X, 2) + System.Math.Pow((double) currentTexInfo.SAxis.Y, 2) + System.Math.Pow((double) currentTexInfo.SAxis.Z, 2));
						double TAxisLength = System.Math.Sqrt(System.Math.Pow((double) currentTexInfo.TAxis.X, 2) + System.Math.Pow((double) currentTexInfo.TAxis.Y, 2) + System.Math.Pow((double) currentTexInfo.TAxis.Z, 2));
						// In compiled maps, shorter vectors=longer textures and vice versa. This will convert their lengths back to 1. We'll use the actual scale values for length.
						texScaleU = (1 / SAxisLength); // Let's use these values using the lengths of the U and V axes we found above.
						texScaleV = (1 / TAxisLength);
						textureU[0] = ((double) currentTexInfo.SAxis.X / SAxisLength);
						textureU[1] = ((double) currentTexInfo.SAxis.Y / SAxisLength);
						textureU[2] = ((double) currentTexInfo.SAxis.Z / SAxisLength);
						double originShiftU = (((double) currentTexInfo.SAxis.X / SAxisLength) * origin[X] + ((double) currentTexInfo.SAxis.Y / SAxisLength) * origin[Y] + ((double) currentTexInfo.SAxis.Z / SAxisLength) * origin[Z]) / texScaleU;
						//UPGRADE_WARNING: Data types in Visual C# might be different.  Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextSettingsIndex'&keyword='jlca1042'"
						textureShiftU = (double) currentTexInfo.SShift - originShiftU;
						textureV[0] = ((double) currentTexInfo.TAxis.X / TAxisLength);
						textureV[1] = ((double) currentTexInfo.TAxis.Y / TAxisLength);
						textureV[2] = ((double) currentTexInfo.TAxis.Z / TAxisLength);
						double originShiftV = (((double) currentTexInfo.TAxis.X / TAxisLength) * origin[X] + ((double) currentTexInfo.TAxis.Y / TAxisLength) * origin[Y] + ((double) currentTexInfo.TAxis.Z / TAxisLength) * origin[Z]) / texScaleV;
						//UPGRADE_WARNING: Data types in Visual C# might be different.  Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextSettingsIndex'&keyword='jlca1042'"
						textureShiftV = (double) currentTexInfo.TShift - originShiftV;
					}
					float texRot = 0; // In compiled maps this is calculated into the U and V axes, so set it to 0 until I can figure out a good way to determine a better value.
					int flags = 0; // Set this to 0 until we can somehow associate faces with brushes
					string material = "wld_lightmap"; // Since materials are a NightFire only thing, set this to a good default
					double lgtScale = 16; // These values are impossible to get from a compiled map since they
					double lgtRot = 0; // are used by RAD for generating lightmaps, then are discarded, I believe.
					brushSides[i] = new MAPBrushSide(currentPlane, texture, textureU, textureShiftU, textureV, textureShiftV, texRot, texScaleU, texScaleV, flags, material, lgtScale, lgtRot);
					mapBrush.add(brushSides[i]);
				}
			}
		}
		
		if (!Settings.skipPlaneFlip)
		{
			if (mapBrush.hasBadSide())
			{
				// If there's a side that might be backward
				if (mapBrush.hasGoodSide())
				{
					// If there's a side that is forward
					mapBrush = MAPBrush.SimpleCorrectPlanes(mapBrush);
					numSimpleCorrects++;
					if (Settings.calcVerts)
					{
						// This is performed in advancedcorrect, so don't use it if that's happening
						try
						{
							mapBrush = MAPBrush.CalcBrushVertices(mapBrush);
						}
						catch (System.NullReferenceException)
						{
							DecompilerThread.OnMessage(this, "WARNING: Brush vertex calculation failed on entity " + mapBrush.Entnum + " brush " + mapBrush.Brushnum + "");
						}
					}
				}
				else
				{
					// If no forward side exists
					try
					{
						mapBrush = MAPBrush.AdvancedCorrectPlanes(mapBrush);
						numAdvancedCorrects++;
					}
					catch (System.ArithmeticException)
					{
						DecompilerThread.OnMessage(this, "WARNING: Plane correct returned 0 triangles for entity " + mapBrush.Entnum + " brush " + mapBrush.Brushnum + "");
					}
				}
			}
			else
			{
				numGoodBrushes++;
			}
		}
		else
		{
			if (Settings.calcVerts)
			{
				// This is performed in advancedcorrect, so don't use it if that's happening
				try
				{
					mapBrush = MAPBrush.CalcBrushVertices(mapBrush);
				}
				catch (System.NullReferenceException)
				{
					DecompilerThread.OnMessage(this, "WARNING: Brush vertex calculation failed on entity " + mapBrush.Entnum + " brush " + mapBrush.Brushnum + "");
				}
			}
		}
		
		// This adds the brush we've been finding and creating to
		// the current entity as an attribute. The way I've coded
		// this whole program and the entities parser, this shouldn't
		// cause any issues at all.
		if (Settings.brushesToWorld)
		{
			mapBrush.Water = false;
			mapFile[0].Brushes.Add(mapBrush);
		}
		else
		{
			mapFile[currentEntity].Brushes.Add(mapBrush);
		}
	}
Ejemplo n.º 18
0
	// The inspiration for this is the BSPSource source code. It's not a direct copy but does essentially
	// the same thing as the algorithm to "create a prism back", and isn't as neatly written.
	public static MAPBrush createBrushFromWind(Vector3D[] froms, Vector3D[] tos, string texture, string backtex, TexInfo scaling)
	{
		Vector3D[] planepts = new Vector3D[3];
		MAPBrushSide[] sides = new MAPBrushSide[froms.Length + 2]; // Each edge, plus a front and back side
		planepts[0] = froms[0];
		planepts[1] = tos[0];
		planepts[2] = tos[1];
		Plane plane = new Plane(planepts);
		Vector3D reverseNormal = plane.Normal;
		sides[0] = new MAPBrushSide(planepts, texture, scaling.SAxis.Point, scaling.SShift, scaling.TAxis.Point, scaling.TShift, 0, 1, 1, 0, "wld_lightmap", 16, 0);
		
		Vector3D[] backplanepts = new Vector3D[3];
		backplanepts[0] = froms[0]-(reverseNormal);
		backplanepts[1] = tos[1]-(reverseNormal);
		backplanepts[2] = tos[0]-(reverseNormal);
		Plane backplane = new Plane(backplanepts);
		Vector3D[] backaxes = TexInfo.textureAxisFromPlane(backplane);
		sides[1] = new MAPBrushSide(backplane, backtex, backaxes[0].Point, 0, backaxes[1].Point, 0, 0, 1, 1, 0, "wld_lightmap", 16, 0);
		
		for (int i = 0; i < froms.Length; i++)
		{
			// each edge
			Vector3D[] sideplanepts = new Vector3D[3];
			sideplanepts[0] = froms[i];
			sideplanepts[1] = tos[i];
			sideplanepts[2] = froms[i]+(reverseNormal);
			Plane sideplane = new Plane(sideplanepts);
			Vector3D[] sideaxes = TexInfo.textureAxisFromPlane(sideplane);
			sides[i + 2] = new MAPBrushSide(sideplane, backtex, sideaxes[0].Point, 0, sideaxes[1].Point, 0, 0, 1, 1, 0, "wld_lightmap", 16, 0);
		}
		
		return new MAPBrush(sides, 0, 0, false);
	}
Ejemplo n.º 19
0
    // -decompileBrush(Brush, int, boolean)
    // Decompiles the Brush and adds it to entitiy #currentEntity as .MAP data.
    private void  decompileBrush(Brush brush, int currentEntity)
    {
        Vector3D origin    = mapFile[currentEntity].Origin;
        int      firstSide = brush.FirstSide;
        int      numSides  = brush.NumSides;

        MAPBrushSide[] brushSides = new MAPBrushSide[0];
        bool           isDetail   = false;

        if (!Settings.noDetail && (brush.Contents[1] & ((sbyte)1 << 1)) != 0)
        {
            isDetail = true;
        }
        MAPBrush mapBrush     = new MAPBrush(numBrshs, currentEntity, isDetail);
        int      numRealFaces = 0;

        Plane[] brushPlanes = new Plane[0];
        //DecompilerThread.OnMessage(this, ": " + numSides + " sides");
        if (mapFile[currentEntity]["classname"] == "func_water")
        {
            mapBrush.Water = true;
        }
        for (int l = 0; l < numSides; l++)
        {
            // For each side of the brush
            BrushSide currentSide = BSPObject.BrushSides[firstSide + l];
            Face      currentFace = BSPObject.Faces[currentSide.Face];        // To find those three points, I can use vertices referenced by faces.
            string    texture     = BSPObject.Textures[currentFace.Texture].Name;
            if ((currentFace.Flags & 0x00000100) == 0)
            {
                // Surfaceflags 512 + 256 + 32 are set only by the compiler, on faces that need to be thrown out.
                if (!texture.ToUpper().Equals("special/clip".ToUpper()) && !texture.ToUpper().Equals("special/playerclip".ToUpper()) && !texture.ToUpper().Equals("special/enemyclip".ToUpper()))
                {
                    if (Settings.replaceWithNull && ((currentFace.Flags & 0x00000200) != 0) && !texture.ToUpper().Equals("special/trigger".ToUpper()))
                    {
                        texture           = "special/null";
                        currentFace.Flags = 0;
                    }
                }
                int   firstVertex = currentFace.FirstVertex;
                int   numVertices = currentFace.NumVertices;
                Plane currentPlane;
                try
                {
                    // I've only ever come across this error once or twice, but something causes it very rarely
                    currentPlane = BSPObject.Planes[currentSide.Plane];
                }
                catch (System.IndexOutOfRangeException)
                {
                    try
                    {
                        // So try to get the plane index from somewhere else
                        currentPlane = BSPObject.Planes[currentFace.Plane];
                    }
                    catch (System.IndexOutOfRangeException f)
                    {
                        // If that fails, BS something
                        DecompilerThread.OnMessage(this, "WARNING: BSP has error, references nonexistant plane " + currentSide.Plane + ", bad side " + (l) + " of brush " + numBrshs + " Entity " + currentEntity);
                        currentPlane = new Plane((double)1, (double)0, (double)0, (double)0);
                    }
                }
                Vector3D[] triangle     = new Vector3D[0];             // Three points define a plane. All I have to do is find three points on that plane.
                bool       pointsWorked = false;
                if (numVertices != 0 && !Settings.planarDecomp)
                {
                    // If the face actually references a set of vertices
                    triangle = new Vector3D[3];
                    double currentHighest = 0.0;
                    // Find the combination of three vertices which gives the greatest area
                    for (int p1 = 0; p1 < numVertices - 2; p1++)
                    {
                        for (int p2 = p1 + 1; p2 < numVertices - 1; p2++)
                        {
                            for (int p3 = p2 + 1; p3 < numVertices; p3++)
                            {
                                double currentArea = Vector3D.SqrTriangleArea(BSPObject.Vertices[firstVertex + p1].Vector, BSPObject.Vertices[firstVertex + p2].Vector, BSPObject.Vertices[firstVertex + p3].Vector);
                                if (currentArea > Settings.precision * Settings.precision * 4.0)                                  // Three collinear points will generate an area of 0 or almost 0
                                {
                                    pointsWorked = true;
                                    if (currentArea > currentHighest)
                                    {
                                        currentHighest = currentArea;
                                        triangle[0]    = BSPObject.Vertices[firstVertex + p1].Vector;
                                        triangle[1]    = BSPObject.Vertices[firstVertex + p2].Vector;
                                        triangle[2]    = BSPObject.Vertices[firstVertex + p3].Vector;
                                    }
                                }
                            }
                        }
                    }
                }
                double[] textureU       = new double[3];
                double[] textureV       = new double[3];
                TexInfo  currentTexInfo = BSPObject.TexInfo[currentFace.TextureScale];
                // Get the lengths of the axis vectors
                double SAxisLength = System.Math.Sqrt(System.Math.Pow((double)currentTexInfo.SAxis.X, 2) + System.Math.Pow((double)currentTexInfo.SAxis.Y, 2) + System.Math.Pow((double)currentTexInfo.SAxis.Z, 2));
                double TAxisLength = System.Math.Sqrt(System.Math.Pow((double)currentTexInfo.TAxis.X, 2) + System.Math.Pow((double)currentTexInfo.TAxis.Y, 2) + System.Math.Pow((double)currentTexInfo.TAxis.Z, 2));
                // In compiled maps, shorter vectors=longer textures and vice versa. This will convert their lengths back to 1. We'll use the actual scale values for length.
                double texScaleU = (1 / SAxisLength);                 // Let's use these values using the lengths of the U and V axes we found above.
                double texScaleV = (1 / TAxisLength);
                textureU[0] = ((double)currentTexInfo.SAxis.X / SAxisLength);
                textureU[1] = ((double)currentTexInfo.SAxis.Y / SAxisLength);
                textureU[2] = ((double)currentTexInfo.SAxis.Z / SAxisLength);
                double originShiftU  = (textureU[0] * origin[X] + textureU[1] * origin[Y] + textureU[2] * origin[Z]) / texScaleU;
                double textureUhiftU = (double)currentTexInfo.SShift - originShiftU;
                textureV[0] = ((double)currentTexInfo.TAxis.X / TAxisLength);
                textureV[1] = ((double)currentTexInfo.TAxis.Y / TAxisLength);
                textureV[2] = ((double)currentTexInfo.TAxis.Z / TAxisLength);
                double originShiftV  = (textureV[0] * origin[X] + textureV[1] * origin[Y] + textureV[2] * origin[Z]) / texScaleV;
                double textureUhiftV = (double)currentTexInfo.TShift - originShiftV;
                float  texRot        = 0;         // In compiled maps this is calculated into the U and V axes, so set it to 0 until I can figure out a good way to determine a better value.
                string material;
                try {
                    material = BSPObject.Materials[currentFace.Material].Name;
                } catch (System.IndexOutOfRangeException) {
                    // In case the BSP has some strange error making it reference nonexistant materials
                    DecompilerThread.OnMessage(this, "WARNING: Map referenced nonexistant material #" + currentFace.Material + ", using wld_lightmap instead!");
                    material = "wld_lightmap";
                }
                double         lgtScale = 16;      // These values are impossible to get from a compiled map since they
                double         lgtRot   = 0;       // are used by RAD for generating lightmaps, then are discarded, I believe.
                MAPBrushSide[] newList  = new MAPBrushSide[brushSides.Length + 1];
                for (int i = 0; i < brushSides.Length; i++)
                {
                    newList[i] = brushSides[i];
                }
                if (Settings.noFaceFlags)
                {
                    currentFace.Flags = 0;
                }
                if (pointsWorked)
                {
                    newList[brushSides.Length] = new MAPBrushSide(currentPlane, triangle, texture, textureU, textureUhiftU, textureV, textureUhiftV, texRot, texScaleU, texScaleV, currentFace.Flags, material, lgtScale, lgtRot);
                }
                else
                {
                    newList[brushSides.Length] = new MAPBrushSide(currentPlane, texture, textureU, textureUhiftU, textureV, textureUhiftV, texRot, texScaleU, texScaleV, currentFace.Flags, material, lgtScale, lgtRot);
                }
                brushSides = newList;
                numRealFaces++;
            }
        }

        for (int i = 0; i < brushSides.Length; i++)
        {
            mapBrush.add(brushSides[i]);
        }

        brushPlanes = new Plane[mapBrush.NumSides];
        for (int i = 0; i < brushPlanes.Length; i++)
        {
            brushPlanes[i] = mapBrush[i].Plane;
        }

        if (!Settings.skipPlaneFlip)
        {
            if (mapBrush.hasBadSide())
            {
                // If there's a side that might be backward
                if (mapBrush.hasGoodSide())
                {
                    // If there's a side that is forward
                    mapBrush = MAPBrush.SimpleCorrectPlanes(mapBrush);
                    numSimpleCorrects++;
                    if (Settings.calcVerts)
                    {
                        // This is performed in advancedcorrect, so don't use it if that's happening
                        try
                        {
                            mapBrush = MAPBrush.CalcBrushVertices(mapBrush);
                        }
                        catch (System.NullReferenceException)
                        {
                            DecompilerThread.OnMessage(this, "WARNING: Brush vertex calculation failed on entity " + mapBrush.Entnum + " brush " + mapBrush.Brushnum + "");
                        }
                    }
                }
                else
                {
                    // If no forward side exists
                    try
                    {
                        mapBrush = MAPBrush.AdvancedCorrectPlanes(mapBrush);
                        numAdvancedCorrects++;
                    }
                    catch (System.ArithmeticException)
                    {
                        DecompilerThread.OnMessage(this, "WARNING: Plane correct returned 0 triangles for entity " + mapBrush.Entnum + " brush " + mapBrush.Brushnum + "");
                    }
                }
            }
            else
            {
                numGoodBrushes++;
            }
        }
        else
        {
            if (Settings.calcVerts)
            {
                // This is performed in advancedcorrect, so don't use it if that's happening
                try
                {
                    mapBrush = MAPBrush.CalcBrushVertices(mapBrush);
                }
                catch (System.NullReferenceException)
                {
                    DecompilerThread.OnMessage(this, "WARNING: Brush vertex calculation failed on entity " + mapBrush.Entnum + " brush " + mapBrush.Brushnum + "");
                }
            }
        }

        // This adds the brush we've been finding and creating to
        // the current entity as an attribute. The way I've coded
        // this whole program and the entities parser, this shouldn't
        // cause any issues at all.
        if (Settings.brushesToWorld)
        {
            mapBrush.Water = false;
            mapFile[0].Brushes.Add(mapBrush);
        }
        else
        {
            mapFile[currentEntity].Brushes.Add(mapBrush);
        }
    }
Ejemplo n.º 20
0
 private string brushSideToString(MAPBrushSide inputData)
 {
     try
     {
         Vector3D[] triangle      = inputData.Triangle;
         string     texture       = inputData.Texture;
         Vector3D   textureS      = inputData.TextureS;
         Vector3D   textureT      = inputData.TextureT;
         double     textureShiftS = inputData.TextureShiftS;
         double     textureShiftT = inputData.TextureShiftT;
         float      texRot        = inputData.TexRot;
         double     texScaleX     = inputData.TexScaleX;
         double     texScaleY     = inputData.TexScaleY;
         int        flags         = inputData.Flags;
         string     material      = inputData.Material;
         double     lgtScale      = inputData.LgtScale;
         double     lgtRot        = inputData.LgtRot;
         if (Double.IsInfinity(texScaleX) || Double.IsNaN(texScaleX))
         {
             texScaleX = 1;
         }
         if (Double.IsInfinity(texScaleY) || Double.IsNaN(texScaleY))
         {
             texScaleY = 1;
         }
         if (Double.IsInfinity(textureShiftS) || Double.IsNaN(textureShiftS))
         {
             textureShiftS = 0;
         }
         if (Double.IsInfinity(textureShiftT) || Double.IsNaN(textureShiftT))
         {
             textureShiftT = 0;
         }
         if (Double.IsInfinity(textureS.X) || Double.IsNaN(textureS.X) || Double.IsInfinity(textureS.Y) || Double.IsNaN(textureS.Y) || Double.IsInfinity(textureS.Z) || Double.IsNaN(textureS.Z))
         {
             textureS = TexInfo.textureAxisFromPlane(inputData.Plane)[0];
         }
         if (Double.IsInfinity(textureT.X) || Double.IsNaN(textureT.X) || Double.IsInfinity(textureT.Y) || Double.IsNaN(textureT.Y) || Double.IsInfinity(textureT.Z) || Double.IsNaN(textureT.Z))
         {
             textureT = TexInfo.textureAxisFromPlane(inputData.Plane)[1];
         }
         if (Settings.roundNums)
         {
             return("( " + Math.Round(triangle[0].X, 6, MidpointRounding.AwayFromZero) + " " + Math.Round(triangle[0].Y, 6, MidpointRounding.AwayFromZero) + " " + Math.Round(triangle[0].Z, 6, MidpointRounding.AwayFromZero) + " ) " +
                    "( " + Math.Round(triangle[1].X, 6, MidpointRounding.AwayFromZero) + " " + Math.Round(triangle[1].Y, 6, MidpointRounding.AwayFromZero) + " " + Math.Round(triangle[1].Z, 6, MidpointRounding.AwayFromZero) + " ) " +
                    "( " + Math.Round(triangle[2].X, 6, MidpointRounding.AwayFromZero) + " " + Math.Round(triangle[2].Y, 6, MidpointRounding.AwayFromZero) + " " + Math.Round(triangle[2].Z, 6, MidpointRounding.AwayFromZero) + " ) " +
                    texture +
                    " [ " + Math.Round(textureS.X, 6, MidpointRounding.AwayFromZero) + " " + Math.Round(textureS.Y, 6, MidpointRounding.AwayFromZero) + " " + Math.Round(textureS.Z, 6, MidpointRounding.AwayFromZero) + " " + Math.Round(textureShiftS, MidpointRounding.AwayFromZero) + " ]" +
                    " [ " + Math.Round(textureT.X, 6, MidpointRounding.AwayFromZero) + " " + Math.Round(textureT.Y, 6, MidpointRounding.AwayFromZero) + " " + Math.Round(textureT.Z, 6, MidpointRounding.AwayFromZero) + " " + Math.Round(textureShiftT, MidpointRounding.AwayFromZero) + " ] " +
                    Math.Round(texRot, 4, MidpointRounding.AwayFromZero) + " " + Math.Round(texScaleX, 4, MidpointRounding.AwayFromZero) + " " + Math.Round(texScaleY, 4, MidpointRounding.AwayFromZero) + " " + flags + " " + material + " [ " + Math.Round(lgtScale, 4, MidpointRounding.AwayFromZero) + " " + Math.Round(lgtRot, 4, MidpointRounding.AwayFromZero) + " ]");
         }
         else
         {
             return("( " + triangle[0].X + " " + triangle[0].Y + " " + triangle[0].Z + " ) " + "( " + triangle[1].X + " " + triangle[1].Y + " " + triangle[1].Z + " ) " + "( " + triangle[2].X + " " + triangle[2].Y + " " + triangle[2].Z + " ) " + texture + " [ " + textureS.X + " " + textureS.Y + " " + textureS.Z + " " + textureShiftS + " ]" + " [ " + textureT.X + " " + textureT.Y + " " + textureT.Z + " " + textureShiftT + " ] " + texRot + " " + texScaleX + " " + texScaleY + " " + flags + " " + material + " [ " + lgtScale + " " + lgtRot + " ]");
         }
     }
     catch (System.NullReferenceException)
     {
         Console.WriteLine("WARNING: Side with bad data! Not exported!");
         return("");
     }
 }
 private string brushSideToString(MAPBrushSide inputData, bool isDetail)
 {
     try {
         Vector3D[] triangle      = inputData.Triangle;
         string     texture       = inputData.Texture;
         Vector3D   textureS      = inputData.TextureS;
         Vector3D   textureT      = inputData.TextureT;
         double     textureShiftS = inputData.TextureShiftS;
         double     textureShiftT = inputData.TextureShiftT;
         float      texRot        = inputData.TexRot;
         double     texScaleX     = inputData.TexScaleX;
         double     texScaleY     = inputData.TexScaleY;
         int        flags         = inputData.Flags;
         string     material      = inputData.Material;
         double     lgtScale      = inputData.LgtScale;
         double     lgtRot        = inputData.LgtRot;
         string     temp          = "";
         // Correct textures here
         try
         {
             if (texture.Substring(0, (9) - (0)).ToUpper().Equals("textures/".ToUpper()))
             {
                 texture = texture.Substring(9);
             }
         }
         catch (System.ArgumentOutOfRangeException)
         {
             ;
         }
         if (BSPVersion == mapType.TYPE_NIGHTFIRE || BSPVersion == mapType.TYPE_DOOM || BSPVersion == mapType.TYPE_HEXEN)
         {
             if (texture.ToUpper().Equals("special/nodraw".ToUpper()) || texture.ToUpper().Equals("special/null".ToUpper()))
             {
                 texture = "common/nodraw";
             }
             else
             {
                 if (texture.ToUpper().Equals("special/clip".ToUpper()))
                 {
                     texture = "common/clip";
                 }
                 else
                 {
                     if (texture.ToUpper().Equals("special/sky".ToUpper()))
                     {
                         texture = "common/skyportal";
                     }
                     else
                     {
                         if (texture.ToUpper().Equals("special/trigger".ToUpper()))
                         {
                             texture = "common/trigger";
                         }
                         else
                         {
                             if (texture.ToUpper().Equals("special/playerclip".ToUpper()))
                             {
                                 texture = "common/playerclip";
                             }
                             else
                             {
                                 if (texture.ToUpper().Equals("special/npcclip".ToUpper()) || texture.ToUpper().Equals("special/enemyclip".ToUpper()))
                                 {
                                     texture = "common/tankclip";
                                 }
                             }
                         }
                     }
                 }
             }
         }
         else
         {
             if (BSPVersion == mapType.TYPE_QUAKE2)
             {
                 try
                 {
                     if (texture.ToUpper().Equals("special/hint".ToUpper()))
                     {
                         texture = "common/hint";
                     }
                     else
                     {
                         if (texture.ToUpper().Equals("special/skip".ToUpper()))
                         {
                             texture = "common/skip";
                         }
                         else
                         {
                             if (texture.ToUpper().Equals("special/sky".ToUpper()))
                             {
                                 texture = "common/skyportal";
                             }
                             else
                             {
                                 if (texture.Substring(texture.Length - 8).ToUpper().Equals("/trigger".ToUpper()))
                                 {
                                     texture = "common/trigger";
                                 }
                                 else
                                 {
                                     if (texture.Substring(texture.Length - 5).ToUpper().Equals("/clip".ToUpper()))
                                     {
                                         texture = "common/clip";
                                     }
                                 }
                             }
                         }
                     }
                 }
                 catch (System.ArgumentOutOfRangeException e)
                 {
                     ;
                 }
             }
             else
             {
                 if (BSPVersion == mapType.TYPE_SOURCE17 || BSPVersion == mapType.TYPE_SOURCE18 || BSPVersion == mapType.TYPE_SOURCE19 || BSPVersion == mapType.TYPE_SOURCE20 || BSPVersion == mapType.TYPE_SOURCE21 || BSPVersion == mapType.TYPE_SOURCE22 || BSPVersion == mapType.TYPE_SOURCE23 || BSPVersion == mapType.TYPE_DMOMAM || BSPVersion == mapType.TYPE_VINDICTUS || BSPVersion == mapType.TYPE_TACTICALINTERVENTION)
                 {
                     try
                     {
                         if (texture.Substring(0, (5) - (0)).ToUpper().Equals("maps/".ToUpper()))
                         {
                             texture = texture.Substring(5);
                             for (int i = 0; i < texture.Length; i++)
                             {
                                 if (texture[i] == '/')
                                 {
                                     texture = texture.Substring(i + 1);
                                     break;
                                 }
                             }
                         }
                     }
                     catch (System.ArgumentOutOfRangeException e)
                     {
                         ;
                     }
                     // Find cubemap textures
                     int  numUnderscores = 0;
                     bool validnumber    = false;
                     for (int i = texture.Length - 1; i > 0; i--)
                     {
                         if (texture[i] <= '9' && texture[i] >= '0')
                         {
                             // Current is a number, start building string
                             validnumber = true;
                         }
                         else
                         {
                             if (texture[i] == '-')
                             {
                                 // Current is a minus sign (-).
                                 if (!validnumber)
                                 {
                                     break;                                         // Make sure there's a number to add the minus sign to. If not, kill the loop.
                                 }
                             }
                             else
                             {
                                 if (texture[i] == '_')
                                 {
                                     // Current is an underscore (_)
                                     if (validnumber)
                                     {
                                         // Make sure there is a number in the current string
                                         numUnderscores++;                                             // before moving on to the next one.
                                         validnumber = false;
                                         if (numUnderscores == 3)
                                         {
                                             // If we've got all our numbers
                                             texture = texture.Substring(0, (i) - (0));             // Cut the texture string
                                             break;                                                 // Kill the loop, we're done
                                         }
                                     }
                                     else
                                     {
                                         // No number after the underscore
                                         break;
                                     }
                                 }
                                 else
                                 {
                                     // Not an acceptable character
                                     break;
                                 }
                             }
                         }
                     }
                 }
             }
         }
         if (Double.IsInfinity(texScaleX) || Double.IsNaN(texScaleX))
         {
             texScaleX = 1;
         }
         if (Double.IsInfinity(texScaleY) || Double.IsNaN(texScaleY))
         {
             texScaleY = 1;
         }
         if (Double.IsInfinity(textureShiftS) || Double.IsNaN(textureShiftS))
         {
             textureShiftS = 0;
         }
         if (Double.IsInfinity(textureShiftT) || Double.IsNaN(textureShiftT))
         {
             textureShiftT = 0;
         }
         if (Double.IsInfinity(textureS.X) || Double.IsNaN(textureS.X) || Double.IsInfinity(textureS.Y) || Double.IsNaN(textureS.Y) || Double.IsInfinity(textureS.Z) || Double.IsNaN(textureS.Z))
         {
             textureS = TexInfo.textureAxisFromPlane(inputData.Plane)[0];
         }
         if (Double.IsInfinity(textureT.X) || Double.IsNaN(textureT.X) || Double.IsInfinity(textureT.Y) || Double.IsNaN(textureT.Y) || Double.IsInfinity(textureT.Z) || Double.IsNaN(textureT.Z))
         {
             textureT = TexInfo.textureAxisFromPlane(inputData.Plane)[1];
         }
         if (Settings.roundNums)
         {
             temp = "( " + MAPMaker.Round(triangle[0].X, 6) +
                    " " + MAPMaker.Round(triangle[0].Y, 6) +
                    " " + MAPMaker.Round(triangle[0].Z, 6) + " ) " +
                    "( " + MAPMaker.Round(triangle[1].X, 6) +
                    " " + MAPMaker.Round(triangle[1].Y, 6) +
                    " " + MAPMaker.Round(triangle[1].Z, 6) + " ) " +
                    "( " + MAPMaker.Round(triangle[2].X, 6) +
                    " " + MAPMaker.Round(triangle[2].Y, 6) +
                    " " + MAPMaker.Round(triangle[2].Z, 6) + " ) " +
                    texture + " " + System.Math.Floor(textureShiftS) + " " + System.Math.Floor(textureShiftT) + " " +
                    MAPMaker.FormattedRound(texRot, 2, "######0.00") + " " +
                    MAPMaker.Round(texScaleX, 6) + " " +
                    MAPMaker.Round(texScaleY, 6) + " " + flags + " 0 0 ";
         }
         else
         {
             temp = "( " + triangle[0].X + " " + triangle[0].Y + " " + triangle[0].Z + " ) " + "( " + triangle[1].X + " " + triangle[1].Y + " " + triangle[1].Z + " ) " + "( " + triangle[2].X + " " + triangle[2].Y + " " + triangle[2].Z + " ) " + texture + " " + textureShiftS + " " + textureShiftT + " " + texRot + " " + texScaleX + " " + texScaleY + " " + flags + " 0 0 ";
         }
         if (isDetail)
         {
             temp += "+surfaceparm detail ";
         }
         return(temp);
     }
     catch (System.NullReferenceException e)
     {
         DecompilerThread.OnMessage(this, "WARNING: Side with bad data! Not exported!");
         return("");
     }
 }
Ejemplo n.º 22
0
            public MTOB(EndianBinaryReader er)
            {
                Type = er.ReadUInt32();
                Signature = er.ReadString(Encoding.ASCII, 4);
                if (Signature != "MTOB") throw new SignatureNotCorrectException(Signature, "MTOB", er.BaseStream.Position);
                Revision = er.ReadUInt32();
                NameOffset = (UInt32)er.BaseStream.Position + er.ReadUInt32();
                Unknown2 = er.ReadUInt32();
                Unknown3 = er.ReadUInt32();
                Flags = (MaterialFlags)er.ReadUInt32();
                TexCoordConfig = er.ReadUInt32();
                TranslucencyKind = er.ReadUInt32();
                MaterialColor = new MaterialColorCtr(er);
                Rasterization = new RasterizationCtr(er);
                FragmentOperation = new FragmentOperationCtr(er);
                NrActiveTextureCoordiators = er.ReadUInt32();
                TextureCoordiators = new TextureCoordinatorCtr[3];
                TextureCoordiators[0] = new TextureCoordinatorCtr(er);
                TextureCoordiators[1] = new TextureCoordinatorCtr(er);
                TextureCoordiators[2] = new TextureCoordinatorCtr(er);
                TexMapper0Offset = er.ReadUInt32();
                if (TexMapper0Offset != 0) TexMapper0Offset += (UInt32)er.BaseStream.Position - 4;
                TexMapper1Offset = er.ReadUInt32();
                if (TexMapper1Offset != 0) TexMapper1Offset += (UInt32)er.BaseStream.Position - 4;
                TexMapper2Offset = er.ReadUInt32();
                if (TexMapper2Offset != 0) TexMapper2Offset += (UInt32)er.BaseStream.Position - 4;
                ProcTexMapperOffset = er.ReadUInt32();
                if (ProcTexMapperOffset != 0) ProcTexMapperOffset += (UInt32)er.BaseStream.Position - 4;
                ShaderOffset = (UInt32)er.BaseStream.Position + er.ReadUInt32();
                FragmentShaderOffset = (UInt32)er.BaseStream.Position + er.ReadUInt32();
                ShaderProgramDescriptionIndex = er.ReadUInt32();
                NrShaderParameters = er.ReadUInt32();
                ShaderParametersOffsetArrayOffset = er.ReadUInt32();
                LightSetIndex = er.ReadUInt32();
                FogIndex = er.ReadUInt32();
                ShadingParameterHash = er.ReadUInt32();
                ShaderParametersHash = er.ReadUInt32();
                TextureCoordinatorsHash = er.ReadUInt32();
                TextureSamplersHash = er.ReadUInt32();
                TextureMappersHash = er.ReadUInt32();
                MaterialColorHash = er.ReadUInt32();
                RasterizationHash = er.ReadUInt32();
                FragmentLightingHash = er.ReadUInt32();
                FragmentLightingTableHash = er.ReadUInt32();
                FragmentLightingTableParametersHash = er.ReadUInt32();
                TextureCombinersHash = er.ReadUInt32();
                AlphaTestHash = er.ReadUInt32();
                FragmentOperationHash = er.ReadUInt32();
                MaterialId = er.ReadUInt32();

                long curpos = er.BaseStream.Position;
                er.BaseStream.Position = NameOffset;
                Name = er.ReadStringNT(Encoding.ASCII);
                if (TexMapper0Offset != 0)
                {
                    er.BaseStream.Position = TexMapper0Offset;
                    Tex0 = new TexInfo(er);
                }
                if (TexMapper1Offset != 0)
                {
                    er.BaseStream.Position = TexMapper1Offset;
                    Tex1 = new TexInfo(er);
                }
                if (TexMapper2Offset != 0)
                {
                    er.BaseStream.Position = TexMapper2Offset;
                    Tex2 = new TexInfo(er);
                }
                /*if (TexMapper3Offset != 0)
                {
                    er.BaseStream.Position = Tex3Offset;
                    Tex3 = new TexInfo(er);
                }*/
                //TODO: Procedural Texture Mapper
                er.BaseStream.Position = ShaderOffset;
                Shader = new SHDR(er);
                er.BaseStream.Position = FragmentShaderOffset;
                FragShader = new FragmentShader(er);
                er.BaseStream.Position = curpos;
            }
Ejemplo n.º 23
0
        protected override void OnUpdate(DX11RenderContext context)
        {
            bool resetta = true;

            try
            {
                var ptadesc = FOutTexArray[0][context].Description;
                resetta = FTADepth[0] != ptadesc.ArraySize ||
                          (int)FTASize[0].x != ptadesc.Width ||
                          (int)FTASize[0].y != ptadesc.Height ||
                          FTAFormat[0] != ptadesc.Format;
            }
            catch (Exception e) { }
            if (resetta)
            {
                try
                {
                    FOutTexArray[0].Dispose(context);
                }
                catch (Exception e) { }
                var tadesc = new Texture2DDescription
                {
                    ArraySize = FTADepth[0],
                    Width     = (int)FTASize[0].x,
                    Height    = (int)FTASize[0].y,
                    Format    = FTAFormat[0],
                    BindFlags = BindFlags.UnorderedAccess | BindFlags.ShaderResource,
                    //CpuAccessFlags = CpuAccessFlags.None,
                    MipLevels         = 1,
                    OptionFlags       = ResourceOptionFlags.None,
                    SampleDescription = new SampleDescription(1, 0),
                    //Usage = ResourceUsage.Default
                };
                FOutTexArray[0][context] = new DX11RWTextureArray2D(context, new Texture2D(context.Device, tadesc));

                foreach (var semantic in CustomSemantics)
                {
                    semantic.Dispose();
                }
                CustomSemantics.Clear();
                CustomSemantics.Add(new RWTexture2dArrayRenderSemantic("TEXTUREARRAY", false)
                {
                    Data = FOutTexArray[0][context]
                });
                CustomSemantics.Add(new Texture2dArrayRenderSemantic("TEXTUREARRAY_SRV", false)
                {
                    Data = FOutTexArray[0][context]
                });
            }

            TexInfo ti = this.rtm.GetRenderTarget(context);

            if (ti.w != this.width || ti.h != this.height || !this.targets.ContainsKey(context) || this.invalidate ||
                ti.format != this.format)
            {
                this.invalidate = false;
                this.width      = ti.w;
                this.height     = ti.h;
                this.format     = ti.format;

                this.depthmanager.NeedReset = true;

                if (targets.ContainsKey(context))
                {
                    context.ResourcePool.Unlock(targets[context]);
                }

                if (targetresolve.ContainsKey(context))
                {
                    context.ResourcePool.Unlock(targetresolve[context]);
                }

                int aacount   = Convert.ToInt32(this.FInAASamplesPerPixel[0].Name);
                int aaquality = 0;

                if (aacount > 1)
                {
                    List <SampleDescription> sds = context.GetMultisampleFormatInfo(ti.format);
                    int maxlevels = sds[sds.Count - 1].Count;

                    if (aacount > maxlevels)
                    {
                        FHost.Log(TLogType.Warning, "Multisample count too high for this format, reverted to: " + maxlevels);
                        aacount = maxlevels;
                    }

                    DX11RenderTarget2D temptarget        = context.ResourcePool.LockRenderTarget(this.width, this.height, ti.format, new SampleDescription(aacount, aaquality), this.FInDoMipMaps[0], this.FInMipLevel[0], this.FInSharedTex[0]).Element;
                    DX11RenderTarget2D temptargetresolve = context.ResourcePool.LockRenderTarget(this.width, this.height, ti.format, new SampleDescription(1, 0), this.FInDoMipMaps[0], this.FInMipLevel[0], this.FInSharedTex[0]).Element;

                    targets[context]       = temptarget;
                    targetresolve[context] = temptargetresolve;

                    this.FOutBuffers[0][context]   = temptargetresolve;
                    this.FOutAABuffers[0][context] = temptarget;
                }
                else
                {
                    //Bind both texture as same output
                    DX11RenderTarget2D temptarget = context.ResourcePool.LockRenderTarget(this.width, this.height, ti.format, new SampleDescription(aacount, aaquality), this.FInDoMipMaps[0], this.FInMipLevel[0], this.FInSharedTex[0]).Element;
                    targets[context] = temptarget;

                    this.FOutBuffers[0][context]   = temptarget;
                    this.FOutAABuffers[0][context] = temptarget;
                }
            }
        }
Ejemplo n.º 24
0
 private int CompareNewMsg(TexInfo a, TexInfo b)
 {
     return(a.path.CompareTo(b.path));
 }
Ejemplo n.º 25
0
        public void Write(EndianBinaryWriter er)
        {
            long offpos = er.BaseStream.Position;

            //header.Write(er, 0);
            er.Write(Signature, Encoding.ASCII, false);
            er.Write((uint)0);

            List <byte> TexData           = new List <byte>();
            List <byte> Tex4x4Data        = new List <byte>();
            List <byte> Tex4x4PlttIdxData = new List <byte>();

            foreach (DictTexData d in dictTex.entry.data)
            {
                if (d.Fmt != Textures.ImageFormat.COMP4x4)
                {
                    TexData.AddRange(d.Data);
                }
                else
                {
                    Tex4x4Data.AddRange(d.Data);
                    Tex4x4PlttIdxData.AddRange(d.Data4x4);
                }
            }
            List <byte> PaletteData = new List <byte>();

            foreach (DictPlttData d in dictPltt.entry.data)
            {
                PaletteData.AddRange(d.Data);
            }

            TexInfo.ofsDict          = 60;
            TexInfo.sizeTex          = (uint)TexData.Count;
            TexInfo.ofsTex           = (UInt32)(60 + 8 + (dictTex.numEntry + 1) * 4 + 4 + dictTex.numEntry * 8 + dictTex.numEntry * 16 + 8 + (dictPltt.numEntry + 1) * 4 + 4 + dictPltt.numEntry * 4 + dictPltt.numEntry * 16);
            Tex4x4Info.ofsDict       = 60;
            Tex4x4Info.sizeTex       = (uint)Tex4x4Data.Count;
            Tex4x4Info.ofsTex        = (UInt32)(60 + 8 + (dictTex.numEntry + 1) * 4 + 4 + dictTex.numEntry * 8 + dictTex.numEntry * 16 + 8 + (dictPltt.numEntry + 1) * 4 + 4 + dictPltt.numEntry * 4 + dictPltt.numEntry * 16 + TexData.Count);
            Tex4x4Info.ofsTexPlttIdx = (UInt32)(60 + 8 + (dictTex.numEntry + 1) * 4 + 4 + dictTex.numEntry * 8 + dictTex.numEntry * 16 + 8 + (dictPltt.numEntry + 1) * 4 + 4 + dictPltt.numEntry * 4 + dictPltt.numEntry * 16 + TexData.Count + Tex4x4Data.Count);
            PlttInfo.ofsDict         = (ushort)(60 + 8 + (dictTex.numEntry + 1) * 4 + 4 + dictTex.numEntry * 8 + dictTex.numEntry * 16);
            PlttInfo.sizePltt        = (uint)PaletteData.Count;
            PlttInfo.ofsPlttData     = (UInt32)(60 + 8 + (dictTex.numEntry + 1) * 4 + 4 + dictTex.numEntry * 8 + dictTex.numEntry * 16 + 8 + (dictPltt.numEntry + 1) * 4 + 4 + dictPltt.numEntry * 4 + dictPltt.numEntry * 16 + TexData.Count + Tex4x4Data.Count + Tex4x4PlttIdxData.Count);
            TexInfo.Write(er);
            Tex4x4Info.Write(er);
            PlttInfo.Write(er);
            uint offset    = 0;
            uint offset4x4 = 0;

            for (int i = 0; i < dictTex.numEntry; i++)
            {
                if (dictTex[i].Value.Fmt != Textures.ImageFormat.COMP4x4)
                {
                    dictTex[i].Value.Offset = offset;
                    offset += (uint)dictTex[i].Value.Data.Length;
                }
                else
                {
                    dictTex[i].Value.Offset = offset4x4;
                    offset4x4 += (uint)dictTex[i].Value.Data.Length;
                }
            }
            dictTex.Write(er);
            uint offsetPltt = 0;

            for (int i = 0; i < dictPltt.numEntry; i++)
            {
                dictPltt[i].Value.offset = offsetPltt;
                offsetPltt += (uint)dictPltt[i].Value.Data.Length;
            }
            dictPltt.Write(er);
            er.Write(TexData.ToArray(), 0, TexData.Count);
            er.Write(Tex4x4Data.ToArray(), 0, Tex4x4Data.Count);
            er.Write(Tex4x4PlttIdxData.ToArray(), 0, Tex4x4PlttIdxData.Count);
            er.Write(PaletteData.ToArray(), 0, PaletteData.Count);
            long curpos = er.BaseStream.Position;

            er.BaseStream.Position = offpos + 4;
            er.Write((UInt32)(curpos - offpos));
            er.BaseStream.Position = curpos;
        }
Ejemplo n.º 26
0
 private string brushSideToString(MAPBrushSide inputData)
 {
     try {
         string texture = inputData.Texture;
         if (BSPVersion == mapType.TYPE_SOURCE17 || BSPVersion == mapType.TYPE_SOURCE18 || BSPVersion == mapType.TYPE_SOURCE19 || BSPVersion == mapType.TYPE_SOURCE20 || BSPVersion == mapType.TYPE_SOURCE21 || BSPVersion == mapType.TYPE_SOURCE22 || BSPVersion == mapType.TYPE_SOURCE23 || BSPVersion == mapType.TYPE_DMOMAM || BSPVersion == mapType.TYPE_VINDICTUS || BSPVersion == mapType.TYPE_TACTICALINTERVENTION)
         {
             try {
                 if (texture.Substring(0, (5) - (0)).ToUpper().Equals("maps/".ToUpper()))
                 {
                     texture = texture.Substring(5);
                     for (int i = 0; i < texture.Length; i++)
                     {
                         if (texture[i] == '/')
                         {
                             texture = texture.Substring(i + 1);
                             break;
                         }
                     }
                 }
             }
             catch (System.ArgumentOutOfRangeException) {
                 ;
             }
             // Find cubemap textures
             int  numUnderscores = 0;
             bool validnumber    = false;
             for (int i = texture.Length - 1; i > 0; i--)
             {
                 if (texture[i] <= '9' && texture[i] >= '0')
                 {
                     // Current is a number, start building string
                     validnumber = true;
                 }
                 else
                 {
                     if (texture[i] == '-')
                     {
                         // Current is a minus sign (-).
                         if (!validnumber)
                         {
                             break;                                 // Make sure there's a number to add the minus sign to. If not, kill the loop.
                         }
                     }
                     else
                     {
                         if (texture[i] == '_')
                         {
                             // Current is an underscore (_)
                             if (validnumber)
                             {
                                 // Make sure there is a number in the current string
                                 numUnderscores++;                                     // before moving on to the next one.
                                 validnumber = false;
                                 if (numUnderscores == 3)
                                 {
                                     // If we've got all our numbers
                                     texture = texture.Substring(0, (i) - (0));     // Cut the texture string
                                     break;                                         // Kill the loop, we're done
                                 }
                             }
                             else
                             {
                                 // No number after the underscore
                                 break;
                             }
                         }
                         else
                         {
                             // Not an acceptable character
                             break;
                         }
                     }
                 }
             }
         }
         Plane    plane         = inputData.Plane;
         Vector3D textureS      = inputData.TextureS;
         Vector3D textureT      = inputData.TextureT;
         double   textureShiftS = inputData.TextureShiftS;
         double   textureShiftT = inputData.TextureShiftT;
         double   texScaleX     = inputData.TexScaleX;
         double   texScaleY     = inputData.TexScaleY;
         if (Double.IsInfinity(texScaleX) || Double.IsNaN(texScaleX))
         {
             texScaleX = 1;
         }
         if (Double.IsInfinity(texScaleY) || Double.IsNaN(texScaleY))
         {
             texScaleY = 1;
         }
         if (Double.IsInfinity(textureShiftS) || Double.IsNaN(textureShiftS))
         {
             textureShiftS = 0;
         }
         if (Double.IsInfinity(textureShiftT) || Double.IsNaN(textureShiftT))
         {
             textureShiftT = 0;
         }
         if (Double.IsInfinity(textureS.X) || Double.IsNaN(textureS.X) || Double.IsInfinity(textureS.Y) || Double.IsNaN(textureS.Y) || Double.IsInfinity(textureS.Z) || Double.IsNaN(textureS.Z))
         {
             textureS = TexInfo.textureAxisFromPlane(inputData.Plane)[0];
         }
         if (Double.IsInfinity(textureT.X) || Double.IsNaN(textureT.X) || Double.IsInfinity(textureT.Y) || Double.IsNaN(textureT.Y) || Double.IsInfinity(textureT.Z) || Double.IsNaN(textureT.Z))
         {
             textureT = TexInfo.textureAxisFromPlane(inputData.Plane)[1];
         }
         if (Settings.roundNums)
         {
             return("( " + MAPMaker.Round(plane.A, 10) + " " + MAPMaker.Round(plane.B, 10) + " " + MAPMaker.Round(plane.C, 10) + " " + MAPMaker.Round(plane.Dist, 10) + " ) " + "( ( 1 0 " + MAPMaker.Round(textureShiftS, 10) + " ) ( 0 1 " + MAPMaker.Round(textureShiftT, 10) + " ) ) " + "\"" + texture + "\" 0 0 0");
         }
         else
         {
             return("( " + plane.A + " " + plane.B + " " + plane.C + " " + plane.Dist + " ) " + "( ( 1 0 " + textureShiftS + " ) ( 0 1 " + textureShiftT + " ) ) " + "\"" + texture + "\" 0 0 0");
         }
     } catch (System.NullReferenceException e) {
         DecompilerThread.OnMessage(this, "WARNING: Side with bad data! Not exported!");
         return(null);
     }
 }
    // -decompileBrush38(Brush, int, boolean)
    // Decompiles the Brush and adds it to entitiy #currentEntity as .MAP data.
    private void decompileBrush(Brush brush, int currentEntity)
    {
        Vector3D origin    = mapFile[currentEntity].Origin;
        int      firstSide = brush.FirstSide;
        int      numSides  = brush.NumSides;

        MAPBrushSide[] brushSides = new MAPBrushSide[numSides];
        bool           isDetail   = false;

        if (currentEntity == 0 && !Settings.noDetail && (brush.Contents[3] & ((sbyte)1 << 3)) != 0)
        {
            isDetail = true;
        }
        MAPBrush mapBrush = new MAPBrush(numBrshs, currentEntity, isDetail);

        if (currentEntity == 0 && !Settings.noWater && (brush.Contents[0] & ((sbyte)1 << 5)) != 0)
        {
            mapBrush.Water = true;
        }
        //DecompilerThread.OnMessage(this, ": " + numSides + " sides, detail: " + isDetail);
        for (int i = 0; i < numSides; i++)
        {
            // For each side of the brush
            BrushSide currentSide = BSPObject.BrushSides[firstSide + i];
            if (currentSide.isBevel() == 0)
            {
                // Bevel sides are evil
                Vector3D[] plane        = new Vector3D[3];                     // Three points define a plane. All I have to do is find three points on that plane.
                Plane      currentPlane = BSPObject.Planes[currentSide.Plane]; // To find those three points, I must extrapolate from planes until I find a way to associate faces with brushes
                bool       isDuplicate  = false;                               /* TODO: We sure don't want duplicate planes (though this is already handled by the MAPBrush class). Make sure neither checked side is bevel.
                                                                                * for(int j=i+1;j<numSides;j++) { // For each subsequent side of the brush
                                                                                * if(currentPlane.equals(BSPObject.Planes.getPlane(BSPObject.getBrushSides()[firstSide+j).getPlane()))) {
                                                                                * DecompilerThread.OnMessage(this, "WARNING: Duplicate planes in a brush, sides "+i+" and "+j,Settings.VERBOSITY_WARNINGS);
                                                                                * isDuplicate=true;
                                                                                * }
                                                                                * }*/
                if (!isDuplicate)
                {
                    TexInfo currentTexInfo = null;
                    string  texture        = "tools/toolsclip";
                    if (currentSide.Texture > -1)
                    {
                        currentTexInfo = BSPObject.TexInfo[currentSide.Texture];
                    }
                    else
                    {
                        int dataIndex = BSPObject.findTexDataWithTexture("tools/toolsclip");
                        if (dataIndex >= 0)
                        {
                            currentTexInfo = new TexInfo(new Vector3D(0, 0, 0), 0, new Vector3D(0, 0, 0), 0, 0, dataIndex);
                        }
                    }
                    if (currentTexInfo != null)
                    {
                        SourceTexData currentTexData;
                        if (currentTexInfo.Texture >= 0)
                        {
                            // I've only found one case where this is a problem: c2a3a in HL Source. Don't know why.
                            currentTexData = BSPObject.TexDatas[currentTexInfo.Texture];
                            texture        = BSPObject.Textures.getTextureAtOffset((uint)BSPObject.TexTable[currentTexData.StringTableIndex]);
                        }
                        else
                        {
                            texture = "tools/toolsskip";
                        }
                    }
                    double[] textureU      = new double[3];
                    double[] textureV      = new double[3];
                    double   textureShiftU = 0;
                    double   textureShiftV = 0;
                    double   texScaleU     = 1;
                    double   texScaleV     = 1;
                    // Get the lengths of the axis vectors
                    if ((texture.Length > 6 && texture.Substring(0, (6) - (0)).ToUpper().Equals("tools/".ToUpper())) || currentTexInfo == null)
                    {
                        // Tools textured faces do not maintain their own texture axes. Therefore, an arbitrary axis is
                        // used in the compiled map. When decompiled, these axes might smear the texture on the face. Fix that.
                        Vector3D[] axes = TexInfo.textureAxisFromPlane(currentPlane);
                        textureU = axes[0].Point;
                        textureV = axes[1].Point;
                    }
                    else
                    {
                        double SAxisLength = System.Math.Sqrt(System.Math.Pow((double)currentTexInfo.SAxis.X, 2) + System.Math.Pow((double)currentTexInfo.SAxis.Y, 2) + System.Math.Pow((double)currentTexInfo.SAxis.Z, 2));
                        double TAxisLength = System.Math.Sqrt(System.Math.Pow((double)currentTexInfo.TAxis.X, 2) + System.Math.Pow((double)currentTexInfo.TAxis.Y, 2) + System.Math.Pow((double)currentTexInfo.TAxis.Z, 2));
                        // In compiled maps, shorter vectors=longer textures and vice versa. This will convert their lengths back to 1. We'll use the actual scale values for length.
                        texScaleU   = (1 / SAxisLength);                       // Let's use these values using the lengths of the U and V axes we found above.
                        texScaleV   = (1 / TAxisLength);
                        textureU[0] = ((double)currentTexInfo.SAxis.X / SAxisLength);
                        textureU[1] = ((double)currentTexInfo.SAxis.Y / SAxisLength);
                        textureU[2] = ((double)currentTexInfo.SAxis.Z / SAxisLength);
                        double originShiftU = (((double)currentTexInfo.SAxis.X / SAxisLength) * origin[X] + ((double)currentTexInfo.SAxis.Y / SAxisLength) * origin[Y] + ((double)currentTexInfo.SAxis.Z / SAxisLength) * origin[Z]) / texScaleU;
                        //UPGRADE_WARNING: Data types in Visual C# might be different.  Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextSettingsIndex'&keyword='jlca1042'"
                        textureShiftU = (double)currentTexInfo.SShift - originShiftU;
                        textureV[0]   = ((double)currentTexInfo.TAxis.X / TAxisLength);
                        textureV[1]   = ((double)currentTexInfo.TAxis.Y / TAxisLength);
                        textureV[2]   = ((double)currentTexInfo.TAxis.Z / TAxisLength);
                        double originShiftV = (((double)currentTexInfo.TAxis.X / TAxisLength) * origin[X] + ((double)currentTexInfo.TAxis.Y / TAxisLength) * origin[Y] + ((double)currentTexInfo.TAxis.Z / TAxisLength) * origin[Z]) / texScaleV;
                        //UPGRADE_WARNING: Data types in Visual C# might be different.  Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextSettingsIndex'&keyword='jlca1042'"
                        textureShiftV = (double)currentTexInfo.TShift - originShiftV;
                    }
                    float  texRot   = 0;               // In compiled maps this is calculated into the U and V axes, so set it to 0 until I can figure out a good way to determine a better value.
                    int    flags    = 0;               // Set this to 0 until we can somehow associate faces with brushes
                    string material = "wld_lightmap";  // Since materials are a NightFire only thing, set this to a good default
                    double lgtScale = 16;              // These values are impossible to get from a compiled map since they
                    double lgtRot   = 0;               // are used by RAD for generating lightmaps, then are discarded, I believe.
                    brushSides[i] = new MAPBrushSide(currentPlane, texture, textureU, textureShiftU, textureV, textureShiftV, texRot, texScaleU, texScaleV, flags, material, lgtScale, lgtRot);
                    mapBrush.add(brushSides[i]);
                }
            }
        }

        if (!Settings.skipPlaneFlip)
        {
            if (mapBrush.hasBadSide())
            {
                // If there's a side that might be backward
                if (mapBrush.hasGoodSide())
                {
                    // If there's a side that is forward
                    mapBrush = MAPBrush.SimpleCorrectPlanes(mapBrush);
                    numSimpleCorrects++;
                    if (Settings.calcVerts)
                    {
                        // This is performed in advancedcorrect, so don't use it if that's happening
                        try
                        {
                            mapBrush = MAPBrush.CalcBrushVertices(mapBrush);
                        }
                        catch (System.NullReferenceException)
                        {
                            DecompilerThread.OnMessage(this, "WARNING: Brush vertex calculation failed on entity " + mapBrush.Entnum + " brush " + mapBrush.Brushnum + "");
                        }
                    }
                }
                else
                {
                    // If no forward side exists
                    try
                    {
                        mapBrush = MAPBrush.AdvancedCorrectPlanes(mapBrush);
                        numAdvancedCorrects++;
                    }
                    catch (System.ArithmeticException)
                    {
                        DecompilerThread.OnMessage(this, "WARNING: Plane correct returned 0 triangles for entity " + mapBrush.Entnum + " brush " + mapBrush.Brushnum + "");
                    }
                }
            }
            else
            {
                numGoodBrushes++;
            }
        }
        else
        {
            if (Settings.calcVerts)
            {
                // This is performed in advancedcorrect, so don't use it if that's happening
                try
                {
                    mapBrush = MAPBrush.CalcBrushVertices(mapBrush);
                }
                catch (System.NullReferenceException)
                {
                    DecompilerThread.OnMessage(this, "WARNING: Brush vertex calculation failed on entity " + mapBrush.Entnum + " brush " + mapBrush.Brushnum + "");
                }
            }
        }

        // This adds the brush we've been finding and creating to
        // the current entity as an attribute. The way I've coded
        // this whole program and the entities parser, this shouldn't
        // cause any issues at all.
        if (Settings.brushesToWorld)
        {
            mapBrush.Water = false;
            mapFile[0].Brushes.Add(mapBrush);
        }
        else
        {
            mapFile[currentEntity].Brushes.Add(mapBrush);
        }
    }
Ejemplo n.º 28
0
        private static void _Combine(CombineInfo combineInfo)
        {
            List <Mesh> meshList = new List <Mesh>();

            try
            {
                CharacterAsset         item = null;
                int                    i, j, k, count, count1, count2;
                List <CombineInstance> combineInstances = new List <CombineInstance>();
                List <Transform>       bones            = new List <Transform>();
                Transform[]            transforms       = combineInfo.root.GetComponentsInChildren <Transform>();


                TexInfo[]           texInfo = new TexInfo[combineInfo.items.Count];
                SkinnedMeshRenderer smr     = null;
                CombineInstance     ci;
                string[]            strs = null;
                string    str            = null;
                Transform transform;
                count2 = transforms.Length;
                count  = (short)combineInfo.items.Count;
                for (i = 0; i < count; i++)
                {
                    item = combineInfo.items[i];
                    smr  = item.GetSkinnedMeshRenderer();
                    if (smr == null)
                    {
                        return;
                    }
                    Mesh mesh = Mesh.Instantiate(smr.sharedMesh) as Mesh;
                    for (j = 0, count1 = smr.sharedMesh.subMeshCount; j < count1; j++)
                    {
                        ci              = new CombineInstance();
                        ci.mesh         = mesh;
                        ci.subMeshIndex = j;
                        combineInstances.Add(ci);
                    }

                    strs = item.GetBoneNames();
                    for (j = 0, count1 = strs.Length; j < count1; j++)
                    {
                        str = strs[j];
                        for (k = 0; k < count2; k++)
                        {
                            transform = transforms[k];
                            if (transform.name != str)
                            {
                                continue;
                            }
                            bones.Add(transform);
                            break;
                        }
                    }

                    meshList.Add(mesh);

                    Object.Destroy(smr.gameObject);
                }

                TempLoad tl     = null;
                string[] strArr = new string[count];

                string destName;
                string path;
                int    size;
                bool   encrypt;
                Example.VersionFile.Type fileType;
                for (i = 0; i < count; i++)
                {
                    item                = combineInfo.items[i];
                    strs                = item.GetTexNames();
                    tl                  = new TempLoad();
                    tl.texInfo          = texInfo;
                    tl.index            = (short)i;
                    tl.combineInstances = combineInstances;
                    tl.bones            = bones;
                    tl.meshList         = meshList;
                    tl.endCombine       = combineInfo.endCombine;
                    tl.endParam         = combineInfo.endParam;
                    tl.root             = combineInfo.root;
                    tl.over             = false;
                    tl.plus             = combineInfo.plus;
                    tl.sub              = combineInfo.sub;
                    tl.autoTemp         = combineInfo.autoTemp;
                    tl.texName          = strArr;
                    tl.light            = combineInfo.light;

                    GameUtils.stringBuilder.Remove(0, GameUtils.stringBuilder.Length);
                    GameUtils.stringBuilder.Append(strs[0]);

                    ResUpdate.GetLoadDetails(GameUtils.stringBuilder.ToString(), out destName, out path, out size, out encrypt, out fileType);
                    strArr[i] = GameUtils.stringBuilder.ToString();
                    ResLoader.LoadByPath(strArr[i], destName, path, fileType, size, OnLoad, tl, combineInfo.autoTemp);
                }
            }
            catch (System.Exception e)
            {
                for (int i = 0; i < meshList.Count; i++)
                {
                    Object.Destroy(meshList[i]);
                }
                if (combineInfo != null && combineInfo.endCombine != null)
                {
                    combineInfo.endCombine(null, -1, -1, combineInfo.endParam);
                }
                Debug.LogError("combine error->" + e.ToString());
            }
        }
    // METHODS

    // Attempt to turn the BSP into a .MAP file
    public virtual Entities decompile()
    {
        DecompilerThread.OnMessage(this, "Decompiling...");
        // In the decompiler, it is not necessary to copy all entities to a new object, since
        // no writing is ever done back to the BSP file.
        mapFile = BSPObject.Entities;
        //int numAreaPortals=0;
        int numTotalItems = 0;
        int onePercent    = (int)((BSPObject.Brushes.Count + BSPObject.Entities.Count) / 100);

        if (onePercent < 1)
        {
            onePercent = 1;
        }
        int originalNumEntities = BSPObject.Entities.Count;         // Need to keep track of this in this algorithm, since I create more entities on the fly

        for (int i = 0; i < originalNumEntities; i++)
        {
            // For each entity
            //DecompilerThread.OnMessage(this, "Entity " + i + ": " + mapFile[i]["classname"]);
            // getModelNumber() returns 0 for worldspawn, the *# for brush based entities, and -1 for everything else
            int currentModel = mapFile[i].ModelNumber;
            if (currentModel > -1)                // If this is still -1 then it's strictly a point-based entity. Move on to the next one.
            {
                Leaf[] leaves      = BSPObject.getLeavesInModel(currentModel);
                int    numLeaves   = leaves.Length;
                bool[] brushesUsed = new bool[BSPObject.Brushes.Count]; // Keep a list of brushes already in the model, since sometimes the leaves lump references one brush several times
                numBrshs = 0;                                           // Reset the brush count for each entity
                for (int j = 0; j < numLeaves; j++)
                {
                    // For each leaf in the bunch
                    Leaf currentLeaf         = leaves[j];
                    int  firstMarkBrushIndex = currentLeaf.FirstMarkBrush;
                    int  numBrushIndices     = currentLeaf.NumMarkBrushes;
                    if (numBrushIndices > 0)
                    {
                        // A lot of leaves reference no brushes. If this is one, this iteration of the j loop is finished
                        for (int k = 0; k < numBrushIndices; k++)
                        {
                            // For each brush referenced
                            long currentBrushIndex = BSPObject.MarkBrushes[firstMarkBrushIndex + k];
                            if (!brushesUsed[(int)currentBrushIndex])
                            {
                                // If the current brush has NOT been used in this entity
                                //Console.Write("Brush " + numBrshs);
                                brushesUsed[(int)currentBrushIndex] = true;
                                Brush brush = BSPObject.Brushes[(int)currentBrushIndex];
                                decompileBrush(brush, i);                                 // Decompile the brush
                                numBrshs++;
                                numTotalItems++;
                                if (numTotalItems % onePercent == 0)
                                {
                                    parent.OnProgress(this, numTotalItems / (double)(BSPObject.Brushes.Count + BSPObject.Entities.Count));
                                }
                            }
                        }
                    }
                }
            }
            numTotalItems++;             // This entity
            if (numTotalItems % onePercent == 0)
            {
                parent.OnProgress(this, numTotalItems / (double)(BSPObject.Brushes.Count + BSPObject.Entities.Count));
            }
        }
        // Find displacement faces and generate brushes for them
        for (int i = 0; i < BSPObject.Faces.Count; i++)
        {
            Face face = BSPObject.Faces[i];
            if (face.Displacement > -1)
            {
                SourceDispInfo disp = BSPObject.DispInfos[face.Displacement];
                TexInfo        currentTexInfo;
                if (face.Texture > -1)
                {
                    currentTexInfo = BSPObject.TexInfo[face.Texture];
                }
                else
                {
                    Vector3D[] axes = TexInfo.textureAxisFromPlane(BSPObject.Planes[face.Plane]);
                    currentTexInfo = new TexInfo(axes[0], 0, axes[1], 0, 0, BSPObject.findTexDataWithTexture("tools/toolsclip"));
                }
                SourceTexData currentTexData = BSPObject.TexDatas[currentTexInfo.Texture];
                string        texture        = BSPObject.Textures.getTextureAtOffset((uint)BSPObject.TexTable[currentTexData.StringTableIndex]);
                double[]      textureU       = new double[3];
                double[]      textureV       = new double[3];
                // Get the lengths of the axis vectors
                double SAxisLength = System.Math.Sqrt(System.Math.Pow((double)currentTexInfo.SAxis.X, 2) + System.Math.Pow((double)currentTexInfo.SAxis.Y, 2) + System.Math.Pow((double)currentTexInfo.SAxis.Z, 2));
                double TAxisLength = System.Math.Sqrt(System.Math.Pow((double)currentTexInfo.TAxis.X, 2) + System.Math.Pow((double)currentTexInfo.TAxis.Y, 2) + System.Math.Pow((double)currentTexInfo.TAxis.Z, 2));
                // In compiled maps, shorter vectors=longer textures and vice versa. This will convert their lengths back to 1. We'll use the actual scale values for length.
                double texScaleU = (1 / SAxisLength);                 // Let's use these values using the lengths of the U and V axes we found above.
                double texScaleV = (1 / TAxisLength);
                textureU[0] = ((double)currentTexInfo.SAxis.X / SAxisLength);
                textureU[1] = ((double)currentTexInfo.SAxis.Y / SAxisLength);
                textureU[2] = ((double)currentTexInfo.SAxis.Z / SAxisLength);
                //UPGRADE_WARNING: Data types in Visual C# might be different.  Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextSettingsIndex'&keyword='jlca1042'"
                double textureShiftU = (double)currentTexInfo.SShift;
                textureV[0] = ((double)currentTexInfo.TAxis.X / TAxisLength);
                textureV[1] = ((double)currentTexInfo.TAxis.Y / TAxisLength);
                textureV[2] = ((double)currentTexInfo.TAxis.Z / TAxisLength);
                //UPGRADE_WARNING: Data types in Visual C# might be different.  Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextSettingsIndex'&keyword='jlca1042'"
                double textureShiftV = (double)currentTexInfo.TShift;

                if (face.NumEdges != 4)
                {
                    DecompilerThread.OnMessage(this, "Displacement face with " + face.NumEdges + " edges!");
                }

                // Turn vertices and edges into arrays of vectors
                Vector3D[] froms = new Vector3D[face.NumEdges];
                Vector3D[] tos   = new Vector3D[face.NumEdges];
                for (int j = 0; j < face.NumEdges; j++)
                {
                    if (BSPObject.SurfEdges[face.FirstEdge + j] > 0)
                    {
                        froms[j] = BSPObject.Vertices[BSPObject.Edges[(int)BSPObject.SurfEdges[face.FirstEdge + j]].FirstVertex].Vector;
                        tos[j]   = BSPObject.Vertices[BSPObject.Edges[(int)BSPObject.SurfEdges[face.FirstEdge + j]].SecondVertex].Vector;
                    }
                    else
                    {
                        tos[j]   = BSPObject.Vertices[BSPObject.Edges[(int)BSPObject.SurfEdges[face.FirstEdge + j] * (-1)].FirstVertex].Vector;
                        froms[j] = BSPObject.Vertices[BSPObject.Edges[(int)BSPObject.SurfEdges[face.FirstEdge + j] * (-1)].SecondVertex].Vector;
                    }
                }

                MAPBrush displacementBrush = MAPBrush.createBrushFromWind(froms, tos, texture, "TOOLS/TOOLSNODRAW", currentTexInfo);

                MAPDisplacement mapdisp = new MAPDisplacement(disp, BSPObject.DispVerts.getVertsInDisp(disp.DispVertStart, disp.Power));
                displacementBrush[0].Displacement = mapdisp;
                mapFile[0].Brushes.Add(displacementBrush);
            }
        }
        for (int i = 0; i < BSPObject.StaticProps.Count; i++)
        {
            Entity           newStaticProp = new Entity("prop_static");
            SourceStaticProp currentProp   = BSPObject.StaticProps[i];
            newStaticProp["model"]       = BSPObject.StaticProps.Dictionary[currentProp.DictionaryEntry];
            newStaticProp["skin"]        = currentProp.Skin + "";
            newStaticProp["origin"]      = currentProp.Origin.X + " " + currentProp.Origin.Y + " " + currentProp.Origin.Z;
            newStaticProp["angles"]      = currentProp.Angles.X + " " + currentProp.Angles.Y + " " + currentProp.Angles.Z;
            newStaticProp["solid"]       = currentProp.Solidity + "";
            newStaticProp["fademindist"] = currentProp.MinFadeDist + "";
            newStaticProp["fademaxdist"] = currentProp.MaxFadeDist + "";
            newStaticProp["fadescale"]   = currentProp.ForcedFadeScale + "";
            if (currentProp.Targetname != null)
            {
                newStaticProp["targetname"] = currentProp.Targetname;
            }
            mapFile.Add(newStaticProp);
        }
        for (int i = 0; i < BSPObject.Cubemaps.Count; i++)
        {
            Entity        newCubemap  = new Entity("env_cubemap");
            SourceCubemap currentCube = BSPObject.Cubemaps[i];
            newCubemap["origin"]      = currentCube.Origin.X + " " + currentCube.Origin.Y + " " + currentCube.Origin.Z;
            newCubemap["cubemapsize"] = currentCube.Size + "";
            mapFile.Add(newCubemap);
        }
        if (!Settings.skipPlaneFlip)
        {
            DecompilerThread.OnMessage(this, "Num simple corrected brushes: " + numSimpleCorrects);
            DecompilerThread.OnMessage(this, "Num advanced corrected brushes: " + numAdvancedCorrects);
            DecompilerThread.OnMessage(this, "Num good brushes: " + numGoodBrushes);
        }
        parent.OnProgress(this, 1.0);
        return(mapFile);
    }
Ejemplo n.º 30
0
    // -decompileBrush(Brush, int)
    // Decompiles the Brush and adds it to entitiy #currentEntity as MAPBrush classes.
    private void decompileBrush(Brush brush, int currentEntity)
    {
        Vector3D origin    = mapFile[currentEntity].Origin;
        int      firstSide = brush.FirstSide;
        int      numSides  = brush.NumSides;

        if (firstSide < 0)
        {
            isCoD             = true;
            firstSide         = currentSideIndex;
            currentSideIndex += numSides;
        }
        MAPBrushSide[] brushSides        = new MAPBrushSide[0];
        bool           isDetail          = false;
        int            brushTextureIndex = brush.Texture;

        byte[] contents = new byte[4];
        if (brushTextureIndex >= 0)
        {
            contents = BSPObject.Textures[brushTextureIndex].Contents;
        }
        if (!Settings.noDetail && (contents[3] & ((byte)1 << 3)) != 0)
        {
            // This is the flag according to q3 source
            isDetail = true;             // it's the same as Q2 (and Source), but I haven't found any Q3 maps that use it, so far
        }
        MAPBrush mapBrush     = new MAPBrush(numBrshs, currentEntity, isDetail);
        int      numRealFaces = 0;

        Plane[] brushPlanes = new Plane[0];
        //DecompilerThread.OnMessage(this, ": " + numSides + " sides");
        if (!Settings.noWater && (contents[0] & ((byte)1 << 5)) != 0)
        {
            mapBrush.Water = true;
        }
        bool isVisBrush = false;

        for (int i = 0; i < numSides; i++)
        {
            // For each side of the brush
            BrushSide currentSide      = BSPObject.BrushSides[firstSide + i];
            int       currentFaceIndex = currentSide.Face;
            Plane     currentPlane;
            if (isCoD)
            {
                switch (i)
                {
                case 0:                         // XMin
                    currentPlane = new Plane((double)(-1), (double)0, (double)0, (double)(-currentSide.Dist));
                    break;

                case 1:                         // XMax
                    currentPlane = new Plane((double)1, (double)0, (double)0, (double)currentSide.Dist);
                    break;

                case 2:                         // YMin
                    currentPlane = new Plane((double)0, (double)(-1), (double)0, (double)(-currentSide.Dist));
                    break;

                case 3:                         // YMax
                    currentPlane = new Plane((double)0, (double)1, (double)0, (double)currentSide.Dist);
                    break;

                case 4:                         // ZMin
                    currentPlane = new Plane((double)0, (double)0, (double)(-1), (double)(-currentSide.Dist));
                    break;

                case 5:                         // ZMax
                    currentPlane = new Plane((double)0, (double)0, (double)1, (double)currentSide.Dist);
                    break;

                default:
                    currentPlane = BSPObject.Planes[currentSide.Plane];
                    break;
                }
            }
            else
            {
                currentPlane = BSPObject.Planes[currentSide.Plane];
            }
            Vector3D[] triangle     = new Vector3D[0];         // Three points define a plane. All I have to do is find three points on that plane.
            bool       pointsWorked = false;
            int        firstVertex  = -1;
            int        numVertices  = 0;
            string     texture      = "noshader";
            bool       masked       = false;
            if (currentFaceIndex > -1)
            {
                Face currentFace         = BSPObject.Faces[currentFaceIndex];
                int  currentTextureIndex = currentFace.Texture;
                firstVertex = currentFace.FirstVertex;
                numVertices = currentFace.NumVertices;
                string mask = BSPObject.Textures[currentTextureIndex].Mask;
                if (mask.ToUpper().Equals("ignore".ToUpper()) || mask.Length == 0)
                {
                    texture = BSPObject.Textures[currentTextureIndex].Name;
                }
                else
                {
                    texture = mask.Substring(0, (mask.Length - 4) - (0));                     // Because mask includes file extensions
                    masked  = true;
                }
                if (numVertices != 0 && !Settings.planarDecomp)
                {
                    // If the face actually references a set of vertices
                    triangle = new Vector3D[3];
                    double currentHighest = 0.0;
                    // Find the combination of three vertices which gives the greatest area
                    for (int p1 = 0; p1 < numVertices - 2; p1++)
                    {
                        for (int p2 = p1 + 1; p2 < numVertices - 1; p2++)
                        {
                            for (int p3 = p2 + 1; p3 < numVertices; p3++)
                            {
                                double currentArea = Vector3D.SqrTriangleArea(BSPObject.Vertices[firstVertex + p1].Vector, BSPObject.Vertices[firstVertex + p2].Vector, BSPObject.Vertices[firstVertex + p3].Vector);
                                if (currentArea > Settings.precision * Settings.precision * 4.0)                                  // Three collinear points will generate an area of 0 or almost 0
                                {
                                    pointsWorked = true;
                                    if (currentArea > currentHighest)
                                    {
                                        currentHighest = currentArea;
                                        triangle[0]    = BSPObject.Vertices[firstVertex + p1].Vector;
                                        triangle[1]    = BSPObject.Vertices[firstVertex + p2].Vector;
                                        triangle[2]    = BSPObject.Vertices[firstVertex + p3].Vector;
                                    }
                                }
                            }
                        }
                    }
                }
            }
            else
            {
                // If face information is not available, use the brush side's info instead
                int currentTextureIndex = currentSide.Texture;
                if (currentTextureIndex >= 0)
                {
                    string mask = BSPObject.Textures[currentTextureIndex].Mask;
                    if (mask.ToUpper().Equals("ignore".ToUpper()) || mask.Length == 0)
                    {
                        texture = BSPObject.Textures[currentTextureIndex].Name;
                    }
                    else
                    {
                        texture = mask.Substring(0, (mask.Length - 4) - (0));                         // Because mask includes file extensions
                        masked  = true;
                    }
                }
                else
                {
                    // If neither face or brush side has texture info, fall all the way back to brush. I don't know if this ever happens.
                    if (brushTextureIndex >= 0)
                    {
                        // If none of them have any info, noshader
                        string mask = BSPObject.Textures[brushTextureIndex].Mask;
                        if (mask.ToUpper().Equals("ignore".ToUpper()) || mask.Length == 0)
                        {
                            texture = BSPObject.Textures[brushTextureIndex].Name;
                        }
                        else
                        {
                            texture = mask.Substring(0, (mask.Length - 4) - (0));                             // Because mask includes file extensions
                            masked  = true;
                        }
                    }
                }
            }
            if (texture.ToUpper().Equals("textures/common/vis".ToUpper()))
            {
                isVisBrush = true;
                return;                 // TODO: Try to recreate the vis entity? It's impossible to recreate the links...
            }
            // Get the lengths of the axis vectors.
            // TODO: This information seems to be contained in Q3's vertex structure. But there doesn't seem
            // to be a way to directly link faces to brush sides.
            double     UAxisLength  = 1;
            double     VAxisLength  = 1;
            double     texScaleS    = 1;
            double     texScaleT    = 1;
            Vector3D[] textureAxes  = TexInfo.textureAxisFromPlane(currentPlane);
            double     originShiftS = (textureAxes[0].X * origin[X]) + (textureAxes[0].Y * origin[Y]) + (textureAxes[0].Z * origin[Z]);
            double     originShiftT = (textureAxes[1].X * origin[X]) + (textureAxes[1].Y * origin[Y]) + (textureAxes[1].Z * origin[Z]);
            double     textureShiftS;
            double     textureShiftT;
            if (firstVertex >= 0)
            {
                textureShiftS = (double)BSPObject.Vertices[firstVertex].TexCoordX - originShiftS;
                textureShiftT = (double)BSPObject.Vertices[firstVertex].TexCoordY - originShiftT;
            }
            else
            {
                textureShiftS = 0 - originShiftS;
                textureShiftT = 0 - originShiftT;
            }
            float  texRot = 0;
            string material;
            if (masked)
            {
                material = "wld_masked";
            }
            else
            {
                material = "wld_lightmap";
            }
            double         lgtScale = 16;
            double         lgtRot   = 0;
            MAPBrushSide[] newList  = new MAPBrushSide[brushSides.Length + 1];
            for (int j = 0; j < brushSides.Length; j++)
            {
                newList[j] = brushSides[j];
            }
            int flags;
            //if(Settings.noFaceFlags) {
            flags = 0;
            //}
            if (pointsWorked)
            {
                newList[brushSides.Length] = new MAPBrushSide(currentPlane, triangle, texture, textureAxes[0].Point, textureShiftS, textureAxes[1].Point, textureShiftT, texRot, texScaleS, texScaleT, flags, material, lgtScale, lgtRot);
            }
            else
            {
                newList[brushSides.Length] = new MAPBrushSide(currentPlane, texture, textureAxes[0].Point, textureShiftS, textureAxes[1].Point, textureShiftT, texRot, texScaleS, texScaleT, flags, material, lgtScale, lgtRot);
            }
            brushSides = newList;
            numRealFaces++;
        }

        for (int i = 0; i < brushSides.Length; i++)
        {
            mapBrush.add(brushSides[i]);
        }

        brushPlanes = new Plane[mapBrush.NumSides];
        for (int i = 0; i < brushPlanes.Length; i++)
        {
            brushPlanes[i] = mapBrush[i].Plane;
        }

        if (isCoD && mapBrush.NumSides > 6)
        {
            // Now we need to get rid of all the sides that aren't used. Get a list of
            // the useless sides from one brush, and delete those sides from all of them,
            // since they all have the same sides.
            if (!Settings.dontCull && numSides > 6)
            {
                int[] badSides = MAPBrush.findUnusedPlanes(mapBrush);
                // Need to iterate backward, since these lists go from low indices to high, and
                // the index of all subsequent items changes when something before it is removed.
                if (mapBrush.NumSides - badSides.Length < 4)
                {
                    DecompilerThread.OnMessage(this, "WARNING: Plane cull returned less than 4 sides for entity " + currentEntity + " brush " + numBrshs);
                }
                else
                {
                    for (int i = badSides.Length - 1; i > -1; i--)
                    {
                        mapBrush.delete(badSides[i]);
                    }
                }
            }
        }

        if (!Settings.skipPlaneFlip)
        {
            if (mapBrush.hasBadSide())
            {
                // If there's a side that might be backward
                if (mapBrush.hasGoodSide())
                {
                    // If there's a side that is forward
                    mapBrush = MAPBrush.SimpleCorrectPlanes(mapBrush);
                    numSimpleCorrects++;
                    if (Settings.calcVerts)
                    {
                        // This is performed in advancedcorrect, so don't use it if that's happening
                        try {
                            mapBrush = MAPBrush.CalcBrushVertices(mapBrush);
                        } catch (System.NullReferenceException) {
                            DecompilerThread.OnMessage(this, "WARNING: Brush vertex calculation failed on entity " + mapBrush.Entnum + " brush " + mapBrush.Brushnum + "");
                        }
                    }
                }
                else
                {
                    // If no forward side exists
                    try {
                        mapBrush = MAPBrush.AdvancedCorrectPlanes(mapBrush);
                        numAdvancedCorrects++;
                    } catch (System.ArithmeticException) {
                        DecompilerThread.OnMessage(this, "WARNING: Plane correct returned 0 triangles for entity " + mapBrush.Entnum + " brush " + mapBrush.Brushnum + "");
                    }
                }
            }
            else
            {
                numGoodBrushes++;
            }
        }
        else
        {
            if (Settings.calcVerts)
            {
                // This is performed in advancedcorrect, so don't use it if that's happening
                try {
                    mapBrush = MAPBrush.CalcBrushVertices(mapBrush);
                } catch (System.NullReferenceException) {
                    DecompilerThread.OnMessage(this, "WARNING: Brush vertex calculation failed on entity " + mapBrush.Entnum + " brush " + mapBrush.Brushnum + "");
                }
            }
        }

        // This adds the brush we've been finding and creating to
        // the current entity as an attribute. The way I've coded
        // this whole program and the entities parser, this shouldn't
        // cause any issues at all.
        if (Settings.brushesToWorld)
        {
            mapBrush.Water = false;
            worldspawn.Brushes.Add(mapBrush);
        }
        else
        {
            mapFile[currentEntity].Brushes.Add(mapBrush);
        }
    }
Ejemplo n.º 31
0
        protected virtual void OnGUI()
        {
            GUILayout.BeginHorizontal();
            resType    = (EResType)EditorGUILayout.EnumPopup("资源目录", resType, GUILayout.MaxWidth(250));
            m_Platform = (EPlatform)EditorGUILayout.EnumPopup("平台", m_Platform, GUILayout.MaxWidth(250));
            GUILayout.EndHorizontal();
            GUILayout.BeginHorizontal();
            ETexType lastTexType = m_TexType;

            m_TexType = (ETexType)EditorGUILayout.EnumPopup("统计类型", m_TexType, GUILayout.MaxWidth(250));
            if (lastTexType != m_TexType)
            {
                m_TexInfo   = null;
                m_TexMat    = null;
                m_Tex       = null;
                m_PrefabSet = null;
            }
            EditorGUILayout.LabelField(string.Format("Total Count:{0} TotalSize:{1}KB-{2}MB ", m_TotalCount, m_TotalSize / 1024, m_TotalSize / 1024 / 1024));
            GUILayout.EndHorizontal();
            GUILayout.BeginHorizontal();
            if (GUILayout.Button("Scan", GUILayout.MaxWidth(150)))
            {
                string resPath = resPaths[(int)resType];
                FindTexs(resPath);
            }
            GUILayout.EndHorizontal();
            GUILayout.BeginHorizontal();

            GUILayout.BeginVertical();
            typeScrollPos = GUILayout.BeginScrollView(typeScrollPos, false, false, GUILayout.MinHeight(400));
            Dictionary <string, TexInfo> texMap = m_FormatMap;

            if (m_TexType == ETexType.Size)
            {
                texMap = m_SizeMap;
            }

            Dictionary <string, TexInfo> .Enumerator it = texMap.GetEnumerator();
            while (it.MoveNext())
            {
                GUILayout.BeginHorizontal();
                string  name = it.Current.Key;
                TexInfo ti   = it.Current.Value;
                EditorGUILayout.LabelField(string.Format("{0} Count:{1} Size:{2}KB-{3}MB ", name, ti.texList.Count, ti.size / 1024, ti.size / 1024 / 1024), GUILayout.MaxWidth(400));
                if (GUILayout.Button("Select", GUILayout.MaxWidth(50)))
                {
                    m_TexInfo   = ti;
                    m_TexMat    = null;
                    m_Tex       = null;
                    m_PrefabSet = null;
                }
                GUILayout.EndHorizontal();
            }
            EditorGUILayout.EndScrollView();

            GUILayout.EndVertical();

            GUILayout.BeginVertical();
            texScrollPos = GUILayout.BeginScrollView(texScrollPos, false, false, GUILayout.MinHeight(400));
            if (m_TexInfo != null)
            {
                for (int i = 0; i < m_TexInfo.texList.Count; ++i)
                {
                    GUILayout.BeginHorizontal();
                    Texture tex = m_TexInfo.texList[i];
                    if (m_TexMat != null && m_Tex == tex)
                    {
                        EditorGUILayout.ObjectField(string.Format("{0} mat:{1}", tex.name, m_TexMat.Count), tex, typeof(Texture), true, GUILayout.MaxWidth(450));
                    }
                    else
                    {
                        EditorGUILayout.ObjectField(tex.name, tex, typeof(Texture), true, GUILayout.MaxWidth(450));
                    }

                    if (GUILayout.Button("Mat", GUILayout.MaxWidth(50)))
                    {
                        m_Tex = tex;
                        m_TexMatMap.TryGetValue(m_Tex, out m_TexMat);
                        m_PrefabSet = null;
                    }
                    GUILayout.EndHorizontal();
                }
            }

            EditorGUILayout.EndScrollView();
            GUILayout.EndVertical();
            GUILayout.EndHorizontal();
            GUILayout.Space(10);
            GUILayout.BeginHorizontal();
            GUILayout.BeginVertical();
            matScrollPos = GUILayout.BeginScrollView(matScrollPos, false, false, GUILayout.MinHeight(400));
            if (m_TexMat != null)
            {
                MatPrefabMat.Enumerator texMatIt = m_TexMat.GetEnumerator();
                while (texMatIt.MoveNext())
                {
                    GUILayout.BeginHorizontal();
                    Material mat = texMatIt.Current.Key;
                    EditorGUILayout.ObjectField(mat.name, mat, typeof(Material), true, GUILayout.MaxWidth(450));

                    GUILayout.EndHorizontal();
                }
            }
            EditorGUILayout.EndScrollView();
            GUILayout.EndVertical();

            GUILayout.BeginVertical();
            prefabScrollPos = GUILayout.BeginScrollView(prefabScrollPos, false, false, GUILayout.MinHeight(500));
            if (m_PrefabSet != null)
            {
                PrefabSet.Enumerator prefabIt = m_PrefabSet.GetEnumerator();
                while (prefabIt.MoveNext())
                {
                    GUILayout.BeginHorizontal();
                    GameObject prefab = prefabIt.Current;
                    EditorGUILayout.ObjectField(prefab.name, prefab, typeof(GameObject), true, GUILayout.MaxWidth(550));
                    GUILayout.EndHorizontal();
                }
            }
            EditorGUILayout.EndScrollView();

            GUILayout.EndVertical();
            GUILayout.EndHorizontal();
        }
 public virtual TexInfo createPerpTexInfo(Plane in_Renamed)
 {
     Vector3D[] axes = TexInfo.textureAxisFromPlane(in_Renamed);
     return(new TexInfo(axes[0], 0, axes[1], 0, 0, BSPObject.findTexDataWithTexture("tools/toolsclip")));
 }
Ejemplo n.º 33
0
    // METHODS

    public void readBSP()
    {
        try {
            byte[] theLump = new byte[0];
            byte[] vis     = new byte[0];
            BSPObject = new BSP(BSPFile.FullName);
            Console.WriteLine("Opening " + BSPFile.FullName);
            for (int i = 0; i < 18; i++)
            {
                try {
                    theLump = readLumpNum(i);
                    switch (i)
                    {
                    case 0:
                        BSPObject.Entities = Entity.createLump(theLump);
                        break;

                    case 1:
                        BSPObject.Planes = Plane.createLump(theLump);
                        break;

                    case 2:
                        BSPObject.Textures = Texture.createLump(theLump);
                        break;

                    case 3:
                        BSPObject.Materials = Texture.createLump(theLump);
                        break;

                    case 4:
                        BSPObject.Vertices = Vertex.createLump(theLump);
                        break;

                    case 5:
                        BSPObject.Normals = new Lump <LumpObject>(theLump.Length, 0);
                        break;

                    case 6:
                        BSPObject.Indices = new NumList(theLump, NumList.dataType.UINT);
                        break;

                    case 7:
                        vis = theLump;
                        break;

                    case 8:
                        BSPObject.Nodes = Node.createLump(theLump);
                        break;

                    case 9:
                        BSPObject.Faces = Face.createLump(theLump);
                        break;

                    case 10:
                        BSPObject.Lightmaps = new NumList(theLump, NumList.dataType.UBYTE);
                        break;

                    case 11:
                        BSPObject.Leaves = Leaf.createLump(theLump);
                        break;

                    case 12:
                        BSPObject.MarkSurfaces = new NumList(theLump, NumList.dataType.UINT);
                        break;

                    case 13:
                        BSPObject.MarkBrushes = new NumList(theLump, NumList.dataType.UINT);
                        break;

                    case 14:
                        BSPObject.Models = Model.createLump(theLump);
                        break;

                    case 15:
                        BSPObject.Brushes = Brush.createLump(theLump);
                        break;

                    case 16:
                        BSPObject.BrushSides = BrushSide.createLump(theLump);
                        break;

                    case 17:
                        BSPObject.TexInfo = TexInfo.createLump(theLump);
                        break;
                    }
                } catch {
                    dumpLump(theLump);
                }
            }
            try {
                int visLength = BSPObject.Leaves[2].PVS;
                if (visLength > 0 && vis.Length > 0)
                {
                    BSPObject.Vis = new Lump <LumpObject>(vis, visLength);
                }
            } catch (ArgumentOutOfRangeException) {; }
            if (BSPObject.Vis == null)
            {
                BSPObject.Vis = new Lump <LumpObject>(0, 0);
            }
            BSPObject.printBSPReport();
        }
        catch (System.IO.IOException) {
            Console.WriteLine("Unable to access BSP file! Is it open in another program?");
        }
        br.Close();
    }
Ejemplo n.º 34
0
        private void InnerScanTex(Texture tex, string texPath)
        {
            AssetImporter   assetImport = AssetImporter.GetAtPath(texPath);
            TextureImporter texImport   = assetImport as TextureImporter;

            if (texImport == null)
            {
                XDebug.LogError(texPath);
                return;
            }
            int texSize = 0;
            TextureImporterFormat format;

            texImport.GetPlatformTextureSettings(m_Platform.ToString(), out texSize, out format);
            long sizePer32 = 1;

            switch (format)
            {
            case TextureImporterFormat.ETC_RGB4:
                sizePer32 = 1;
                break;

            case TextureImporterFormat.RGB24:
                sizePer32 = 6;
                break;

            case TextureImporterFormat.RGBA16:
                sizePer32 = 4;
                break;

            case TextureImporterFormat.RGBA32:
                sizePer32 = 8;
                break;

            case TextureImporterFormat.Alpha8:
                sizePer32 = 2;
                break;
            }
            long    size      = tex.width * tex.height * sizePer32 / 2;
            string  sizeStr   = string.Format("{0}x{0}", tex.width, tex.height);
            string  formatStr = format.ToString();
            TexInfo ti        = null;

            if (!m_FormatMap.TryGetValue(formatStr, out ti))
            {
                ti = new TexInfo();
                m_FormatMap.Add(formatStr, ti);
            }
            ti.texList.Add(tex);
            ti.size += size;

            ti = null;
            if (!m_SizeMap.TryGetValue(sizeStr, out ti))
            {
                ti = new TexInfo();
                m_SizeMap.Add(sizeStr, ti);
            }
            ti.texList.Add(tex);
            ti.size     += size;
            m_TotalSize += size;
            m_TotalCount++;
        }
Ejemplo n.º 35
0
    // -decompileBrush38(Brush, int, boolean)
    // Decompiles the Brush and adds it to entitiy #currentEntity as .MAP data.
    private void decompileBrush(Brush brush, int currentEntity)
    {
        Vector3D origin    = mapFile[currentEntity].Origin;
        int      firstSide = brush.FirstSide;
        int      numSides  = brush.NumSides;
        bool     isDetail  = false;

        MAPBrushSide[] brushSides = new MAPBrushSide[numSides];
        if (!Settings.noDetail && (brush.Contents[3] & ((sbyte)1 << 3)) != 0)
        {
            // According to Q2's source, this is the detail flag
            isDetail = true;
        }
        MAPBrush mapBrush = new MAPBrush(numBrshs, currentEntity, isDetail);

        //DecompilerThread.OnMessage(this, ": " + numSides + " sides");
        if (!Settings.noWater && (brush.Contents[0] & ((sbyte)1 << 5)) != 0)
        {
            mapBrush.Water = true;
        }
        for (int i = 0; i < numSides; i++)
        {
            // For each side of the brush
            Vector3D[] plane        = new Vector3D[3];                     // Three points define a plane. All I have to do is find three points on that plane.
            BrushSide  currentSide  = BSPObject.BrushSides[firstSide + i];
            Plane      currentPlane = BSPObject.Planes[currentSide.Plane]; // To find those three points, I must extrapolate from planes until I find a way to associate faces with brushes
            Texture    currentTexture;
            bool       isDuplicate = false;
            for (int j = i + 1; j < numSides; j++)
            {
                // For each subsequent side of the brush
                // For some reason, QUAKE 2 MAKES COPLANAR SIDES OF BRUSHES. I don't know why but it's stupid.
                if (currentPlane.Equals(BSPObject.Planes[BSPObject.BrushSides[firstSide + j].Plane]))
                {
                    DecompilerThread.OnMessage(this, "WARNING: Duplicate planes in entity " + currentEntity + " brush " + numBrshs + ", sides " + i + " and " + j + " (BSP planes " + currentSide.Plane + " and " + BSPObject.BrushSides[firstSide + j].Plane);
                    isDuplicate = true;
                }
            }
            if (!isDuplicate)
            {
                /*
                 * if(!Settings.planarDecomp) {
                 * // Find a face whose plane and texture information corresponds to the current side
                 * // It doesn't really matter if it's the actual brush's face, just as long as it provides vertices.
                 * SiNFace currentFace=null;
                 * boolean faceFound=false;
                 * for(int j=0;j<BSP.getSFaces().size();j++) {
                 * currentFace=BSP.getSFaces().getFace(j);
                 * if(currentFace.getPlane()==currentSide.getPlane() && currentFace.getTexInfo()==currentSide.getTexInfo() && currentFace.getNumEdges()>1) {
                 * faceFound=true;
                 * break;
                 * }
                 * }
                 * if(faceFound) {
                 * int markEdge=BSP.getMarkEdges().getInt(currentFace.getFirstEdge());
                 * int currentMarkEdge=0;
                 * int firstVertex;
                 * int secondVertex;
                 * if(markEdge>0) {
                 * firstVertex=BSP.getEdges().getEdge(markEdge).getFirstVertex();
                 * secondVertex=BSP.getEdges().getEdge(markEdge).getSecondVertex();
                 * } else {
                 * firstVertex=BSP.getEdges().getEdge(-markEdge).getSecondVertex();
                 * secondVertex=BSP.getEdges().getEdge(-markEdge).getFirstVertex();
                 * }
                 * int numVertices=currentFace.getNumEdges()+1;
                 * boolean pointsWorked=false;
                 * plane[0]=new Vector3D(BSP.getVertices().getVertex(firstVertex)); // Grab and store the first one
                 * plane[1]=new Vector3D(BSP.getVertices().getVertex(secondVertex)); // The second should be unique from the first
                 * boolean second=false;
                 * if(plane[0].equals(plane[1])) { // If for some messed up reason they are the same
                 * for(currentMarkEdge=1;currentMarkEdge<currentFace.getNumEdges();currentMarkEdge++) { // For each edge after the first one
                 * markEdge=BSP.getMarkEdges().getInt(currentFace.getFirstEdge()+currentMarkEdge);
                 * if(markEdge>0) {
                 * plane[1]=new Vector3D(BSP.getVertices().getVertex(BSP.getEdges().getEdge(markEdge).getFirstVertex()));
                 * } else {
                 * plane[1]=new Vector3D(BSP.getVertices().getVertex(BSP.getEdges().getEdge(-markEdge).getSecondVertex()));
                 * }
                 * if(!plane[0].equals(plane[1])) { // Make sure the point isn't the same as the first one
                 * second=false;
                 * break; // If it isn't the same, this point is good
                 * } else {
                 * if(markEdge>0) {
                 * plane[1]=new Vector3D(BSP.getVertices().getVertex(BSP.getEdges().getEdge(markEdge).getSecondVertex()));
                 * } else {
                 * plane[1]=new Vector3D(BSP.getVertices().getVertex(BSP.getEdges().getEdge(-markEdge).getFirstVertex()));
                 * }
                 * if(!plane[0].equals(plane[1])) {
                 * second=true;
                 * break;
                 * }
                 * }
                 * }
                 * }
                 * if(second) {
                 * currentMarkEdge++;
                 * }
                 * for(;currentMarkEdge<currentFace.getNumEdges();currentMarkEdge++) {
                 * markEdge=BSP.getMarkEdges().getInt(currentFace.getFirstEdge()+currentMarkEdge);
                 * if(second) {
                 * if(markEdge>0) {
                 * plane[2]=new Vector3D(BSP.getVertices().getVertex(BSP.getEdges().getEdge(markEdge).getFirstVertex()));
                 * } else {
                 * plane[2]=new Vector3D(BSP.getVertices().getVertex(BSP.getEdges().getEdge(-markEdge).getSecondVertex()));
                 * }
                 * if(!plane[2].equals(plane[0]) && !plane[2].equals(plane[1])) { // Make sure no point is equal to the third one
                 * if((Vector3D.crossProduct(plane[0].subtract(plane[1]), plane[0].subtract(plane[2])).X!=0) || // Make sure all
                 * (Vector3D.crossProduct(plane[0].subtract(plane[1]), plane[0].subtract(plane[2])).Y!=0) || // three points
                 * (Vector3D.crossProduct(plane[0].subtract(plane[1]), plane[0].subtract(plane[2])).Z!=0)) { // are not collinear
                 * pointsWorked=true;
                 * break;
                 * }
                 * }
                 * }
                 * // if we get to here, the first vertex of the edge failed, or was already used
                 * if(markEdge>0) { // use the second vertex
                 * plane[2]=new Vector3D(BSP.getVertices().getVertex(BSP.getEdges().getEdge(markEdge).getSecondVertex()));
                 * } else {
                 * plane[2]=new Vector3D(BSP.getVertices().getVertex(BSP.getEdges().getEdge(-markEdge).getFirstVertex()));
                 * }
                 * if(!plane[2].equals(plane[0]) && !plane[2].equals(plane[1])) { // Make sure no point is equal to the third one
                 * if((Vector3D.crossProduct(plane[0].subtract(plane[1]), plane[0].subtract(plane[2])).X!=0) || // Make sure all
                 * (Vector3D.crossProduct(plane[0].subtract(plane[1]), plane[0].subtract(plane[2])).Y!=0) || // three points
                 * (Vector3D.crossProduct(plane[0].subtract(plane[1]), plane[0].subtract(plane[2])).Z!=0)) { // are not collinear
                 * pointsWorked=true;
                 * break;
                 * }
                 * }
                 * // If we get here, neither point worked and we need to try the next edge.
                 * second=true;
                 * }
                 * if(!pointsWorked) {
                 * plane=Plane.generatePlanePoints(currentPlane);
                 * }
                 * } else { // Face not found
                 * plane=Plane.generatePlanePoints(currentPlane);
                 * }
                 * } else { // Planar decomp only */
                plane = Plane.generatePlanePoints(currentPlane);
                // }
                string   texture   = "special/clip";
                double[] textureU  = new double[3];
                double[] textureV  = new double[3];
                double   UShift    = 0;
                double   VShift    = 0;
                double   texScaleU = 1;
                double   texScaleV = 1;
                if (currentSide.Texture > -1)
                {
                    currentTexture = BSPObject.Textures[currentSide.Texture];
                    if ((currentTexture.Flags[0] & ((sbyte)1 << 2)) != 0)
                    {
                        texture = "special/sky";
                    }
                    else
                    {
                        if ((currentTexture.Flags[1] & ((sbyte)1 << 1)) != 0)
                        {
                            texture = "special/skip";
                        }
                        else
                        {
                            if ((currentTexture.Flags[1] & ((sbyte)1 << 0)) != 0)
                            {
                                if (currentEntity == 0)
                                {
                                    texture = "special/hint";                                     // Hint was not used the same way in Quake 2 as other games.
                                }
                                else
                                {
                                    // For example, a Hint brush CAN be used for a trigger in Q2 and is used as such a lot.
                                    texture = "special/trigger";
                                }
                            }
                            else
                            {
                                texture = currentTexture.Name;
                            }
                        }
                    }
                    // Get the lengths of the axis vectors
                    double SAxisLength = System.Math.Sqrt(System.Math.Pow((double)currentTexture.TexAxes.SAxis.X, 2) + System.Math.Pow((double)currentTexture.TexAxes.SAxis.Y, 2) + System.Math.Pow((double)currentTexture.TexAxes.SAxis.Z, 2));
                    double TAxisLength = System.Math.Sqrt(System.Math.Pow((double)currentTexture.TexAxes.TAxis.X, 2) + System.Math.Pow((double)currentTexture.TexAxes.TAxis.Y, 2) + System.Math.Pow((double)currentTexture.TexAxes.TAxis.Z, 2));
                    // In compiled maps, shorter vectors=longer textures and vice versa. This will convert their lengths back to 1. We'll use the actual scale values for length.
                    texScaleU   = (1 / SAxisLength);                   // Let's use these values using the lengths of the U and V axes we found above.
                    texScaleV   = (1 / TAxisLength);
                    textureU[0] = ((double)currentTexture.TexAxes.SAxis.X / SAxisLength);
                    textureU[1] = ((double)currentTexture.TexAxes.SAxis.Y / SAxisLength);
                    textureU[2] = ((double)currentTexture.TexAxes.SAxis.Z / SAxisLength);
                    textureV[0] = ((double)currentTexture.TexAxes.TAxis.X / TAxisLength);
                    textureV[1] = ((double)currentTexture.TexAxes.TAxis.Y / TAxisLength);
                    textureV[2] = ((double)currentTexture.TexAxes.TAxis.Z / TAxisLength);
                    UShift      = (double)currentTexture.TexAxes.SShift;
                    VShift      = (double)currentTexture.TexAxes.TShift;
                }
                else
                {
                    Vector3D[] axes = TexInfo.textureAxisFromPlane(currentPlane);
                    textureU = axes[0].Point;
                    textureV = axes[1].Point;
                }
                double originShiftU  = (textureU[0] * origin[X] + textureU[1] * origin[Y] + textureU[2] * origin[Z]) / texScaleU;
                double textureShiftU = UShift - originShiftU;
                double originShiftV  = (textureV[0] * origin[X] + textureV[1] * origin[Y] + textureV[2] * origin[Z]) / texScaleV;
                double textureShiftV = VShift - originShiftV;
                float  texRot        = 0;              // In compiled maps this is calculated into the U and V axes, so set it to 0 until I can figure out a good way to determine a better value.
                int    flags         = 0;              // Set this to 0 until we can somehow associate faces with brushes
                string material      = "wld_lightmap"; // Since materials are a NightFire only thing, set this to a good default
                double lgtScale      = 16;             // These values are impossible to get from a compiled map since they
                double lgtRot        = 0;              // are used by RAD for generating lightmaps, then are discarded, I believe.
                brushSides[i] = new MAPBrushSide(plane, texture, textureU, textureShiftU, textureV, textureShiftV, texRot, texScaleU, texScaleV, flags, material, lgtScale, lgtRot);
                mapBrush.add(brushSides[i]);
            }
        }

        if (!Settings.skipPlaneFlip)
        {
            if (mapBrush.hasBadSide())
            {
                // If there's a side that might be backward
                if (mapBrush.hasGoodSide())
                {
                    // If there's a side that is forward
                    mapBrush = MAPBrush.SimpleCorrectPlanes(mapBrush);
                    numSimpleCorrects++;
                    if (Settings.calcVerts)
                    {
                        // This is performed in advancedcorrect, so don't use it if that's happening
                        try
                        {
                            mapBrush = MAPBrush.CalcBrushVertices(mapBrush);
                        }
                        catch (System.NullReferenceException)
                        {
                            DecompilerThread.OnMessage(this, "WARNING: Brush vertex calculation failed on entity " + mapBrush.Entnum + " brush " + mapBrush.Brushnum + "");
                        }
                    }
                }
                else
                {
                    // If no forward side exists
                    try
                    {
                        mapBrush = MAPBrush.AdvancedCorrectPlanes(mapBrush);
                        numAdvancedCorrects++;
                    }
                    catch (System.ArithmeticException)
                    {
                        DecompilerThread.OnMessage(this, "WARNING: Plane correct returned 0 triangles for entity " + mapBrush.Entnum + " brush " + mapBrush.Brushnum + "");
                    }
                }
            }
            else
            {
                numGoodBrushes++;
            }
        }
        else
        {
            if (Settings.calcVerts)
            {
                // This is performed in advancedcorrect, so don't use it if that's happening
                try
                {
                    mapBrush = MAPBrush.CalcBrushVertices(mapBrush);
                }
                catch (System.NullReferenceException)
                {
                    DecompilerThread.OnMessage(this, "WARNING: Brush vertex calculation failed on entity " + mapBrush.Entnum + " brush " + mapBrush.Brushnum + "");
                }
            }
        }

        // This adds the brush we've been finding and creating to
        // the current entity as an attribute. The way I've coded
        // this whole program and the entities parser, this shouldn't
        // cause any issues at all.
        if (Settings.brushesToWorld)
        {
            mapBrush.Water = false;
            mapFile[0].Brushes.Add(mapBrush);
        }
        else
        {
            mapFile[currentEntity].Brushes.Add(mapBrush);
        }
    }