protected override void OnPositionChanged(Vector3 newPosition) { base.OnPositionChanged(newPosition); if (includedInInteractionMap) { if (Vector3.Distance(transform.position, lastPosition) > 1f) { FoliageReceiver.CallInteractionsRefresh(); } } }
public void RecalculateInteractions(FoliageReceiver receiver) { Clear(false, defaultColor); var relevantInteractions = BaseInteraction.GetRelevantInteractions(receiver); for (int i = 0; i < relevantInteractions.Count; i++) { relevantInteractions[i].UpdateInteraction(receiver); } SetPixels32(); }
protected Vector2 GetNormalizedPosition(Vector2 position, FoliageReceiver receiver) { if (receiver.latestChunk == null) { return(Vector2.zero); } var fManagerTransform = receiver.middleFoliageChunkFromNeighbors.isFoliageInstanceAttached ? receiver.middleFoliageChunkFromNeighbors.GetOrCreateFoliageManagerInstance() : null; Vector2 fManagerDepth = new Vector2(fManagerTransform.transform.position.x, fManagerTransform.transform.position.z); return(receiver.interactionMap.TransformCord(position - fManagerDepth - receiver.latestChunk.position)); }
public static List <BaseInteraction> GetRelevantInteractions(FoliageReceiver receiver) { List <BaseInteraction> relevantInteractions = new List <BaseInteraction>(); BaseInteraction interaction; for (int i = 0; i < interactions.Count; i++) { interaction = interactions[i]; if (Vector3.Distance(receiver.threadPositionDepth, interaction.threadPositionDepth) <= receiver.interactionMap.radius) { relevantInteractions.Add(interaction); } } return(relevantInteractions); }
public static InteractionMap CreateMap(FoliageReceiver receiver) { if (FoliageCore_MainManager.instance == null) { return(null); } int size = receiver.interactionMapResolutionIntegral; Texture2D map = new Texture2D(size, size, TextureFormat.RGBA32, false, true); Color32[] pixels = new Color32[size * size]; for (int i = 0; i < size * size; i++) { pixels[i] = defaultColor; } map.SetPixels32(pixels); map.Apply(); return(new InteractionMap(map, map.GetPixels32(), (int)FoliageCore_MainManager.instance.instancesSectorChunkSize)); }
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); } } } } } } } }
protected Vector2 GetNormalizedPosition(FoliageReceiver receiver) { return(GetNormalizedPosition(threadPositionDepth, receiver)); }
/// <summary> /// Please dont use map.SetPixels, it will be assigned later on automatically.. /// </summary> /// <param name="receiver"></param> protected virtual void UpdateInteraction(FoliageReceiver receiver, Vector2 normalizedPosition) { }
/// <summary> /// Update the interaction /// </summary> /// <param name="receiver"></param> public void UpdateInteraction(FoliageReceiver receiver) { UpdateInteraction(receiver, GetNormalizedPosition(receiver)); }