internal static FoliageManagerInstance CreateInstance(FoliageCore_Chunk attachedTo) { GameObject go = new GameObject("Foliage Manager Instance"); go.transform.SetParent(attachedTo.transform); go.transform.localPosition = Vector3.zero; go.transform.localRotation = Quaternion.identity; go.transform.localScale = Vector3.one; FoliageManagerInstance mInstance = go.AddComponent <FoliageManagerInstance>(); mInstance._attachedTo = attachedTo; #if UNITY_EDITOR UnityEditor.EditorUtility.DisplayProgressBar("uNature", "Creating Manager Instance - Color Map", 0f); #endif if (mInstance.colorMap == null) { } ; #if UNITY_EDITOR UnityEditor.EditorUtility.DisplayProgressBar("uNature", "Creating Manager Instance - Grass Maps", 0.33f); #endif if (mInstance.grassMaps == null) { } ; #if UNITY_EDITOR UnityEditor.EditorUtility.DisplayProgressBar("uNature", "Creating Manager Instance - World Map", 0.67f); #endif if (mInstance.worldMap == null) { } ; #if UNITY_EDITOR UnityEditor.EditorUtility.ClearProgressBar(); #endif #if UNITY_EDITOR if (!Application.isPlaying) { #if UNITY_5_3_OR_NEWER UnityEditor.SceneManagement.EditorSceneManager.MarkAllScenesDirty(); #else UnityEditor.EditorApplication.MarkSceneDirty(); #endif } #endif return(mInstance); }
protected override void OnChunkCreated(Chunk chunk) { base.OnChunkCreated(chunk); FoliageCore_Chunk FoliageChunkInstance = chunk as FoliageCore_Chunk; if (FoliageChunkInstance != null) { foliageChunks.Add(FoliageChunkInstance); } }
protected override void Update() { if (!Application.isPlaying) { return; } base.Update(); FoliageCore_Chunk midChunk = middleFoliageChunkFromNeighbors; // middle chunk FoliageManagerInstance mInstance; if ((!wasPositionChecked || Vector3.Distance(lastCheckedPosition, transform.position) >= checkDistance) && isGrassReceiver && midChunk != null && midChunk.isFoliageInstanceAttached) { //latestChunk = FoliageManager.instance.sector.getChunk(new Vector3(transform.position.x - FoliageManager.instance.transform.position.x, 0, transform.position.z - FoliageManager.instance.transform.position.z), 0) as FoliageChunk; mInstance = midChunk.GetOrCreateFoliageManagerInstance(); latestChunk = mInstance.sector.getChunk(new Vector3(transform.position.x - mInstance.transform.position.x, 0, transform.position.z - mInstance.transform.position.z), 0) as FoliageChunk; _neighbors = UNStandaloneUtility.GetFoliageChunksNeighbors(transform.position - FoliageCore_MainManager.instance.transform.position, _neighbors); wasPositionChecked = true; lastCheckedPosition = transform.position; } }
void OnSceneGUI(SceneView sView) { if (FoliageCore_MainManager.instance == null) { return; } var current = Event.current; if (current != null) { if (Event.current.keyCode == KeyCode.Escape) // try to disable brush on Scene window { chosenBrushes.Clear(); EditorUtility.SetDirty(FoliageDB.instance); EditorUtility.SetDirty(FoliageCore_MainManager.instance); } EventType type = current.type; var ray = HandleUtility.GUIPointToWorldRay(current.mousePosition); RaycastHit hit; #region Brushes if (chosenBrushes.Count > 0 && chosenPrototypes.Count > 0) { HandleUtility.AddDefaultControl(GUIUtility.GetControlID(FocusType.Passive)); //Disable scene view mouse selection UNBrushUtility.instance.DrawBrush(chosenBrushes[0].brushTexture, Color.cyan, ray.origin, Quaternion.FromToRotation(Vector3.forward, ray.direction), paintBrushSize); bool hitTarget = Physics.Raycast(ray, out hit, Mathf.Infinity); if (type == EventType.MouseDrag && current.button == 0 && hitTarget) { if (Vector3.Distance(lastBrushPosition, hit.point) > 1) { lastBrushPosition = hit.point; PaintBrush(current.shift, new Vector2(hit.point.x, hit.point.z), chosenBrushes[0]); Repaint(); } if (type == EventType.KeyUp) { HandleUtility.Repaint(); //Enable scene view mouse selection } } } #endregion #region Chunks Selection if (type == EventType.mouseDown && current.button == 0) { RaycastHit[] hits = Physics.RaycastAll(ray, Mathf.Infinity); FoliageCore_Chunk mChunk; for (int i = 0; i < hits.Length; i++) { hit = hits[i]; mChunk = hit.transform.GetComponent <FoliageCore_Chunk>(); if (mChunk != null) { if (selectedChunk == mChunk) // if not changed { selectedChunk = null; } else { selectedChunk = mChunk; } return; } } } } #endregion #region DebugMode if (FoliageCore_MainManager.instance != null) { FoliageCore_MainManager.instance.DEBUG_DrawUI(); } #endregion }
public void OnDrawCamera(Camera camera) { if (!FoliageCore_MainManager.instance.enabled || prototypeMeshInstances == null) { return; } bool runCameraCheck = true; FoliageReceiver receiver = null; #if UNITY_EDITOR runCameraCheck = !UnityEditor.SceneView.GetAllSceneCameras().Contains(camera); #endif if (runCameraCheck) { if (FoliageReceiver.FReceivers.Count == 0) { return; } for (int i = 0; i < FoliageReceiver.FReceivers.Count; i++) { if (camera == FoliageReceiver.FReceivers[i].playerCamera) { receiver = FoliageReceiver.FReceivers[i]; break; } if (i == FoliageReceiver.FReceivers.Count - 1) { return; } } } if (receiver != null && !receiver.isGrassReceiver) { return; } int areaSizeIntegral = FoliageCore_MainManager.FOLIAGE_INSTANCE_AREA_SIZE; FoliageCore_Chunk[] targetedChunks = null; FoliageCore_Chunk currentMChunk; if (receiver == null) { targetedChunks = UNStandaloneUtility.GetFoliageChunksNeighbors(camera.transform.position - transform.position, targetedChunks); latestManagerChunk = targetedChunks[4]; } else { targetedChunks = receiver.neighbors; latestManagerChunk = receiver.middleFoliageChunkFromNeighbors; } Vector3 normalizedCameraPosition; FoliageManagerInstance mInstance; FoliageSector sector; FoliageChunk chunk; float density = FoliageCore_MainManager.instance.density; int instancesResolution = FoliageCore_MainManager.instance.instancesSectorResolution; #region PER_INSTANCE GPUMesh gpuInstance = null; FoliageChunk currentInstanceChunk; Vector3 pos; Material mat; int chunkIndex; FoliageMeshInstancesGroup meshGroup; FoliagePrototype prototype; int maxDensity; FoliageMeshInstance meshInstance; Vector3 chunkPos; int gpuMeshIndex = -1; Camera renderCamera = Application.isPlaying ? camera : null; List <FoliageChunk> chunks; Mesh targetMesh; Dictionary <int, GPUMesh> prototypeInstances; bool useQualitySettingsShadows = FoliageCore_MainManager.instance.useQualitySettingsShadowDistance; float shadowsDistance = FoliageCore_MainManager.instance.foliageShadowDistance; #endregion propertyBlock.SetVector("_StreamingAdjuster", UNStandaloneUtility.GetStreamingAdjuster()); if (receiver != null) { propertyBlock.SetFloat("_InteractionResolution", receiver.interactionMapResolutionIntegral); } for (int i = 0; i < targetedChunks.Length; i++) { currentMChunk = targetedChunks[i]; if (currentMChunk == null) { continue; } normalizedCameraPosition = camera.transform.position; if (!currentMChunk.InBounds(normalizedCameraPosition, 100) || !currentMChunk.isFoliageInstanceAttached) { continue; } mInstance = currentMChunk.GetOrCreateFoliageManagerInstance(); normalizedCameraPosition -= mInstance.transform.position; normalizedCameraPosition.x = Mathf.Clamp(normalizedCameraPosition.x, 0, areaSizeIntegral - 1); normalizedCameraPosition.z = Mathf.Clamp(normalizedCameraPosition.z, 0, areaSizeIntegral - 1); sector = mInstance.sector; chunks = sector.FoliageChunks; prototypeInstances = mInstance.meshInstances; chunk = sector.getChunk(normalizedCameraPosition) as FoliageChunk; if (chunk == null) { continue; } if (receiver != null) { propertyBlock.SetVector(PROPERTY_ID_FOLIAGE_INTERACTION_POSITION, chunk.position3D); } DEBUG_ResetValues(); mInstance.UpdateMaterialBlock(propertyBlock); for (int prototypeIndex = 0; prototypeIndex < FoliageDB.unSortedPrototypes.Count; prototypeIndex++) { prototype = FoliageDB.unSortedPrototypes[prototypeIndex]; if (!prototype.enabled) { continue; } int chunkOffset = FoliageMeshInstance.GENERATION_RANGE_OFFSET(prototype); int prototypeRadius = (int)prototype.FoliageGenerationRadius; propertyBlock.SetTexture(PROPERTY_ID_GRASSMAP, mInstance.grassMaps[prototype].map); //DEBUG _lastRenderedPrototypes++; try { gpuInstance = prototypeInstances[prototype.id]; } catch (System.Exception ex) { Debug.LogError(ex.ToString()); return; } try { mat = prototype.FoliageInstancedMeshData.mat; } catch { // if Foliage db was deleted/ a detail was removed... FoliageCore_MainManager.DestroyMeshInstance(prototype.id); OnDrawCamera(camera); return; } int xIndex; int zIndex; for (int x = 0; x < prototypeRadius; x++) { for (int z = 0; z < prototypeRadius; z++) { xIndex = chunk.x + (x - chunkOffset); zIndex = chunk.z + (z - chunkOffset); if (xIndex < 0 || zIndex < 0) { continue; } chunkIndex = xIndex + (zIndex * instancesResolution); if (chunkIndex >= chunks.Count) { continue; } currentInstanceChunk = chunks[chunkIndex]; if (currentInstanceChunk != null) { chunkPos = currentInstanceChunk.position3D; maxDensity = (int)(currentInstanceChunk.GetMaxDensityOnArea(prototype.id) * density); gpuMeshIndex = gpuInstance.GetMesh(maxDensity); if (gpuMeshIndex != -1) { //meshGroup = gpuInstance.LODMeshInstances[x, z, gpuMeshIndex]; meshGroup = gpuInstance.LODMeshInstances[gpuMeshIndex]; targetMesh = gpuInstance.meshes[gpuMeshIndex].mesh; for (int j = 0; j < meshGroup.Count; j++) { meshInstance = meshGroup[j]; pos = meshInstance.GetPosition(chunkPos); if (pos.x < 0 || pos.z < 0 || pos.x >= areaSizeIntegral || pos.z >= areaSizeIntegral) { continue; } propertyBlock.SetVector(PROPERTY_ID_WORLDPOSITION, pos); //DEBUG _lastRenderedVertices += targetMesh.vertexCount; //DEBUG _lastRenderedDrawCalls++; meshInstance.DrawAndUpdate(pos, targetMesh, mat, renderCamera, normalizedCameraPosition, prototype, propertyBlock, useQualitySettingsShadows, shadowsDistance); } } } } } } } }