Пример #1
0
    static Material doMaterials(NIFFile nf, NiMesh mesh, GameObject go)
    {
        StringBuilder strB = new StringBuilder(20);

        if (standardShader == null)
        {
            standardShader = Shader.Find("Standard");
        }

        bool     IS_TERRAIN     = (nf.getStringTable().Contains("terrainL1"));
        bool     animated       = false;
        bool     presetMaterial = false;
        string   materialName   = null;
        Material mat            = null;


        Material mat2 = null;

        if (mesh.materialNames.Count > 0)
        {
            strB.Length = 0;
            strB.Append("materials/");
            strB.Append(mesh.materialNames[0]);
            mat2 = Resources.Load <Material>(strB.ToString());
            if (mat2 != null)
            {
                mat = Material.Instantiate <Material>(mat2);
            }
        }
        else
        {
            Debug.LogWarning("No mesh materials found in mesh :" + mesh.name);
        }

        if (mat == null)
        {
            // do materials/textures

            if (IS_TERRAIN)
            {
                materialName = "terrainmat";
            }

            if (mesh.materialNames.Contains("Ocean_Water_Shader") || mesh.materialNames.Contains("Flow_Water") || mesh.name.Contains("water_UP") || mesh.name.Contains("water_DOWN"))
            {
                materialName = "WaterMaterial";
            }

            bool alpha = (mesh.materialNames.Contains("TwoSided_Alpha_Specular") || mesh.materialNames.Contains("Lava_Flow_Decal"));
            foreach (string n in mesh.materialNames)
            {
                if (n.ToLower().Contains("alpha"))
                {
                    alpha = true;
                }
            }
            if (alpha)
            {
                materialName = "2sidedtransmat_fade";
            }

            // handle some simple animated "scrolling" textures
            animated = (mesh.materialNames.Contains("Additive_UVScroll_Distort") || mesh.materialNames.Contains("Lava_Flow_Decal") || mesh.materialNames.Contains("Local_Cloud_Flat") ||
                        mesh.materialNames.Contains("Alpha_UVScroll_Overlay_Foggy_Waterfall") || mesh.materialNames.Contains("Fat_spike12_m") || mesh.materialNames.Contains("pPlane1_m"));


            if (animated)
            {
                materialName = "2sidedtransmat_fade";
            }



            foreach (int eid in mesh.extraDataIDs)
            {
                NIFObject obj = nf.getObject(eid);
                if (obj is NiBooleanExtraData)
                {
                    NiBooleanExtraData fExtra = (NiBooleanExtraData)obj;
                    switch (fExtra.extraDataString)
                    {
                    case "doAlphaTest":
                        if (fExtra.booleanData)
                        {
                            materialName = "2sidedtransmat";
                        }
                        break;

                    default:
                        break;
                    }
                }
            }
            if (materialName == null)
            {
                if (standardMaterial == null)
                {
                    standardMaterial = new Material(standardShader);
                }
                mat          = Material.Instantiate(standardMaterial);
                materialName = standardMaterial.name;
            }
            else
            {
                mat = Material.Instantiate(Resources.Load <Material>(materialName));
            }
            //Debug.Log("Using guessed material[" + materialName + "] for " + mesh.name + " from list of materials: " + string.Join(",", mesh.materialNames.ToArray()), go);
        }
        else if (mat2 != null)
        {
            materialName   = mat2.name;
            presetMaterial = true;
            //Debug.Log("Using actual material[" + materialName + "] for " + mesh.name + " from list of materials: " + string.Join(",", mesh.materialNames.ToArray()), go);
        }
        else
        {
            Debug.LogWarning("No material found!?");
        }
#if UNITY_EDITOR
        MeshOriginalMaterial mom = go.AddComponent <MeshOriginalMaterial>();
        if (mesh.materialNames.Count > 0)
        {
            mom.materialName = mesh.materialNames[0];
        }
#endif

        if (presetMaterial)
        {
            foreach (int extraId in mesh.extraDataIDs)
            {
                NIFObject obj = nf.getObject(extraId);
                setMaterialProperty(mat, obj);
            }

            if (mat.HasProperty("doAlphaTest"))
            {
                if (mat.GetInt("doAlphaTest") == 0)
                {
                    strB.Length = 0;
                    strB.Append("materials/");
                    strB.Append(mat2.name);
                    strB.Append("_shader_opaque");

                    string shaderName = strB.ToString();
                    //Debug.Log("loading opaque shader:" + shaderName, go);
                    Shader shader = Resources.Load <Shader>(shaderName);
                    if (shader != null)
                    {
                        mat.shader = shader;
                    }
                }
            }
        }

        mat.enableInstancing = true;
        mat.EnableKeyword("_SPECULARHIGHLIGHTS_OFF");



        if (animated)
        {
            NiFloatsExtraData extra = getFloatsExtraData(nf, mesh, "tex0ScrollRate");
            if (extra != null)
            {
                UVScroll scroller = go.AddComponent <UVScroll>();
                scroller.material = mat;

                scroller.xRate = extra.floatData[0];
                scroller.yRate = extra.floatData[1];
            }
        }

        foreach (int eid in mesh.extraDataIDs)
        {
            NIFObject obj = nf.getObject(eid);
            if (obj is NiFloatExtraData)
            {
                NiFloatExtraData fExtra = (NiFloatExtraData)obj;
                switch (fExtra.extraDataString)
                {
                case "scaleY":
                    if (mat.HasProperty("_MainTex"))
                    {
                        mat.mainTextureScale = new Vector2(mat.mainTextureScale.x, fExtra.floatData);
                    }
                    else
                    {
                        if (mat.HasProperty("scaleY"))
                        {
                            mat.SetFloat("scaleY", fExtra.floatData);
                        }
                        else
                        {
                            Debug.LogWarning("While trying to set scaleY, material[" + mat.name + "][" + materialName + "] doesn't have an appropriate texture property");
                        }
                    }
                    break;

                case "scale":
                    if (mat.HasProperty("_MainTex"))
                    {
                        mat.mainTextureScale = new Vector2(fExtra.floatData, mat.mainTextureScale.y);
                    }
                    else
                    {
                        if (mat.HasProperty("scale"))
                        {
                            mat.SetFloat("scale", fExtra.floatData);
                        }
                        else
                        {
                            Debug.LogWarning("While trying to set scale, material[" + mat.name + "][" + materialName + "] doesn't have an appropriate texture property");
                        }
                    }
                    break;

                default:
                    break;
                }
            }
        }

        string[] textureNameIds = getTextureIds(nf, mesh);

        if (presetMaterial)
        {
            foreach (int extraId in mesh.extraDataIDs)
            {
                NIFObject obj = nf.getObject(extraId);
                setMaterialProperty(mat, obj);
            }
        }

        if (mat.HasProperty("alphaTestRef"))
        {
            mat.SetFloat("alphaTestRef", 1.0f - mat.GetFloat("alphaTestRef"));
        }

        List <int> propIDs = mesh.nodePropertyIDs;
        foreach (int propID in propIDs)
        {
            NIFObject obj = nf.getObject(propID);

            if (obj is NiTexturingProperty)
            {
                NiTexturingProperty propObj = (NiTexturingProperty)obj;
                foreach (NifTexMap tex in propObj.texList)
                {
                    if (tex != null)
                    {
                        Debug.Log("\t" + tex.sourceTexLinkID);
                    }
                }

                int i = 0;
                foreach (NifTexMap tex in propObj.shaderMapList)
                {
                    string texName = "";
                    if (tex != null)
                    {
                        int sourceTexID = tex.sourceTexLinkID;
                        if (sourceTexID != -1)
                        {
                            NiSourceTexture sourceTex = (NiSourceTexture)nf.getObject(sourceTexID);
                            texName = sourceTex.texFilename;
                            if (presetMaterial)
                            {
                                strB.Length = 0;
                                if (IS_TERRAIN)
                                {
                                    strB.Append("_terrain");
                                    strB.Append(i);
                                }
                                else
                                {
                                    strB.Append("_");
                                    strB.Append(textureNameIds[i]);
                                }

                                // Debug.Log("attempt to set texture property :" + propertyName + " with texure:" + texName);

                                enqueSetTexture(mat, strB.ToString(), nf, texName);
                                //mat.SetTexture(propertyName, loadTexture(nf, texName));
                            }
                            else if (IS_TERRAIN)
                            {
                                strB.Length = 0;
                                strB.Append("_terrain");
                                strB.Append(i);
                                string param = strB.ToString();
                                //"_terrain" + i;
                                //Debug.Log("set " + param + " to " + texName + " mat:" + mat.name);
                                enqueSetTexture(mat, param, nf, texName);
                                //mat.SetTexture(param, loadTexture(nf, texName));
                            }
                            else
                            {
                                //Debug.Log("texName[" + texName + "]: id:" + textureNameIds[i]);
                                try
                                {
                                    switch (textureNameIds[i])
                                    {
                                    case "skyGradientTexture0":
                                    case "diffuseTexture":
                                    case "diffuseTextureXZ":
                                        enqueSetTexture(mat, "_MainTex", nf, texName);
                                        //mat.SetTexture("_MainTex", loadTexture(nf, texName));
                                        break;

                                    case "decalNormalTexture":
                                        enqueSetTexture(mat, "_DetailNormalMap", nf, texName);
                                        //mat.SetTexture("_DetailNormalMap", loadTexture(nf, texName));
                                        break;

                                    case "normalTexture":
                                        enqueSetTexture(mat, "_BumpMap", nf, texName);
                                        //mat.SetTexture("_BumpMap", loadTexture(nf, texName));
                                        break;

                                    case "glowTexture":
                                        mat.EnableKeyword("_EMISSION");
                                        if (mesh.materialNames.Contains("Lava_Flow_Decal"))
                                        {
                                            mat.SetColor("_EmissionColor", Color.red);
                                        }
                                        else
                                        {
                                            mat.SetColor("_EmissionColor", Color.white * 0.5f);
                                        }
                                        enqueSetTexture(mat, "_EmissionMap", nf, texName);
                                        //mat.SetTexture("_EmissionMap", loadTexture(nf, texName));
                                        break;

                                    case "glossTexture":
                                        enqueSetTexture(mat, "_MetallicGlossMap", nf, texName);
                                        //mat.SetTexture("_MetallicGlossMap", loadTexture(nf, texName));
                                        break;

                                    case "decalTexture":
                                    case "starMapTexture0":
                                        enqueSetTexture(mat, "_DetailAlbedoMap", nf, texName);
                                        //mat.SetTexture("_DetailAlbedoMap", loadTexture(nf, texName));
                                        break;

                                    default:
                                        //Debug.LogWarning("No shader material property for " + textureNameIds[i]);
                                        break;
                                    }
                                }catch (ArgumentOutOfRangeException ex)
                                {
                                    Debug.LogWarning("Texture id[" + i + "] was out of range of the texture name ids: " + textureNameIds.ToList());
                                    //mat.SetTexture("_MainTex", loadTexture(nf, texName));
                                    enqueSetTexture(mat, "_MainTex", nf, texName);
                                }
                            }
                        }
                    }
                    i++;
                }
            }
        }
        return(mat);
    }
Пример #2
0
    /// <summary>
    /// This method needs to be called within an Update method from unity. As such, it should be pretty quick
    /// </summary>
    /// <param name="nf"></param>
    /// <param name="mesh"></param>
    /// <param name="meshData"></param>
    /// <param name="skinMesh"></param>
    /// <returns></returns>
    static GameObject processMesh(NIFFile nf, NiMesh mesh, NIFFile.MeshData meshData, bool skinMesh)
    {
        //Debug.Log("process mesh:" + mesh.name);
        GameObject go = new GameObject();

        go.name = mesh.name;
        if (mesh.name.Length == 0)
        {
            go.name = "mesh";
        }
        go.transform.localPosition = new Vector3(mesh.translation.x, mesh.translation.y, mesh.translation.z);
        Mesh       newMesh = new Mesh();
        MeshFilter mf      = go.AddComponent <MeshFilter>();

        Renderer r;

        if (!skinMesh)
        {
            r = go.AddComponent <MeshRenderer>();
        }
        else
        {
            r = go.AddComponent <SkinnedMeshRenderer>();
            // needed to force Unity to use 2 bones. RIFT exposes 3 bones, and if we let Unity choose, it'll try to use 4
            // which will make models look wrong
            ((SkinnedMeshRenderer)r).quality    = SkinQuality.Bone2;
            ((SkinnedMeshRenderer)r).sharedMesh = newMesh;
        }

        mf.mesh = newMesh;
        if (Assets.GameWorld.useColliders)
        {
            MeshCollider mc = go.AddComponent <MeshCollider>();
            mc.sharedMesh = newMesh;
        }
        newMesh.subMeshCount = mesh.numSubMeshes;
        if (mesh.meshPrimType != 0) // Triangles
        {
            Debug.Log("unknown meshPrimType:" + mesh.meshPrimType);
        }
        else
        {
            bool IS_TERRAIN = (nf.getStringTable().Contains("terrainL1"));

            newMesh.SetVertices(meshData.verts);
            if (meshData.inNormals.Count > 0)
            {
                newMesh.SetNormals(meshData.inNormals);
            }
            if (meshData.uvs.Count > 0)
            {
                newMesh.SetUVs(0, meshData.uvs);
            }
            if (meshData.boneWeights.Count > 0 && !IS_TERRAIN && skinMesh)
            {
                newMesh.boneWeights = meshData.boneWeights.ToArray();
            }
            // huge memory GC issue here....
            newMesh.triangles = meshData.tristest;
            r.material        = doMaterials(nf, mesh, go);
        }
        return(go);
    }