public void Execute(ArchetypeChunk chunk, int chunkIndex, int firstEntityIndex)
            {
                if (!chunk.DidChange(RendererBounds, LastSystemVersion) && !chunk.DidChange(LocalToWorld, LastSystemVersion))
                {
                    return;
                }

                //@TODO: Delta change...
                var        worldBounds  = chunk.GetNativeArray(WorldRenderBounds);
                var        localBounds  = chunk.GetNativeArray(RendererBounds);
                var        localToWorld = chunk.GetNativeArray(LocalToWorld);
                MinMaxAABB combined     = MinMaxAABB.Empty;

                for (int i = 0; i != localBounds.Length; i++)
                {
                    var transformed = AABB.Transform(localToWorld[i].Value, localBounds[i].Value);

                    worldBounds[i] = new WorldRenderBounds {
                        Value = transformed
                    };
                    combined.Encapsulate(transformed);
                }

                chunk.SetChunkComponentData(ChunkWorldRenderBounds, new ChunkWorldRenderBounds {
                    Value = combined
                });
            }
示例#2
0
    public static void CreatePanel(EntityManager dstManager, GameObjectConversionSystem conversionSystem, GameObject gameObject, GameObject prefab, LocalToWorld localToWorld)
    {
        var meshRenderer = prefab.GetComponent <MeshRenderer>();
        var meshFilter   = prefab.GetComponent <MeshFilter>();
        var materials    = new List <Material>(10);
        var mesh         = meshFilter.sharedMesh;

        meshRenderer.GetSharedMaterials(materials);

        var segmentEntity = conversionSystem.CreateAdditionalEntity(gameObject);
        var pos           = localToWorld.Position;

        var renderBounds = new RenderBounds
        {
            Value = new AABB
            {
                Center  = new float3(0.0f, 0.0f, 0.0f),
                Extents = new float3(0.5f, 0.5f, 0.5f)
            }
        };
        var worldRenderBounds = new WorldRenderBounds
        {
            Value = new AABB
            {
                Center  = pos,
                Extents = new float3(0.5f, 0.5f, 0.5f)
            }
        };
        var frozenRenderSceneTag = new FrozenRenderSceneTag
        {
            HasStreamedLOD = 0,
            SceneGUID      = Hash128.Compute("Grid Panel"),
            SectionIndex   = 0
        };

#if UNITY_EDITOR
        dstManager.SetName(segmentEntity, "Grid Panel");
#endif
        dstManager.AddComponentData(segmentEntity, localToWorld);
        dstManager.AddComponentData(segmentEntity, renderBounds);

        dstManager.AddComponentData(segmentEntity, worldRenderBounds);
        dstManager.AddSharedComponentData(segmentEntity, frozenRenderSceneTag);
        dstManager.AddComponent(segmentEntity, typeof(Static));

        CreateRenderMesh(segmentEntity, dstManager, conversionSystem, meshRenderer, mesh, materials);
    }
示例#3
0
            public void Execute(ArchetypeChunk chunk, int chunkIndex, int firstEntityIndex)
            {
                var        worldBounds  = chunk.GetNativeArray(WorldRenderBounds);
                var        localBounds  = chunk.GetNativeArray(RendererBounds);
                var        localToWorld = chunk.GetNativeArray(LocalToWorld);
                MinMaxAABB combined     = MinMaxAABB.Empty;

                for (int i = 0; i != localBounds.Length; i++)
                {
                    var transformed = AABB.Transform(localToWorld[i].Value, localBounds[i].Value);

                    worldBounds[i] = new WorldRenderBounds {
                        Value = transformed
                    };
                    combined.Encapsulate(transformed);
                }

                chunk.SetChunkComponentData(ChunkWorldRenderBounds, new ChunkWorldRenderBounds {
                    Value = combined
                });
            }
    public void Convert(Entity entity, EntityManager dstManager, GameObjectConversionSystem conversionSystem)
    {
        // set up initial counts and values for everything
        MaxFarmers  = maxFarmers;
        MaxDrones   = maxDrones;
        droneCount  = 0;
        farmerCount = 0;
        BoardWidth  = boardWidth;
        PerformTaskSystem.InitializeTillSystem(maxFarmers);

        // set up mesh rendering from prefab
        MeshRenderer meshRenderer = TilePrefab.GetComponent <MeshRenderer>();
        var          meshFilter   = TilePrefab.GetComponent <MeshFilter>();
        var          materials    = new List <Material>(MATERIAL_NUMBER);
        var          mesh         = meshFilter.sharedMesh;

        meshRenderer.GetSharedMaterials(materials);

        // set up entity and manager
        entityManager = dstManager;
        boardEntity   = conversionSystem.GetPrimaryEntity(TilePrefab);

        // a board archetype
        boardArchetype = entityManager.CreateArchetype(
            typeof(Translation), typeof(GridBoard));

        // Generate rock prefab entity
        rockEntity = conversionSystem.GetPrimaryEntity(RockPrefab);
        entityManager.AddComponentData(rockEntity, new RockTag {
        });

        // Generate drone prefab entity
        droneEntity = conversionSystem.GetPrimaryEntity(DronePrefab);
        entityManager.AddComponentData(droneEntity, new MovementComponent {
        });
        entityManager.AddComponentData(droneEntity, new EntityInfo {
            specificEntity = droneEntity, type = -1
        });
        entityManager.AddComponent(droneEntity, typeof(DroneTag));

        // generate 3 plants to use for everything else
        plantEntity = new Entity[DIFF_PLANT_COUNT];
        Unity.Mathematics.Random rand  = new Unity.Mathematics.Random(42);
        int          nextRandom        = rand.NextInt();
        MeshRenderer meshPlantRenderer = PlantMeshPrefab.GetComponent <MeshRenderer>();
        var          meshPlantFilter   = PlantMeshPrefab.GetComponent <MeshFilter>();
        var          materials2        = new List <Material>(MATERIAL_NUMBER);

        meshPlantRenderer.GetSharedMaterials(materials2);

        for (int i = 0; i < DIFF_PLANT_COUNT; i++)
        {
            plantMesh = GeneratePlantMesh(nextRandom);
            var meshPlantTmp = Instantiate(plantMesh);
            meshPlantFilter.sharedMesh = meshPlantTmp;
            plantEntity[i]             = conversionSystem.GetPrimaryEntity(PlantMeshPrefab);
            Convert(plantEntity[i], dstManager, conversionSystem, meshPlantRenderer, meshPlantTmp, materials2);
            entityManager.AddComponent(plantEntity[i], typeof(PlantTag));
            entityManager.SetComponentData(plantEntity[i], new Translation {
                Value = new float3(-1, -5, -1)
            });
            entityManager.AddComponentData(plantEntity[i], new NonUniformScale {
                Value = new float3(1.0f, 2.0f, 1.0f)
            });
            entityManager.AddComponentData(plantEntity[i], new PlantComponent
            {
                timeGrown    = 0,
                state        = (int)PlantState.None,
                reserveIndex = -1
            });
            nextRandom = rand.NextInt();
        }
        // create atlas and texture info
        CalculatePredeterminedTextures();
        // if textures changed we'd have to re-create them with the following:
        //CreateAtlasData();
        //CreateTextures();

        // the texture indices in the world
        // clearing memory gives everything the first image in the uv's,
        // which is conveniently non-tilled ground
        blockIndices = new NativeArray <int>(BoardWidth * BoardWidth, Allocator.Persistent, NativeArrayOptions.ClearMemory);

        // initialize hash table that stores all the tile state info
        GridData gdata = GridData.GetInstance();

        gdata.Initialize(BoardWidth);

        // generate the terrain mesh and add it to the world
        Mesh mesh2;
        int  maxX = BoardWidth / MAX_MESH_WIDTH;
        int  maxZ = BoardWidth / MAX_MESH_WIDTH;

        // only one mesh
        allMeshes = new Mesh[(maxX + 1) * (maxZ + 1)];
        allUVs    = new NativeArray <float2> [(maxX + 1) * (maxZ + 1)];
        allVerts  = new NativeArray <float3> [(maxX + 1) * (maxZ + 1)];
        allTris   = new NativeArray <int> [(maxX + 1) * (maxZ + 1)];

        // for small enough meshes it's just a single mesh in the world
        int height = 0;

        if (maxX == 0 && maxZ == 0)
        {
            int cornerX = 0;
            int cornerZ = 0;
            allUVs[0] = new NativeArray <float2>(BoardWidth * BoardWidth * 4, Allocator.Persistent);
            mesh2     = GenerateTerrainMesh(BoardWidth, BoardWidth, 0, 0, height, allUVs[0]);

            mesh                  = Instantiate(mesh2);
            allMeshes[0]          = mesh;
            meshFilter.sharedMesh = mesh;

            var segmentEntity = conversionSystem.CreateAdditionalEntity(gameObject);
            var pos           = new float3(cornerX, 0, cornerZ);

            var localToWorld = new LocalToWorld
            {
                Value = float4x4.Translate(pos)
            };
            var aabb = new AABB
            {
                Center  = pos,
                Extents = new float3(BoardWidth, 0.5f, BoardWidth)
            };
            var worldRenderBounds = new WorldRenderBounds
            {
                Value = aabb
            };

            dstManager.AddComponentData(segmentEntity, localToWorld);
            dstManager.AddComponentData(segmentEntity, worldRenderBounds);
            dstManager.AddComponent(segmentEntity, ComponentType.ChunkComponent <ChunkWorldRenderBounds>());
            //dstManager.AddComponent(segmentEntity, typeof(Frozen));

            Convert(segmentEntity, dstManager, conversionSystem, meshRenderer, mesh, materials);
        }
        else
        {
            // FIX: this could be parallelized as all meshes are
            // independent from each other
            // for larger meshes it's broken up into
            // 64k vertex pieces

            for (int index = 0; index < (maxX + 1) * (maxZ + 1); index++)
            {
                //Parallel.For(0, (maxX + 1) * (maxZ + 1), (index) =>
                //{
                int x = (int)(index / (maxX + 1));
                int z = index - (maxX + 1) * x;
                //UnityEngine.Debug.Log("x: " + x + " " + z);
                int cornerX = x * MAX_MESH_WIDTH;
                int cornerZ = z * MAX_MESH_WIDTH;
                int width   = 0;
                int depth   = 0;
                int startX  = 0;
                int startZ  = 0;

                float3 pos = new float3(cornerX, 0, cornerZ);

                if (x < maxX && z < maxZ)
                {
                    startX = cornerX;
                    startZ = cornerZ;
                    width  = MAX_MESH_WIDTH;
                    depth  = MAX_MESH_WIDTH;
                }
                else if (x < maxX)
                {
                    startX = cornerX;
                    startZ = cornerZ;
                    width  = MAX_MESH_WIDTH;
                    depth  = BoardWidth - cornerZ;
                }
                else if (z < maxZ)
                {
                    startX = cornerX;
                    startZ = cornerZ;
                    width  = BoardWidth - cornerX;
                    depth  = MAX_MESH_WIDTH;
                }
                else
                {
                    startX = cornerX;
                    startZ = cornerZ;
                    width  = BoardWidth - cornerX;
                    depth  = BoardWidth - cornerZ;
                }
                //UnityEngine.Debug.Log("index " + index + " " + width + " " + depth +
                //    " " + cornerX + " " + cornerZ);

                allUVs[index]   = new NativeArray <float2>(width * depth * 4, Allocator.Persistent);
                allVerts[index] = new NativeArray <float3>(width * depth * 4, Allocator.Persistent);
                allTris[index]  = new NativeArray <int>(width * depth * 6, Allocator.Persistent);
                NativeArray <float2> uvs  = allUVs[index];
                NativeArray <float3> vert = allVerts[index];
                NativeArray <int>    tri  = allTris[index];

                int triangleIndex    = 0;
                int vertexIndex      = 0;
                int vertexMultiplier = 4; // create quads to fit uv's to so we can use more than one uv

                int uvIndex = 0;

                for (x = 0; x < width; x++)
                {
                    for (z = 0; z < depth; z++)
                    {
                        int y            = height;
                        int textureIndex = 0;
                        int index2D      = (z + startZ) + width * (x + startX);
                        textureIndex = blockIndices[index2D];

                        // add vertices for the quad first
                        // front
                        vert[vertexIndex]     = new float3(x + 0.5f, 0.5f, z + -0.5f);
                        vert[vertexIndex + 1] = new float3(x + 0.5f, 0.5f, z + 0.5f);
                        vert[vertexIndex + 2] = new float3(x + -0.5f, 0.5f, z + 0.5f);
                        vert[vertexIndex + 3] = new float3(x + -0.5f, 0.5f, z + -0.5f);

                        // set the UV's
                        uvs[uvIndex] = new float2(textures[textureIndex].pixelStartX,
                                                  textures[textureIndex].pixelStartY);
                        uvs[uvIndex + 1] = new float2(textures[textureIndex].pixelStartX,
                                                      textures[textureIndex].pixelEndY);
                        uvs[uvIndex + 2] = new float2(textures[textureIndex].pixelEndX,
                                                      textures[textureIndex].pixelEndY);
                        uvs[uvIndex + 3] = new float2(textures[textureIndex].pixelEndX,
                                                      textures[textureIndex].pixelStartY);
                        uvIndex += 4;

                        // front or top face
                        tri[triangleIndex]     = vertexIndex;
                        tri[triangleIndex + 1] = vertexIndex + 2;
                        tri[triangleIndex + 2] = vertexIndex + 1;
                        tri[triangleIndex + 3] = vertexIndex;
                        tri[triangleIndex + 4] = vertexIndex + 3;
                        tri[triangleIndex + 5] = vertexIndex + 2;
                        triangleIndex         += 6;

                        // increment the vertices
                        vertexIndex += vertexMultiplier;
                    }
                }
                AABB aabb;
                aabb = new AABB
                {
                    Center  = pos,
                    Extents = new float3(width, 0.5f, depth)
                };
                mesh2 = new Mesh();
                mesh2.SetVertices(allVerts[index]);
                mesh2.SetUVs(0, allUVs[index]);
                mesh2.SetTriangles(allTris[index].ToArray(), 0);
                mesh2.RecalculateNormals();
                mesh2.RecalculateBounds();
                mesh = Instantiate(mesh2);
                meshFilter.sharedMesh = mesh;
                //Debug.Log("creating mesh for : " + x + " " + z + "  " + (z + (maxX + 1) * x));
                allMeshes[index] = mesh;
                var segmentEntity = conversionSystem.CreateAdditionalEntity(gameObject);

                var localToWorld = new LocalToWorld
                {
                    Value = float4x4.Translate(pos)
                };
                var worldRenderBounds = new WorldRenderBounds
                {
                    Value = aabb
                };

                dstManager.AddComponentData(segmentEntity, localToWorld);
                dstManager.AddComponentData(segmentEntity, worldRenderBounds);
                dstManager.AddComponent(segmentEntity, ComponentType.ChunkComponent <ChunkWorldRenderBounds>());
                //dstManager.AddComponent(segmentEntity, typeof(Frozen));

                Convert(segmentEntity, dstManager, conversionSystem, meshRenderer, mesh, materials);
            }
            //);
        }

        // generate rocks and such on the grid
        GenerateGrid();

        // generate the farmers
        // Create farmer entity prefab from the game object hierarchy once
        farmerEntity = conversionSystem.GetPrimaryEntity(FarmerPrefab);
        entityManager.AddComponent <FarmerTag>(farmerEntity);

        // FIX: this could be parallelized
        // NOTE: NOT WORTH DOING UNTIL ALL THE add/set component is
        // part of burst as that's all this is
        // Also note: usually not that many farmers to justify
        // parallelization.
        for (int i = 0; i < farmerNumber; i++)
        {
            farmerCount++;
            var instance = entityManager.Instantiate(farmerEntity);
            if (i == 0)
            {
                firstFarmer = instance;
            }
            int startX = Math.Abs(rand.NextInt()) % gdata.width;
            int startZ = Math.Abs(rand.NextInt()) % gdata.width;

            // Place the instantiated entity in a grid with some noise
            var position = new float3(startX, 2, startZ);
            entityManager.SetComponentData(instance, new Translation()
            {
                Value = position
            });
            var data = new MovementComponent
            {
                startPos  = new float2(startX, startZ),
                speed     = 2,
                targetPos = new float2(startX, startZ),
            };
            var entityData = new EntityInfo {
                specificEntity = instance, type = -1
            };
            entityManager.AddComponentData(instance, data);
            entityManager.AddComponentData(instance, entityData);

            // give his first command based on the 1's in the hash
            entityManager.AddComponent <NeedsTaskTag>(instance);
        }

        if (blockIndices.IsCreated)
        {
            blockIndices.Dispose();
        }
    }