Exemple #1
0
    /// <summary>
    /// Creates the SuperPlane mesh based on the existing parameters. aFullBuild tells it whether or not to calculate some of the more time expensive items, such as lightmap UVs.
    /// </summary>
    /// <param name="aFullBuild">Do time consuming calculations (lightmap UVs), or just the bare essentials?</param>
    public void Build(bool aFullBuild)
    {
        MeshFilter filter   = GetComponent <MeshFilter>();
        Renderer   r        = GetComponent <Renderer>();
        Mesh       m        = filter.sharedMesh;
        string     thisName = "FerrSuperPlane_" + gameObject.name + "_" + gameObject.GetInstanceID();

        // Make sure there's a mesh for us to build into!
        if (m == null)
        {
            m = new Mesh();
        }
        if (m.name == "")
        {
            m.name = thisName;
        }
        else if (m.name.Contains("FerrSuperPlane_") && m.name != thisName)
        {
            m      = new Mesh();
            m.name = thisName;
        }

        // figure out how many slices go onto the mesh
        int sliceX = 2;
        int sliceY = 2;

        if (mSliceFaces)
        {
            sliceX = Mathf.Max(2, (int)(mExtents.x / mSliceDistance) + 1);
            sliceY = Mathf.Max(2, (int)(mExtents.z / mSliceDistance) + 1);
        }

        int            vCount  = sliceX * sliceY;
        List <Vector3> verts   = new List <Vector3>(vCount);
        List <Vector2> uvs     = new List <Vector2>(vCount);
        List <Vector3> norms   = new List <Vector3>(vCount);
        List <Vector4> tans    = new List <Vector4>(vCount);
        List <Color>   colors  = new List <Color>(vCount);
        List <int>     indices = new List <int>((sliceX - 1) * (sliceY - 1) * 6);

        // calculate the uv step amount based on its aspect ratio
        float uvRatio = 1;

        if (r.sharedMaterial != null && r.sharedMaterial.mainTexture != null)
        {
            uvRatio = r.sharedMaterial.mainTexture.width / r.sharedMaterial.mainTexture.height;
        }

        // Create the plane itself
        SuperCubeUtil.AddFace(transform.localToWorldMatrix, Matrix4x4.TRS(Vector3.zero, Quaternion.Euler(90, 0, 0), new Vector3(mExtents.x, mExtents.z, 1)), 0, mUVType, mUVOffset, mUVTile, 0, mExtents.z * uvRatio / mExtents.y, sliceX, sliceY, ref verts, ref uvs, ref norms, ref tans, ref indices);

        // TODO: Improve plane color sampling for 1.1
        // Resample mesh colors
        if (m.colors != null && m.colors.Length > 0)
        {
            SuperCubeUtil.ResampleColors(ref colors, sliceX, sliceY, m.colors, 0, mPrevSlicesX, mPrevSlicesY);
        }
        else
        {
            for (int i = 0; i < verts.Count; ++i)
            {
                colors.Add(Color.white);
            }
        }

        if (verts.Count >= 65000)
        {
            Debug.LogWarning("SuperCube has too many vertices (more than 65,000)! Please increase Slice Distance, or hide unnecessary faces!");
            return;
        }
                #if UNITY_EDITOR
        if (verts.Count > 500 && aFullBuild && UnityEditor.GameObjectUtility.AreStaticEditorFlagsSet(gameObject, UnityEditor.StaticEditorFlags.LightmapStatic))
        {
            Debug.LogWarning("Unwrapping for lightmaps may take a long time to calculate (" + verts.Count + " vertices)! You can disable this calculation by unchecking Lightmap Static in your GameObject's static settings! Try enabling it once after your object has been placed properly, or increase the Slice Distance!");
        }
                #endif

        // Set the mesh data
        m.Clear();
        m.vertices = verts.ToArray();
        m.normals  = norms.ToArray();
        m.uv       = uvs.ToArray();
        m.tangents = tans.ToArray();
        m.colors   = colors.ToArray();
        m.SetIndices(indices.ToArray(), MeshTopology.Triangles, 0);

        // Additional mesh processing
        m.RecalculateBounds();
                #if UNITY_EDITOR
        if (aFullBuild && UnityEditor.GameObjectUtility.AreStaticEditorFlagsSet(gameObject, UnityEditor.StaticEditorFlags.LightmapStatic))
        {
            UnityEditor.Unwrapping.GenerateSecondaryUVSet(m);
        }
                #endif

        // Set the mesh, and update any box colliders on the object!
        filter.sharedMesh = m;
        BoxCollider collider = GetComponent <BoxCollider>();
        if (collider != null)
        {
            collider.center = Vector3.zero;
            collider.size   = new Vector3(mExtents.x, 0, mExtents.z);
        }

        // Remember the number of  slices for color resampling!
        mPrevSlicesX = sliceX;
        mPrevSlicesY = sliceY;
    }
Exemple #2
0
    /// <summary>
    /// Creates the SuperCube mesh based on the existing parameters. aFullBuild tells it whether or not to calculate some of the more time expensive items, such as lightmap UVs.
    /// </summary>
    /// <param name="aFullBuild">Do time consuming calculations (lightmap UVs, editor only), or just the bare essentials?</param>
    public void Build(bool aFullBuild)
    {
        MeshFilter filter   = GetComponent <MeshFilter>();
        Renderer   r        = GetComponent <Renderer>();
        Mesh       m        = filter.sharedMesh;
        string     thisName = "FerrSuperCube_" + gameObject.name + "_" + gameObject.GetInstanceID();

        // Make sure there's a mesh for us to build into!
        if (m == null)
        {
            m = new Mesh();
        }
        if (m.name == "")
        {
            m.name = thisName;
        }
        else if (m.name.Contains("FerrSuperCube_") && m.name != thisName)
        {
            m      = new Mesh();
            m.name = thisName;
        }

        Matrix4x4      transMat = transform.localToWorldMatrix;
        int            vCount   = GetVertCount();
        List <Vector3> verts    = new List <Vector3>(vCount);
        List <Vector2> uvs      = new List <Vector2>(vCount);
        List <Vector3> norms    = new List <Vector3>(vCount);
        List <Vector4> tans     = new List <Vector4>(vCount);
        List <Color>   colors   = new List <Color>(vCount);

        List <List <int> > indexList = new List <List <int> >();
        List <Material>    materials = new List <Material>();

        CreateIndexArrays(out materials, out indexList);

        // figure out how many slices go onto the mesh
        int sliceX = 2;
        int sliceY = 2;
        int sliceZ = 2;

        if (mSliceFaces)
        {
            sliceX = Mathf.Max(2, (int)(mExtents.x / mSliceDistance) + 1);
            sliceY = Mathf.Max(2, (int)(mExtents.y / mSliceDistance) + 1);
            sliceZ = Mathf.Max(2, (int)(mExtents.z / mSliceDistance) + 1);
        }
        int startID = 0;

        // calculate the uv step amount based on its aspect ratio
        float uStart  = 0;
        float uvRatio = 1;

        if (r.sharedMaterial != null && r.sharedMaterial.mainTexture != null)
        {
            uvRatio = (float)r.sharedMaterial.mainTexture.height / r.sharedMaterial.mainTexture.width;
        }

        // Front
        List <int> indices = GetIndexArray(mOverrideFront, materials, indexList);

        if (mFaceFront)
        {
            SuperCubeUtil.AddFace(transMat, Matrix4x4.TRS(Vector3.zero, Quaternion.Euler(0, 0, 0), new Vector3(mExtents.x, mExtents.y, mExtents.z)), 0.5f, mWallUVType, mWallUVOffset, mWallUVTile, uStart, uStart + mExtents.x * uvRatio / mExtents.y, sliceX, sliceY, ref verts, ref uvs, ref norms, ref tans, ref indices);
            startID = Resample(0, startID, m, ref colors, sliceX, sliceY);
        }
        uStart += mExtents.x * uvRatio / mExtents.y;

        // Left
        indices = GetIndexArray(mOverrideLeft, materials, indexList);
        if (mFaceLeft)
        {
            SuperCubeUtil.AddFace(transMat, Matrix4x4.TRS(Vector3.zero, Quaternion.Euler(0, 90, 0), new Vector3(mExtents.z, mExtents.y, mExtents.x)), 0.5f, mWallUVType, mWallUVOffset, mWallUVTile, uStart, uStart + mExtents.z * uvRatio / mExtents.y, sliceZ, sliceY, ref verts, ref uvs, ref norms, ref tans, ref indices);
            startID = Resample(1, startID, m, ref colors, sliceZ, sliceY);
        }
        uStart += mExtents.z * uvRatio / mExtents.y;

        // Back
        indices = GetIndexArray(mOverrideBack, materials, indexList);
        if (mFaceBack)
        {
            SuperCubeUtil.AddFace(transMat, Matrix4x4.TRS(Vector3.zero, Quaternion.Euler(0, 180, 0), new Vector3(mExtents.x, mExtents.y, mExtents.z)), 0.5f, mWallUVType, mWallUVOffset, mWallUVTile, uStart, uStart + mExtents.x * uvRatio / mExtents.y, sliceX, sliceY, ref verts, ref uvs, ref norms, ref tans, ref indices);
            startID = Resample(2, startID, m, ref colors, sliceX, sliceY);
        }
        uStart += mExtents.x * uvRatio / mExtents.y;

        // Right
        indices = GetIndexArray(mOverrideRight, materials, indexList);
        if (mFaceRight)
        {
            SuperCubeUtil.AddFace(transMat, Matrix4x4.TRS(Vector3.zero, Quaternion.Euler(0, 270, 0), new Vector3(mExtents.z, mExtents.y, mExtents.x)), 0.5f, mWallUVType, mWallUVOffset, mWallUVTile, uStart, uStart + mExtents.z * uvRatio / mExtents.y, sliceZ, sliceY, ref verts, ref uvs, ref norms, ref tans, ref indices);
            startID = Resample(3, startID, m, ref colors, sliceZ, sliceY);
        }
        uStart += mExtents.z * uvRatio / mExtents.y;

        // Top
        indices = GetIndexArray(mOverrideTop, materials, indexList);
        if (mFaceTop)
        {
            SuperCubeUtil.AddFace(transMat, Matrix4x4.TRS(Vector3.zero, Quaternion.Euler(90, 0, 0), new Vector3(mExtents.x, mExtents.z, mExtents.y)), 0.5f, mTopBottomUVType, mTopBottomUVOffset, mTopBottomUVTile, uStart, uStart + mExtents.x, sliceX, sliceZ, ref verts, ref uvs, ref norms, ref tans, ref indices);
            startID = Resample(4, startID, m, ref colors, sliceX, sliceZ);
        }
        // Bottom
        indices = GetIndexArray(mOverrideBottom, materials, indexList);
        if (mFaceBottom)
        {
            SuperCubeUtil.AddFace(transMat, Matrix4x4.TRS(Vector3.zero, Quaternion.Euler(270, 0, 0), new Vector3(mExtents.x, mExtents.z, mExtents.y)), 0.5f, mTopBottomUVType, mTopBottomUVOffset, mTopBottomUVTile, uStart, uStart + mExtents.x, sliceX, sliceZ, ref verts, ref uvs, ref norms, ref tans, ref indices);
            startID = Resample(5, startID, m, ref colors, sliceX, sliceZ);
        }

        if (verts.Count >= 65000)
        {
            Debug.LogWarning("SuperCube has too many vertices (more than 65,000)! Please increase Slice Distance, or hide unnecessary faces!");
            return;
        }
                #if UNITY_EDITOR
        if (verts.Count > 500 && aFullBuild && UnityEditor.GameObjectUtility.AreStaticEditorFlagsSet(gameObject, UnityEditor.StaticEditorFlags.LightmapStatic))
        {
            Debug.LogWarning("Unwrapping for lightmaps may take a long time to calculate (" + verts.Count + " vertices)! You can disable this calculation by unchecking Lightmap Static in your GameObject's static settings! Try enabling it once after your object has been placed properly, or increase the Slice Distance!");
        }
                #endif

        // Set the mesh data
        m.Clear();
        m.vertices = verts.ToArray();
        m.normals  = norms.ToArray();
        m.uv       = uvs.ToArray();
        m.tangents = tans.ToArray();
        // TODO: Color resampling for v1.1
        //m.colors   = colors.ToArray();

        // Set up the mesh indices and material based sub-meshes
        m.subMeshCount = indexList.Count;
        for (int i = 0; i < indexList.Count; ++i)
        {
            if (indexList[i].Count <= 0)
            {
                indexList.RemoveAt(i);
                materials.RemoveAt(i);
                i--;
                continue;
            }
            m.SetIndices(indexList[i].ToArray(), MeshTopology.Triangles, i);
        }
        r.sharedMaterials = materials.ToArray();

        // Additional mesh processing
        m.RecalculateBounds();
                #if UNITY_EDITOR
        if (aFullBuild && UnityEditor.GameObjectUtility.AreStaticEditorFlagsSet(gameObject, UnityEditor.StaticEditorFlags.LightmapStatic))
        {
            UnityEditor.Unwrapping.GenerateSecondaryUVSet(m);
        }
                #endif

        // Set the mesh, and update any box colliders on the object!
        filter.sharedMesh = m;
        BoxCollider collider = GetComponent <BoxCollider>();
        if (collider != null)
        {
            collider.center = Vector3.zero;
            collider.size   = mExtents;
        }
    }