void SaveTowerPositions(WG_TerrainBuilder builderComponent) { NumberFormatInfo nfi = new NumberFormatInfo(); nfi.NumberDecimalSeparator = "."; WG_Tower[] positions = WG_Helper.FindObjectsOfTypeAll <WG_Tower>().ToArray();// FindObjectsOfType<WG_Tower>(); string path = serverPath + "Towers.txt"; using (StreamWriter sw = File.CreateText(path)) { for (int i = 0; i < positions.Length; i++) { Vector3 p = positions[i].transform.position; IntPair loc = WG_Helper.GetLocationCoordinates(p, builderComponent.segmentSize); if (loc.u >= builderComponent.segmentsMinX && loc.u <= builderComponent.segmenstMaxX && loc.v >= builderComponent.segmentsMinY && loc.v <= builderComponent.segmenstMaxY) { sw.Write(positions[i].towerType); sw.Write(","); sw.Write(p.x.ToString("0.000", nfi)); sw.Write(","); sw.Write(p.z.ToString("0.000", nfi)); sw.Write(","); sw.Write(positions[i].towerName); if (i < positions.Length - 1) { sw.Write("|"); } } } } }
string SaveTextureAsset(Texture2D texture, bool isHdr) { #if UNITY_EDITOR string dataPath = WG_Helper.RemoveFirstFolderFromPath(textureAssetFolder) + "lightmap_" + texture.GetInstanceID().ToString() + (isHdr ? ".exr" : ".png"); string filePath = Application.dataPath + "/" + dataPath; if (isHdr) { //Debug.Log("Save exr " + filePath); //Debug.Log("center pixel: " + texture.GetPixel(texture.width / 2, texture.height / 2).ToString()); byte[] _bytes = texture.EncodeToEXR(); File.WriteAllBytes(filePath, _bytes); AssetDatabase.ImportAsset("Assets/" + dataPath, ImportAssetOptions.ForceUpdate); return("Assets/" + dataPath); } else { byte[] _bytes = texture.EncodeToPNG(); File.WriteAllBytes(filePath, _bytes); AssetDatabase.ImportAsset("Assets/" + dataPath, ImportAssetOptions.ForceUpdate); return("Assets/" + dataPath); } #else return(""); #endif }
public int ExportMesh(Mesh mesh, GameObject obj) { int meshId = mesh.GetInstanceID(); #if UNITY_EDITOR if (!meshLinks.ContainsKey(meshId)) { string meshName = "mesh_" + meshId.ToString() + "_" + WG_Helper.NormalizeName(mesh.name); string meshLink = "meshes/" + meshName; string meshPath = AssetDatabase.GetAssetPath(mesh); if (meshPath.Length > 0) { AssetImporter.GetAtPath(meshPath).SetAssetBundleNameAndVariant(meshLink, ""); meshLinks.Add(meshId, new NameLinkPath() { link = meshLink, name = mesh.name, path = meshPath }); } else { Debug.Log("Mesh component of the object " + obj.name + " not saved as asset. Save it before exorting scene."); } } #endif return(meshId); }
void ClearGeneratedAssets() { //Application.dataPath = .../Assets WG_Helper.ClearFolder(Application.dataPath + assetMaterialPath); WG_Helper.ClearFolder(Application.dataPath + assetLocationPath); WG_Helper.ClearFolder(Application.dataPath + assetMeshPath); WG_Helper.ClearFolder(Application.dataPath + assetTexturePath); WG_Helper.ClearFolder(Application.dataPath + assetNavmeshPath); WG_Helper.ClearFolder(Application.dataPath + assetMinimapPath); }
string SaveMinimapAsset(Texture2D texture) { #if UNITY_EDITOR byte[] _bytes = texture.EncodeToPNG(); string dataPath = WG_Helper.RemoveFirstFolderFromPath(minimapAssetFolder) + texture.name + ".png"; string filePath = Application.dataPath + "/" + dataPath; File.WriteAllBytes(filePath, _bytes); string assetPath = "Assets/" + dataPath; AssetDatabase.ImportAsset(assetPath, ImportAssetOptions.ForceUpdate); return(assetPath); #else return(""); #endif }
public static Color ConvertColorToLightmap(Color color, bool applyGamma = false) { if (applyGamma) { return(new Color(WG_Helper.ApplyGammaCorrection(color.r, 0.4545f), WG_Helper.ApplyGammaCorrection(color.g, 0.4545f), WG_Helper.ApplyGammaCorrection(color.b, 0.4545f), color.a)); } else { return(color); } }
public int ExportMaterial(Material material) { int materialId = material.GetInstanceID(); int shaderId = material.shader.GetInstanceID(); #if UNITY_EDITOR //should we add the shader to the asset bundle if (!shaderLinks.ContainsKey(shaderId)) { Shader shader = material.shader; string shaderName = "shader_" + shaderId.ToString(); string shaderLink = "shaders/" + shaderName; string assetPath = AssetDatabase.GetAssetPath(shader); AssetImporter.GetAtPath(assetPath).SetAssetBundleNameAndVariant(shaderLink, ""); shaderLinks.Add(shaderId, new NameLinkPath() { link = shaderLink, name = shaderName, path = assetPath }); } if (!materialLinks.ContainsKey(materialId)) { string matName = "material_" + materialId.ToString() + "_" + WG_Helper.NormalizeName(material.name); string matLink = "materials/" + matName; string assetPath = AssetDatabase.GetAssetPath(material); //iterate throw parameters of the material and try to find all textures Shader shader = material.shader; int propsCount = ShaderUtil.GetPropertyCount(shader); for (int i = 0; i < propsCount; i++) { if (ShaderUtil.GetPropertyType(shader, i) == ShaderUtil.ShaderPropertyType.TexEnv) { string texPropName = ShaderUtil.GetPropertyName(shader, i); Texture tex = material.GetTexture(texPropName); ExportTexture(tex); } } AssetImporter.GetAtPath(assetPath).SetAssetBundleNameAndVariant(matLink, ""); materialLinks.Add(materialId, new NameLinkPath() { link = matLink, name = material.name, path = assetPath }); } #endif return(materialId); }
public static Color[] ConverPixelsToLightMap(Color[] array, bool debug = false) { Color[] toReturn = new Color[array.Length]; Color randomColor = Random.ColorHSV(); for (int i = 0; i < toReturn.Length; i++) { if (debug) { toReturn[i] = randomColor; } else { toReturn[i] = WG_Helper.ConvertColorToLightmap(array[i]); } } return(toReturn); }
//void SaveCollisionMap(NavMeshData data) public void SaveCollisionMap(string serverPath) { List <BoundaryEdge> boundary = WG_Helper.GetNavmeshBoundary(); if (serverPath != null) { using (StreamWriter outputFile = new StreamWriter(serverPath + @"CollisionMap.txt")) { for (int i = 0; i < boundary.Count; i++) { BoundaryEdge edge = boundary[i]; outputFile.Write(WG_Helper.Vectro3ToString(edge.start) + "|" + WG_Helper.Vectro3ToString(edge.end) + (i == boundary.Count - 1 ? "" : "|")); //IntIntClass edge = edgesList[boundaryEdges[i]].GetEdgeVertices(); //outputFile.Write(WG_Helper.Vectro3ToString(vertexList[edge.value1].position) + "|" + WG_Helper.Vectro3ToString(vertexList[edge.value2].position) + (i == boundaryEdges.Count - 1 ? "" : "|")); } } } }
public float GetHeight(Vector2 point) { int maxIndex = -1; bool isHeight = false; for (int i = 0; i < points.Count; i++) { Disc d = points[i]; if (WG_Helper.IsInside(point, d)) { if (d.level > maxIndex) { maxIndex = d.level; isHeight = !d.isNegative; } } } return(isHeight ? 1.0f : 0.0f); }
public void ExportTexture(Texture tex) { #if UNITY_EDITOR if (tex != null) { int texId = tex.GetInstanceID(); if (!textureLinks.ContainsKey(texId)) { string texName = "texture_" + texId.ToString() + "_" + WG_Helper.NormalizeName(tex.name); string texPath = AssetDatabase.GetAssetPath(tex); string texLink = "textures/" + texName; AssetImporter.GetAtPath(texPath).SetAssetBundleNameAndVariant(texLink, ""); textureLinks.Add(texId, new NameLinkPath() { link = texLink, name = texName, path = texPath }); } } #endif }
void CreateMinimap(int minimapSize, Camera minimapCamera, float minimapCameraHeight) { RenderTexture renderTexture = new RenderTexture(minimapSize, minimapSize, 16, DefaultFormat.LDR); renderTexture.Create(); minimapCamera.targetTexture = renderTexture; Rect rectReadPicture = new Rect(0, 0, minimapSize, minimapSize); Vector3 locPosition = gameObject.transform.position; minimapCamera.transform.position = new Vector3(locPosition.x, minimapCameraHeight, locPosition.z); minimapCamera.Render(); RenderTexture.active = renderTexture; //Create texture locationMinimap = new Texture2D(minimapSize, minimapSize); locationMinimap.name = "minimap_" + u.ToString() + "_" + v.ToString(); // Read pixels locationMinimap.ReadPixels(rectReadPicture, 0, 0); Color[] rawPixels = locationMinimap.GetPixels(); Color[] processPixels = new Color[rawPixels.Length]; for (int pi = 0; pi < rawPixels.Length; pi++) { float a = rawPixels[pi].a; processPixels[pi] = new Color(a, a, a, a); } locationMinimap.SetPixels(processPixels); // Clean up RenderTexture.active = null; renderTexture.Release(); minimapAssetPath = SaveMinimapAsset(locationMinimap); WG_Helper.SetTextureSprite(minimapAssetPath); }
public override string ToString() { return("(" + vertex01.ToString() + ", " + vertex02.ToString() + "), triangles: " + WG_Helper.ListToString(triangles) + ", isBoundary: " + isBoundary.ToString()); }
public void BuildMesh() { #if UNITY_EDITOR //clear generated segments navmeshExist = false; //create helper object for all sub-generated objects GameObject store = new GameObject() { name = "Temp Store" }; Transform[] allTransforms = gameObject.GetComponentsInChildren <Transform>(); for (int trIndex = allTransforms.Length - 1; trIndex >= 0; trIndex--) { GameObject go = allTransforms[trIndex].gameObject; //try to get noise primitive component //if this component is null, then delete game object WG_Primitive_PerlinNoise noiseComponent = go.GetComponent <WG_Primitive_PerlinNoise>(); WG_Primitive_Paint paintComponent = go.GetComponent <WG_Primitive_Paint>(); WG_Painter painterComponent = go.GetComponent <WG_Painter>(); WG_VisualCenter visCenterComponent = go.GetComponent <WG_VisualCenter>(); if (go != gameObject && noiseComponent == null && paintComponent == null && painterComponent == null && visCenterComponent == null) { if (clearAll) { DestroyImmediate(go); } else { //check is this object contains location controller WG_LocationController locController = go.GetComponent <WG_LocationController>(); if (locController != null) {//this is location root object, destoy it DestroyImmediate(go); } else { //this is not location root, may be walls or ground object if (go.name == groundName || go.name == wallsName || go.name == meshRootName) { //this is generated ground or wall object, destoy it DestroyImmediate(go); } else {//this is sub-placed object, store it if (PrefabUtility.GetOutermostPrefabInstanceRoot(go) == null || PrefabUtility.GetOutermostPrefabInstanceRoot(go) == go) { go.transform.SetParent(store.transform, true); } } } } } } //fill map for all location segments bool[,] map = new bool[(segmenstMaxX - segmentsMinX + 1) * meshSquaresCount + 1, (segmenstMaxY - segmentsMinY + 1) * meshSquaresCount + 1]; WG_Primitive_BaseNoise[] noises = gameObject.GetComponentsInChildren <WG_Primitive_BaseNoise>(); float meshSquareSize = segmentSize / meshSquaresCount; Vector2 bottomLeftCorner = new Vector2((segmentsMinX - 0.5f) * segmentSize, (segmentsMinY - 0.5f) * segmentSize); for (int x = 0; x < map.GetLength(0); x++) { for (int y = 0; y < map.GetLength(1); y++) { Vector2 pos = new Vector2(x * meshSquareSize, y * meshSquareSize) + bottomLeftCorner; map[x, y] = IsPointMountains(pos, noises); } } //next create root for location segments GameObject locationsRoot = new GameObject { name = meshRootName }; locationsRoot.transform.SetParent(gameObject.transform); //create location generator WG_SegmentsGenerator generator = new WG_SegmentsGenerator(); List <WG_LocationController> locations = generator.GenerateLocationSegments(this, segmentSize, meshSquareSize, meshSquaresCount, segmentsMinX, segmenstMaxX, segmentsMinY, segmenstMaxY, locationsRoot, groundMaterial, mountainsMaterial, wallsMaterial, map, mountainsHeight, !(forceUpdate && buildMesh), navMeshCutVolume, uv2Padding); #endif #if UNITY_EDITOR //after generation we should place back all stored objects, we will place it inside location root object Transform[] storedObjects = store.GetComponentsInChildren <Transform>(); for (int tfmIndex = 0; tfmIndex < storedObjects.Length; tfmIndex++) { Transform tfm = storedObjects[tfmIndex]; if (tfm.gameObject != store) { Vector3 position = tfm.position; IntPair locCoords = WG_Helper.GetLocationCoordinates(position, segmentSize); WG_LocationController loc = GetLocationByCoordinates(locCoords, locations); if (loc != null) { //rever prefab properties (mesh and material) GameObject prefabMaster = PrefabUtility.GetOutermostPrefabInstanceRoot(tfm.gameObject); MeshFilter meshComponent = tfm.GetComponent <MeshFilter>(); if ((prefabMaster == null && meshComponent != null) || prefabMaster == tfm.gameObject) { Vector3 scale = tfm.localScale; GameObject source = PrefabUtility.GetCorrespondingObjectFromSource(tfm.gameObject); if (source != null) { PrefabUtility.RevertPrefabInstance(tfm.gameObject, InteractionMode.UserAction); } tfm.localScale = scale; //move object inside location tfm.SetParent(loc.gameObject.transform, true); tfm.position += loc.gameObject.transform.position; } } else { Debug.Log("There is no locations with coordinates " + locCoords.ToString() + ", so skip the object " + tfm.gameObject.name); } } } //delete temp store DestroyImmediate(store); #endif BuildNavmeshOnly(); }
void CalculateMeshOutlines() { //WG_Helper.PrintArray(vertices.ToArray()); for (int vertexIndex = 0; vertexIndex < vertices.Count; vertexIndex++) { if (!checkedVertices.Contains(vertexIndex)) { int newOulineVertex = GetConnectedOutlineVertex(vertexIndex); if (newOulineVertex != -1) { //if both vertexIndex and newOulineVertex are on boundary, skip the process Vector3 startPoint = vertices[vertexIndex]; Vector3 nextPoint = vertices[newOulineVertex]; bool isStartBoundary = IsNearBoundary(startPoint); bool isNextBoundary = IsNearBoundary(nextPoint); //Debug.Log(startPoint.ToString() + " " + nextPoint.ToString() + " " + isStartBoundary.ToString() + " " + isNextBoundary.ToString() + " " + IsDifferentBoundarySides(startPoint, nextPoint).ToString()); if (!isStartBoundary || !isNextBoundary || IsDifferentBoundarySides(startPoint, nextPoint)) { checkedVertices.Add(vertexIndex); List <int> newOutline = new List <int> { vertexIndex }; outlines.Add(newOutline); FollowOutline(newOulineVertex, outlines.Count - 1); //check if we break the outline new zone boundary //in this case we should revert the process from the last point (in zone boundary) to the other direction int lastIndex = newOutline[newOutline.Count - 1]; //Debug.Log("Last index: " + lastIndex.ToString()); if (IsNearBoundary(vertices[lastIndex])) { //Debug.Log("point " + lastIndex.ToString() + " near boundary"); //remove vertices from the checked set //WG_Helper.PrintArray(checkedVertices); for (int i = newOutline.Count - 1; i >= 0; i--) { checkedVertices.Remove(newOutline[i]); } //WG_Helper.PrintArray(checkedVertices); //remove outline outlines.RemoveAt(outlines.Count - 1); //start the process again checkedVertices.Add(lastIndex); List <int> newOtherOutline = new List <int> { lastIndex }; outlines.Add(newOtherOutline); newOulineVertex = GetConnectedOutlineVertex(lastIndex); FollowOutline(newOulineVertex, outlines.Count - 1); } else { outlines[outlines.Count - 1].Add(vertexIndex); } //check if we should revert outline array //get triangles incident to the start vertex int startVertex = outlines[outlines.Count - 1][0]; List <Triangle> startTriangles = triangleDictionary[startVertex]; //find in a triangle the next point in the outline int nextVertex = outlines[outlines.Count - 1][1]; bool shouldRevert = true; foreach (Triangle startTriangle in startTriangles) { if ((startTriangle.vertexIndexA == startVertex && startTriangle.vertexIndexB == nextVertex) || (startTriangle.vertexIndexB == startVertex && startTriangle.vertexIndexC == nextVertex) || (startTriangle.vertexIndexC == startVertex && startTriangle.vertexIndexA == nextVertex)) { shouldRevert = false; break; } } if (shouldRevert) { outlines[outlines.Count - 1] = WG_Helper.Revert(outlines[outlines.Count - 1]); } //WG_Helper.PrintArray(outlines[outlines.Count - 1].ToArray()); } } } } }
void OnDrawGizmos() { #if UNITY_EDITOR if (visualMap != null && visualizeMap) { for (int x = 0; x < visualMap.GetLength(0); x++) { for (int y = 0; y < visualMap.GetLength(1); y++) { Gizmos.color = (visualMap[x, y]) ? new Color(0, 0, 0, gizmoAlpha) : new Color(1, 1, 1, gizmoAlpha); Vector3 pos = new Vector3(-visualAreaSize / 2 + (x + 0.5f) * visualSquareSize + visualAreaCenter.position.x, 0, -visualAreaSize / 2 + (y + 0.5f) * visualSquareSize + visualAreaCenter.position.z); Gizmos.DrawCube(pos, new Vector3(visualSquareSize * 0.75f, 0.0f, visualSquareSize * 0.75f)); } } Vector2 minCorner = new Vector2(visualAreaCenter.position.x - visualAreaSize / 2, visualAreaCenter.position.z - visualAreaSize / 2); Vector2 maxCorner = new Vector2(visualAreaCenter.position.x + visualAreaSize / 2, visualAreaCenter.position.z + visualAreaSize / 2); int minX = (int)(minCorner.x / (segmentSize / 2)) + (minCorner.x > 0 ? 1 : 0); int maxX = (int)(maxCorner.x / (segmentSize / 2)) + (maxCorner.x > 0 ? 1 : 0); int minY = (int)(minCorner.y / (segmentSize / 2)) + (minCorner.y > 0 ? 1 : 0); int maxY = (int)(maxCorner.y / (segmentSize / 2)) + (maxCorner.y > 0 ? 1 : 0); Gizmos.color = visualZoneLine; for (int x = minX - 1; x < maxX + 1; x++) { for (int y = minY - 1; y < maxY + 1; y++) { if (x % 2 == 0 && y % 2 == 0) { Gizmos.DrawLine(GetPositionOfSegmetnCorner(x - 1, y - 1), GetPositionOfSegmetnCorner(x + 1, y - 1)); Gizmos.DrawLine(GetPositionOfSegmetnCorner(x + 1, y - 1), GetPositionOfSegmetnCorner(x + 1, y + 1)); Gizmos.DrawLine(GetPositionOfSegmetnCorner(x + 1, y + 1), GetPositionOfSegmetnCorner(x - 1, y + 1)); Gizmos.DrawLine(GetPositionOfSegmetnCorner(x - 1, y + 1), GetPositionOfSegmetnCorner(x - 1, y - 1)); string labelString = "(" + (x / 2).ToString() + ", " + (y / 2).ToString() + ")"; Vector3 labelPos = new Vector3(x * segmentSize / 2, 2.0f, y * segmentSize / 2); Handles.Label(labelPos, labelString); } } } } if (visualizeBoundaryEdges) { List <BoundaryEdge> boundary = WG_Helper.GetNavmeshBoundary(); Gizmos.color = boundaryLine; for (int i = 0; i < boundary.Count; i++) { BoundaryEdge edge = boundary[i]; if (true) { Gizmos.DrawLine(edge.start, edge.end); //Handles.DrawSolidDisc(edge.start, Vector3.up, 0.03f); //Handles.Label(edge.start, edge.startVertex.ToString()); //Handles.DrawSolidDisc(edge.end, Vector3.up, 0.03f); //Handles.Label(edge.end, edge.endVertes.ToString()); //Handles.Label((edge.start + edge.end) / 2.0f, edge.index.ToString()); } } } #endif }
void PrepareMaterial(GameObject go) { //for material of the geometry we should get lightmap, save it, reassign material with all textures plus lightmap #if UNITY_EDITOR MeshRenderer meshRenderer = go.GetComponent <MeshRenderer>(); if (meshRenderer != null) { //get material Material originalMaterial = meshRenderer.sharedMaterial; //if material use lightMap texture, then does not save new texture and reassign material bool lmSlotExist = IsMaterialContainsMap(originalMaterial, "_LightMap"); bool bumpSlotExist = IsMaterialContainsMap(originalMaterial, "_BumpMap"); bool emissionSlotExist = IsMaterialContainsMap(originalMaterial, "_EmissionMap"); bool diffuseSlotExist = IsMaterialContainsMap(originalMaterial, "_MainTex"); if (lmSlotExist) { Texture t = originalMaterial.GetTexture("_LightMap"); if (t == null) { lmSlotExist = false; } } if (!lmSlotExist) {//material does not contains slot for lightmap, so, we should save it and re-assign material //get lightmap string lmTextureAssetPath = ""; int lmIndex = meshRenderer.lightmapIndex; bool reAssignMaterial = false; if (lmIndex > -1 && lmIndex < LightmapSettings.lightmaps.Length) { LightmapData data = LightmapSettings.lightmaps[lmIndex]; Texture2D lmTexture = data.lightmapColor; WG_Helper.SetTextureReadable(lmTexture, true); //int width = (int)(lmTexture.width * Mathf.Min(1.0f, meshRenderer.lightmapScaleOffset.x)); //int height = (int)(lmTexture.height * Mathf.Min(1.0f, meshRenderer.lightmapScaleOffset.y)); int width = (int)(lmTexture.width * meshRenderer.lightmapScaleOffset.x); int height = (int)(lmTexture.height * meshRenderer.lightmapScaleOffset.y); //int startX = Mathf.Max(0, (int)(lmTexture.width * meshRenderer.lightmapScaleOffset.z)); //int startY = Mathf.Max(0, (int)(lmTexture.height * meshRenderer.lightmapScaleOffset.w)); int startX = (int)(lmTexture.width * meshRenderer.lightmapScaleOffset.z); int startY = (int)(lmTexture.height * meshRenderer.lightmapScaleOffset.w); Texture2D newTexture = new Texture2D(width, height, isLightmapHDR ? DefaultFormat.HDR : DefaultFormat.LDR, TextureCreationFlags.MipChain); int mapStartX = Mathf.Max(0, startX); int mapStartY = Mathf.Max(0, startY); int mapEndX = Mathf.Min(lmTexture.width, startX + width); int mapEndY = Mathf.Min(lmTexture.height, startY + height); int mapWidth = mapEndX - mapStartX; int mapHeight = mapEndY - mapStartY; //fill the main rect Color[] lmColorsRaw = lmTexture.GetPixels(mapStartX, mapStartY, mapWidth, mapHeight); //WG_Helper.PrintMinMaxPixels(lmColorsRaw); Color[] lmColors = WG_Helper.ConverPixelsToLightMap(lmColorsRaw); //WG_Helper.PrintMinMaxPixels(lmColors); //Debug.Log("main rect: " + (mapStartX - startX).ToString() + " " + (mapStartY - startY).ToString() + " " + mapWidth.ToString() + " " + mapHeight.ToString()); newTexture.SetPixels(mapStartX - startX, mapStartY - startY, mapWidth, mapHeight, isLightmapHDR ? lmColors : lmColorsRaw); //next fill left area (if we need it) Color[] leftColorsRaw = lmTexture.GetPixels(mapStartX, mapStartY, 1, mapHeight); Color[] leftColors = WG_Helper.ConverPixelsToLightMap(leftColorsRaw); for (int column = 0; column < mapStartX - startX; column++) { newTexture.SetPixels(column, mapStartY - startY, 1, mapHeight, isLightmapHDR ? leftColors : leftColorsRaw); } //next right area Color[] rightColorsRaw = lmTexture.GetPixels(mapEndX - 1, mapStartY, 1, mapHeight); Color[] rightColors = WG_Helper.ConverPixelsToLightMap(rightColorsRaw); for (int column = 0; column < width + startX - mapEndX; column++) { newTexture.SetPixels(mapEndX - startX + column, mapStartY - startY, 1, mapHeight, isLightmapHDR ? rightColors: rightColorsRaw); } //bottom and top Color[] bottomColorsRaw = lmTexture.GetPixels(mapStartX, mapStartY, mapWidth, 1); Color[] bottomColors = WG_Helper.ConverPixelsToLightMap(bottomColorsRaw); for (int row = 0; row < mapStartY - startY; row++) { newTexture.SetPixels(mapStartX - startX, row, mapWidth, 1, isLightmapHDR ? bottomColors : bottomColorsRaw); } Color[] topColorsRaw = lmTexture.GetPixels(mapStartX, mapEndY - 1, mapWidth, 1); Color[] topColors = WG_Helper.ConverPixelsToLightMap(topColorsRaw); for (int row = 0; row < height + startY - mapEndY; row++) { newTexture.SetPixels(mapStartX - startX, mapEndY - startY + row, mapWidth, 1, isLightmapHDR ? topColors : topColorsRaw); } //regions on corners Color leftBootm = isLightmapHDR ? WG_Helper.ConvertColorToLightmap(lmTexture.GetPixel(mapStartX, mapStartY)) : lmTexture.GetPixel(mapStartX, mapStartY); Color leftTop = isLightmapHDR ? WG_Helper.ConvertColorToLightmap(lmTexture.GetPixel(mapStartX, mapEndY - 1)) : lmTexture.GetPixel(mapStartX, mapEndY - 1); Color rightBootm = isLightmapHDR ? WG_Helper.ConvertColorToLightmap(lmTexture.GetPixel(mapEndX - 1, mapStartY)) : lmTexture.GetPixel(mapEndX - 1, mapStartY); Color rightTop = isLightmapHDR ? WG_Helper.ConvertColorToLightmap(lmTexture.GetPixel(mapEndX - 1, mapEndY - 1)) : lmTexture.GetPixel(mapEndX - 1, mapEndY - 1); Color[] leftBottomColors = WG_Helper.CreateArray(leftBootm, (mapStartX - startX) * (mapStartY - startY)); Color[] leftTopColors = WG_Helper.CreateArray(leftTop, (mapStartX - startX) * (startY + height - mapEndY)); Color[] rightBottomColors = WG_Helper.CreateArray(rightBootm, (startX + width - mapEndX) * (mapStartY - startY)); Color[] rightTopColors = WG_Helper.CreateArray(rightTop, (startX + width - mapEndX) * (startY + height - mapEndY)); newTexture.SetPixels(0, 0, mapStartX - startX, mapStartY - startY, leftBottomColors); newTexture.SetPixels(0, mapEndY, mapStartX - startX, startY + height - mapEndY, leftTopColors); //Debug.Log(rightBottomColors.Length.ToString() + " " + (startX + width - mapEndX).ToString() + " " + (mapStartY - startY).ToString()); try { newTexture.SetPixels(mapEndX, 0, startX + width - mapEndX, mapStartY - startY, rightBottomColors); } catch { Debug.Log(rightBottomColors.Length.ToString() + " " + (startX + width - mapEndX).ToString() + " " + (mapStartY - startY).ToString()); } newTexture.SetPixels(mapEndX, mapEndY, startX + width - mapEndX, startY + height - mapEndY, rightTopColors); newTexture.Apply(); //Debug.Log("isLightmapHDR=" + isLightmapHDR.ToString()); //Debug.Log("original pixel: " + lmTexture.GetPixel(mapStartX + width / 3, mapStartY + height / 3).ToString() + " " //+ lmTexture.GetPixel(mapStartX + 2*width / 3, mapStartY + 2*height / 3).ToString()); //Debug.Log("saved pixel: " + newTexture.GetPixel(width / 3, height / 3).ToString() + " " + newTexture.GetPixel(2*width / 3, 2*height / 3).ToString()); lmTextureAssetPath = SaveTextureAsset(newTexture, isLightmapHDR); WG_Helper.SetTextureLightmap(lmTextureAssetPath, isLightmapHDR); reAssignMaterial = true; } else { Debug.Log("Object " + go.name + " does not have lightmaps or this data is invalid."); } //reassign material if we need it if (reAssignMaterial) { if (true) { Material newMaterial = lmMode == LMShaderMode.LWRP ? new Material(lwrpShader) : new Material(GetStdShader(diffuseSlotExist, bumpSlotExist, emissionSlotExist)); //Material newMaterial = (lmMode == LMShaderMode.LWRP || (lmMode == LMShaderMode.Std && bumpSlotExist == false)) ? new Material(lmShader) : new Material(lmSecondShader); //for LWRP we use only one uber-shader, for std shaders each different once from array //assign all parameters from original material to the new one Shader originalShader = originalMaterial.shader; List <string> newMaterialNames = WG_Helper.GetShaderParameterNames(newMaterial.shader); int propsCount = ShaderUtil.GetPropertyCount(originalShader); for (int i = 0; i < propsCount; i++) { string propName = ShaderUtil.GetPropertyName(originalShader, i); if (newMaterialNames.Contains(propName)) { ShaderUtil.ShaderPropertyType type = ShaderUtil.GetPropertyType(originalShader, i); if (type == ShaderUtil.ShaderPropertyType.Color) { newMaterial.SetColor(propName, originalMaterial.GetColor(propName)); } else if (type == ShaderUtil.ShaderPropertyType.Float) { newMaterial.SetFloat(propName, originalMaterial.GetFloat(propName)); } else if (type == ShaderUtil.ShaderPropertyType.Range) { newMaterial.SetFloat(propName, originalMaterial.GetFloat(propName)); } else if (type == ShaderUtil.ShaderPropertyType.TexEnv) { newMaterial.SetTexture(propName, originalMaterial.GetTexture(propName)); newMaterial.SetTextureOffset(propName, originalMaterial.GetTextureOffset(propName)); newMaterial.SetTextureScale(propName, originalMaterial.GetTextureScale(propName)); } else if (type == ShaderUtil.ShaderPropertyType.Vector) { newMaterial.SetVector(propName, originalMaterial.GetVector(propName)); } } else { Debug.Log("New material (" + newMaterial.shader.name + ") for the object " + go.name + " does not contains property " + propName + ". Skip it."); } } //set gpu instancing newMaterial.enableInstancing = originalMaterial.enableInstancing; //finally assign lightMap texture newMaterial.SetTexture("_LightMap", AssetDatabase.LoadAssetAtPath <Texture2D>(lmTextureAssetPath)); //set amibient, if we need it if (!isLightmapHDR) { //--newMaterial.SetColor("_Ambient", ldrAmbient); // <-- does not used in WebGL mode newMaterial.SetFloat("_Multiplier", ldrLightmapMultiplier); } //enable all kewords string[] originalKeyWords = originalMaterial.shaderKeywords; for (int s = 0; s < originalKeyWords.Length; s++) { newMaterial.EnableKeyword(originalKeyWords[s]); } //CoreUtils.SetKeyword(newMaterial, "_EMISSION", originalMaterial.IsKeywordEnabled("_EMISSION")); //assign material to the object meshRenderer.sharedMaterial = newMaterial; SaveMaterialAsset(newMaterial); } else { } } else { //string matAssetPath = SaveMaterialAsset(originalMaterial); //Debug.Log("Create material asset " + matAssetPath); } } else { SaveMaterialAsset(originalMaterial); } } #endif }
public static List <BoundaryEdge> GetNavmeshBoundary() { //copy algorithm NavMeshTriangulation triangulatedNavMesh = NavMesh.CalculateTriangulation(); Vector3[] originalVertices = triangulatedNavMesh.vertices; int[] originalIndexes = triangulatedNavMesh.indices; float weldValue = 0.01f; List <VertexData> vertexList = new List <VertexData>(); for (int i = 0; i < originalVertices.Length; i++) { Vector3 vPos = originalVertices[i]; bool isNew = true; //Try to find this vertex on vertexList for (int vIndex = 0; vIndex < vertexList.Count; vIndex++) { VertexData v = vertexList[vIndex]; if (Vector3.Distance(vPos, v.position) < weldValue) {//i-th vertex placed in the same position as vIndex in the list. Add it index v.indexes.Add(i); vIndex = vertexList.Count; isNew = false; } } if (isNew) { VertexData newVertex = new VertexData(); newVertex.position = vPos; newVertex.indexes = new List <int>(); newVertex.indexes.Add(i); vertexList.Add(newVertex); } } List <EdgeData> edgesList = new List <EdgeData>(); int originalTrianglesCount = originalIndexes.Length / 3; for (int i = 0; i < originalTrianglesCount; i++) { int i1 = WG_Helper.GetVertexIndex(originalIndexes[3 * i], vertexList); int i2 = WG_Helper.GetVertexIndex(originalIndexes[3 * i + 1], vertexList); int i3 = WG_Helper.GetVertexIndex(originalIndexes[3 * i + 2], vertexList); bool isFindI12 = false; bool isFindI23 = false; bool isFindI31 = false; for (int eIndex = 0; eIndex < edgesList.Count; eIndex++) { isFindI12 = edgesList[eIndex].TryToAdd(i1, i2) || isFindI12; isFindI23 = edgesList[eIndex].TryToAdd(i2, i3) || isFindI23; isFindI31 = edgesList[eIndex].TryToAdd(i3, i1) || isFindI31; } if (!isFindI12) { EdgeData newEdge = new EdgeData(i1, i2); edgesList.Add(newEdge); } if (!isFindI23) { EdgeData newEdge = new EdgeData(i2, i3); edgesList.Add(newEdge); } if (!isFindI31) { EdgeData newEdge = new EdgeData(i3, i1); edgesList.Add(newEdge); } } //filter boundary edges, if it contains vertex of the other boundary edge inside it List <int> boundaryIndexes = new List <int>(); for (int i = 0; i < edgesList.Count; i++) { if (edgesList[i].IsBoundary()) { boundaryIndexes.Add(i); } } bool isUpdate = true; while (isUpdate) { isUpdate = false; int i = 0; while (i < boundaryIndexes.Count) { IntInt currentEdge; currentEdge.value01 = edgesList[boundaryIndexes[i]].GetEdgeVertices().value1; currentEdge.value02 = edgesList[boundaryIndexes[i]].GetEdgeVertices().value2; //IntIntClass currentEdge = edgesList[boundaryIndexes[i]].GetEdgeVertices(); Vector3 currentStart = vertexList[currentEdge.value01].position; Vector3 currentEnd = vertexList[currentEdge.value02].position; if (Vector3.Distance(currentStart, currentEnd) < 0.01f) { boundaryIndexes.RemoveAt(i); i = boundaryIndexes.Count + 1; isUpdate = true; } else { int j = 0; while (j < boundaryIndexes.Count) { IntInt testEdge; testEdge.value01 = edgesList[boundaryIndexes[j]].GetEdgeVertices().value1; testEdge.value02 = edgesList[boundaryIndexes[j]].GetEdgeVertices().value2; //IntIntClass testEdge = edgesList[boundaryIndexes[j]].GetEdgeVertices(); Vector3 testStart = vertexList[testEdge.value01].position; Vector3 testEnd = vertexList[testEdge.value02].position; if (Vector3.Distance(testStart, testEnd) < 0.01f) { boundaryIndexes.RemoveAt(j); j = boundaryIndexes.Count + 1; i = boundaryIndexes.Count + 1; isUpdate = true; } else if (i != j && boundaryIndexes[i] < boundaryIndexes[j]) { if (IsEdgesCollinear(currentStart, currentEnd, testStart, testEnd)) { if (IsPointsClose(currentStart, testEnd) && IsPointOnTheEdge(testStart, currentStart, currentEnd)) { EdgeData ith = new EdgeData(testEdge.value01, currentEdge.value02); EdgeData jth = new EdgeData(currentEdge.value01, testEdge.value02); edgesList[boundaryIndexes[i]] = ith; edgesList[boundaryIndexes[j]] = jth; i = boundaryIndexes.Count + 1; j = boundaryIndexes.Count + 1; isUpdate = true; } else if (IsPointsClose(currentEnd, testStart) && IsPointOnTheEdge(testEnd, currentStart, currentEnd)) { EdgeData ith = new EdgeData(currentEdge.value01, testEdge.value02); EdgeData jth = new EdgeData(testEdge.value01, currentEdge.value02); edgesList[boundaryIndexes[i]] = ith; edgesList[boundaryIndexes[j]] = jth; i = boundaryIndexes.Count + 1; j = boundaryIndexes.Count + 1; isUpdate = true; } else if (IsPointsClose(currentStart, testEnd) && IsPointOnTheEdge(currentEnd, testStart, testEnd)) { EdgeData ith = new EdgeData(currentEdge.value01, testEdge.value02); EdgeData jth = new EdgeData(testEdge.value01, currentEdge.value02); edgesList[boundaryIndexes[i]] = ith; edgesList[boundaryIndexes[j]] = jth; i = boundaryIndexes.Count + 1; j = boundaryIndexes.Count + 1; isUpdate = true; } else if (IsPointsClose(currentEnd, testStart) && IsPointOnTheEdge(currentStart, testStart, testEnd)) { EdgeData ith = new EdgeData(testEdge.value01, currentEdge.value02); EdgeData jth = new EdgeData(currentEdge.value01, testEdge.value02); edgesList[boundaryIndexes[i]] = ith; edgesList[boundaryIndexes[j]] = jth; i = boundaryIndexes.Count + 1; j = boundaryIndexes.Count + 1; isUpdate = true; } else if (IsPointsClose(currentEnd, testStart) && IsPointsClose(currentStart, testEnd)) { EdgeData ith = new EdgeData(currentEdge.value01, currentEdge.value01); EdgeData jth = new EdgeData(testEdge.value01, testEdge.value01); edgesList[boundaryIndexes[i]] = ith; edgesList[boundaryIndexes[j]] = jth; i = boundaryIndexes.Count + 1; j = boundaryIndexes.Count + 1; isUpdate = true; } } } j++; } } i++; } } //copy to the output List <BoundaryEdge> toReturn = new List <BoundaryEdge>(); for (int i = 0; i < boundaryIndexes.Count; i++) { int index = boundaryIndexes[i]; IntIntClass edge = edgesList[index].GetEdgeVertices(); BoundaryEdge newEdge = new BoundaryEdge(); newEdge.index = index; newEdge.start = vertexList[edge.value1].position; newEdge.end = vertexList[edge.value2].position; newEdge.startVertex = edge.value1; newEdge.endVertes = edge.value2; toReturn.Add(newEdge); } return(toReturn); }
void ExportScene(Transform locationRoot) { WG_Helper.ClearFolder(Application.dataPath + assetLocationSOPath); for (int i = 0; i < locationRoot.childCount; i++) { Transform loc = locationRoot.GetChild(i); WG_LocationController locController = loc.GetComponent <WG_LocationController>(); if (locController != null) { locController.ExportLocation("Assets" + assetLocationXMLPath, "Assets" + assetLocationSOPath, minimapSize, minimapCamera, minimapCameraHeight, "Assets" + assetMinimapPath); } } #if UNITY_EDITOR //export navmesh WG_TerrainBuilder builderComponent = builder.gameObject.GetComponent <WG_TerrainBuilder>(); NavMeshData data = builderComponent.GetNavmeshData(); string navmeshAssetPath = ""; if (data != null) { navmeshAssetPath = "navmeshes/" + data.name; AssetImporter.GetAtPath(AssetDatabase.GetAssetPath(data)).SetAssetBundleNameAndVariant(navmeshAssetPath, ""); } else { if (localNavMesh == null) { Debug.Log("Navmesh data is null, can't export it."); } else { Debug.Log("Use local version of the navmesh data object."); data = localNavMesh; navmeshAssetPath = "navmeshes/" + localNavMesh.name; AssetImporter.GetAtPath(AssetDatabase.GetAssetPath(localNavMesh)).SetAssetBundleNameAndVariant(navmeshAssetPath, ""); } } //create xml with navmeshlink and starting points GlobalLocation globalLocation = new GlobalLocation(); if (navmeshAssetPath.Length > 0 && data != null) { globalLocation.navmeshData = new NavmeshData() { link = navmeshAssetPath, name = data.name }; if (exportPlayerPositionsInLocations) { globalLocation.positions = new List <PositionData>(); WG_Position[] positions = WG_Helper.FindObjectsOfTypeAll <WG_Position>().ToArray();// FindObjectsOfType<WG_Position>(); for (int i = 0; i < positions.Length; i++) { Vector3 pos = positions[i].gameObject.transform.position; IntPair loc = WG_Helper.GetLocationCoordinates(pos, builderComponent.segmentSize); if (loc.u >= builderComponent.segmentsMinX && loc.u <= builderComponent.segmenstMaxX && loc.v >= builderComponent.segmentsMinY && loc.v <= builderComponent.segmenstMaxY) { globalLocation.positions.Add(new PositionData() { positionX = pos.x, positionY = pos.y, positionZ = pos.z }); } } if (globalLocation.positions.Count == 0) { Debug.Log("No start positions on the scene. Add default position (0, 0, 0)."); globalLocation.positions.Add(new PositionData() { positionX = 0.0f, positionY = 0.0f, positionZ = 0.0f }); } } globalLocation.bounds = new LocationsBounds() { minU = builderComponent.segmentsMinX, maxU = builderComponent.segmenstMaxX, minV = builderComponent.segmentsMinY, maxV = builderComponent.segmenstMaxY }; globalLocation.locationSize = new LocationSize() { value = builderComponent.segmentSize }; string globalLocationName = "global_location"; string globalLocationAssetPath = "Assets" + assetLocationXMLPath + globalLocationName + ".xml"; globalLocation.Save(globalLocationAssetPath); AssetDatabase.ImportAsset(globalLocationAssetPath, ImportAssetOptions.ForceUpdate); AssetImporter.GetAtPath(globalLocationAssetPath).SetAssetBundleNameAndVariant("locations/" + globalLocationName, ""); //export server data SavePlayerPositions(builderComponent); SaveCollisionMap(serverPath); SaveTowerPositions(builderComponent); //also export locations data to SO GlobalLocationDataSO globalSO = ScriptableObjectUtility.CreateAsset <GlobalLocationDataSO>("Assets" + assetLocationSOPath, globalLocationName); globalSO.minU = builderComponent.segmentsMinX; globalSO.maxU = builderComponent.segmenstMaxX; globalSO.minV = builderComponent.segmentsMinY; globalSO.maxV = builderComponent.segmenstMaxY; globalSO.size = builderComponent.segmentSize; globalSO.navmeshName = data.name; globalSO.navmeshLink = navmeshAssetPath; if (exportPlayerPositionsInLocations) { globalSO.startPositions = new List <Vector3>(); for (int pi = 0; pi < globalLocation.positions.Count; pi++) { globalSO.startPositions.Add(new Vector3(globalLocation.positions[pi].positionX, globalLocation.positions[pi].positionY, globalLocation.positions[pi].positionZ)); } } EditorUtility.SetDirty(globalSO); AssetDatabase.SaveAssets(); AssetDatabase.Refresh(); AssetImporter.GetAtPath("Assets" + assetLocationSOPath + globalLocationName + ".asset").SetAssetBundleNameAndVariant("locations_so/" + globalLocationName, ""); } #endif }