コード例 #1
0
        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);
        }
コード例 #2
0
        protected override void OnChunkCreated(Chunk chunk)
        {
            base.OnChunkCreated(chunk);

            FoliageCore_Chunk FoliageChunkInstance = chunk as FoliageCore_Chunk;

            if (FoliageChunkInstance != null)
            {
                foliageChunks.Add(FoliageChunkInstance);
            }
        }
コード例 #3
0
        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;
            }
        }
コード例 #4
0
        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
        }
コード例 #5
0
        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);
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }