/// <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; }
/// <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; } }