コード例 #1
0
ファイル: MeshBuilder.cs プロジェクト: buckslice/shardcraft
    public static void GetBlockMesh(Block block, MeshFilter filter)
    {
        var blockData = JobController.instance.blockData;

        BlockData bd = blockData[block.type];

        var vertices  = Pools.v3N.Get();
        var normals   = Pools.v3N.Get();
        var uvs       = Pools.v3N.Get();
        var uv2s      = Pools.v3N.Get();
        var colors    = Pools.c32N.Get();
        var triangles = Pools.intN.Get();

        NativeMeshData data = new NativeMeshData(vertices, normals, uvs, uv2s, colors, triangles, faceList);

        const int x = 1;
        const int y = 1;
        const int z = 1;

        blockArray.c[x + z * S + y * S * S] = block;

        ushort light = bd.light;

        if (light == 0)
        {
            light = ushort.MaxValue;
        }

        lightArray.c[x + z * S + y * S * S] = new Light {
            torch = light
        };
        lightArray.c[x - 1 + z * S + y * S * S] = new Light {
            torch = light
        };
        lightArray.c[x + (z - 1) * S + y * S * S] = new Light {
            torch = light
        };
        lightArray.c[x + z * S + (y - 1) * S * S] = new Light {
            torch = light
        };
        lightArray.c[x + 1 + z * S + y * S * S] = new Light {
            torch = light
        };
        lightArray.c[x + (z + 1) * S + y * S * S] = new Light {
            torch = light
        };
        lightArray.c[x + z * S + (y + 1) * S * S] = new Light {
            torch = light
        };

        AddBlockFaces(x, y, z, ref data, ref blockArray, ref lightArray, blockData);

        // to correct x,y,z offset
        for (int i = 0; i < vertices.Length; ++i)
        {
            vertices[i] = (vertices[i] - (Vector3.one * 0.75f)) * 2.0f;
        }

        UpdateMeshFilter(filter, vertices, normals, uvs, uv2s, colors, triangles);
    }
コード例 #2
0
ファイル: MeshBuilder.cs プロジェクト: buckslice/shardcraft
    static void AddNorthFace(int x, int y, int z, ref NativeMeshData data)
    {
        Vector3 v;

        v.x = x + 1.0f;
        v.y = y;
        v.z = z + 1.0f;
        data.vertices.Add(v / Chunk.BPU);
        v.y = y + 1.0f;
        data.vertices.Add(v / Chunk.BPU);
        v.x = x;
        data.vertices.Add(v / Chunk.BPU);
        v.y = y;
        data.vertices.Add(v / Chunk.BPU);
    }
コード例 #3
0
ファイル: MeshBuilder.cs プロジェクト: buckslice/shardcraft
    public static void BuildNaive(ref NativeMeshData meshData, ref NativeArray3x3 <Block> blocks, ref NativeArray3x3 <Light> lights, NativeArray <BlockData> blockData)
    {
        for (int y = 0; y < S; y++)
        {
            for (int z = 0; z < S; z++)
            {
                for (int x = 0; x < S; x++)
                {
                    //blocks.c[x + z * S + y * S * S].GetType().AddDataNative(x, y, z, ref data, ref blocks, ref lights, faces);

                    BlockData bd = blockData[blocks.c[x + z * S + y * S * S].type];

                    if (bd.renderType > 0)
                    {
                        AddBlockFaces(x, y, z, ref meshData, ref blocks, ref lights, blockData);
                    }
                }
            }
        }
    }
コード例 #4
0
    // also record list of who needs to update after this (if u edit their light)

    public void Execute()
    {
#if _DEBUG
        long initLightTime    = 0;
        long processLightTime = 0;
        long meshingTime      = 0;
        long colliderTime     = 0;
        System.Diagnostics.Stopwatch watch = new System.Diagnostics.Stopwatch();
        watch.Restart();
        UnityEngine.Profiling.Profiler.BeginSample("Lighting");
#endif

        //LightCalculator.AddSunlightRemovals(ref lights, lightOps, lightRBFS);

        // if chunk hasnt been rendered before then check each block to see if it has any lights
        if (calcInitialLight)
        {
            LightCalculator.CalcInitialLightOps(blocks.c, blockData, lightOps);
#if _DEBUG
            initLightTime = watch.ElapsedMilliseconds;
            watch.Restart();
#endif
            LightCalculator.CalcInitialSunLight(blocks.c, blockData, lights.c, lights.u, lightBFS, upRendered, chunkWorldPos);
        }
        // always call this incase lightBFS comes with some data in it already
        LightCalculator.ProcessSunlight(ref lights, ref blocks, blockData, lightBFS, lightBFS_U, lightRBFS, lightRBFS_U);
        Assert.IsTrue(lightBFS.Count == 0 && lightRBFS.Count == 0);
        LightCalculator.ProcessTorchLightOpsOptimal(ref lights, ref blocks, blockData, lightOps, lightBFS, lightRBFS);
        Assert.IsTrue(lightBFS.Count == 0 && lightRBFS.Count == 0);
        int torchLightFlags = lights.flags;

        // add this so job controller can see after jobs done
        lightBFS.Enqueue(torchLightFlags);

        // also here maybe add nodes that weren't finished due to hitting bottom of chunks

#if _DEBUG
        UnityEngine.Profiling.Profiler.EndSample();
        processLightTime = watch.ElapsedMilliseconds;
        watch.Restart();
        UnityEngine.Profiling.Profiler.BeginSample("Meshing");
#endif

        NativeMeshData meshData = new NativeMeshData(vertices, normals, uvs, uv2s, colors, triangles, faces); // add faces to this
        MeshBuilder.BuildNaive(ref meshData, ref blocks, ref lights, blockData);

#if _DEBUG
        meshingTime = watch.ElapsedMilliseconds;
        watch.Restart();
        UnityEngine.Profiling.Profiler.EndSample();
#endif

#if GEN_COLLIDERS
#if _DEBUG
        UnityEngine.Profiling.Profiler.BeginSample("Collider");
#endif
        if (genCollider)
        {
            MeshBuilder.BuildGreedyCollider(ref blocks, colliderVerts, colliderTris);
        }
#if _DEBUG
        colliderTime = watch.ElapsedMilliseconds;
        UnityEngine.Profiling.Profiler.EndSample();
#endif
#endif

#if _DEBUG
        lightBFS.Enqueue((int)initLightTime);
        lightBFS.Enqueue((int)processLightTime);
        lightBFS.Enqueue((int)meshingTime);
        lightBFS.Enqueue((int)colliderTime);
#endif
    }
コード例 #5
0
ファイル: MeshBuilder.cs プロジェクト: buckslice/shardcraft
    static void AddUVs(int x, int y, int z, ref NativeMeshData data, ref NativeArray3x3 <Block> blocks, NativeArray <BlockData> blockData, Dir dir, bool isLight)
    {
        // calculate uv1s, xy is uv coordinates, z is texture type
        BlockData bd = blockData[blocks.Get(x, y, z).type];

        if (bd.renderType == 1)   // normal texture
        {
            if (bd.texture < 0)   // dynamic, depends on nearby blocks
            {
                data.AddFaceUVs(GetTextureIndex(dir, x, y, z, ref blocks));
            }
            else
            {
                data.AddFaceUVs(bd.texture);
            }
        }
        else if (bd.renderType == 2) // using tiling textures
        {
            if (bd.texture < 0)      // dynamic, depends on nearby blocks
            {
                int texture = GetTileTextureIndex(dir, x, y, z, ref blocks);
                data.AddTileUvs(texture, dir, x, y, z, ref blocks, blockData);
            }
            else
            {
                data.AddTileUvs(bd.texture, dir, x, y, z, ref blocks, blockData);
            }
        }

        // now add uv2s, x is tiletype and y is ambient occlusion (z is unused for now)
        Vector3 uv2_0, uv2_1, uv2_2, uv2_3;

        uv2_0   = uv2_1 = uv2_2 = uv2_3 = default;
        uv2_0.x = uv2_1.x = uv2_2.x = uv2_3.x = bd.renderType == 1 ? 0.5f : 1.5f;
        if (isLight)
        {
            uv2_0.y = uv2_1.y = uv2_2.y = uv2_3.y = 1.0f; // dont add ao on the faces of lights, looks weird
        }
        else
        {
            switch (dir)
            {
            case Dir.west: {
                int up    = GetOpacity(ref blocks, blockData, x - 1, y + 1, z);
                int down  = GetOpacity(ref blocks, blockData, x - 1, y - 1, z);
                int north = GetOpacity(ref blocks, blockData, x - 1, y, z + 1);
                int south = GetOpacity(ref blocks, blockData, x - 1, y, z - 1);
                uv2_0.y = CalcAO(down, north, ref blocks, blockData, x - 1, y - 1, z + 1);
                uv2_1.y = CalcAO(up, north, ref blocks, blockData, x - 1, y + 1, z + 1);
                uv2_2.y = CalcAO(up, south, ref blocks, blockData, x - 1, y + 1, z - 1);
                uv2_3.y = CalcAO(down, south, ref blocks, blockData, x - 1, y - 1, z - 1);
            }
            break;

            case Dir.down: {
                int north = GetOpacity(ref blocks, blockData, x, y - 1, z + 1);
                int south = GetOpacity(ref blocks, blockData, x, y - 1, z - 1);
                int east  = GetOpacity(ref blocks, blockData, x + 1, y - 1, z);
                int west  = GetOpacity(ref blocks, blockData, x - 1, y - 1, z);
                uv2_0.y = CalcAO(south, west, ref blocks, blockData, x - 1, y - 1, z - 1);
                uv2_1.y = CalcAO(south, east, ref blocks, blockData, x + 1, y - 1, z - 1);
                uv2_2.y = CalcAO(north, east, ref blocks, blockData, x + 1, y - 1, z + 1);
                uv2_3.y = CalcAO(north, west, ref blocks, blockData, x - 1, y - 1, z + 1);
            }
            break;

            case Dir.south: {
                int up   = GetOpacity(ref blocks, blockData, x, y + 1, z - 1);
                int down = GetOpacity(ref blocks, blockData, x, y - 1, z - 1);
                int east = GetOpacity(ref blocks, blockData, x + 1, y, z - 1);
                int west = GetOpacity(ref blocks, blockData, x - 1, y, z - 1);
                uv2_0.y = CalcAO(down, west, ref blocks, blockData, x - 1, y - 1, z - 1);
                uv2_1.y = CalcAO(up, west, ref blocks, blockData, x - 1, y + 1, z - 1);
                uv2_2.y = CalcAO(up, east, ref blocks, blockData, x + 1, y + 1, z - 1);
                uv2_3.y = CalcAO(down, east, ref blocks, blockData, x + 1, y - 1, z - 1);
            }
            break;

            case Dir.east: {
                int up    = GetOpacity(ref blocks, blockData, x + 1, y + 1, z);
                int down  = GetOpacity(ref blocks, blockData, x + 1, y - 1, z);
                int north = GetOpacity(ref blocks, blockData, x + 1, y, z + 1);
                int south = GetOpacity(ref blocks, blockData, x + 1, y, z - 1);
                uv2_0.y = CalcAO(down, south, ref blocks, blockData, x + 1, y - 1, z - 1);
                uv2_1.y = CalcAO(up, south, ref blocks, blockData, x + 1, y + 1, z - 1);
                uv2_2.y = CalcAO(up, north, ref blocks, blockData, x + 1, y + 1, z + 1);
                uv2_3.y = CalcAO(down, north, ref blocks, blockData, x + 1, y - 1, z + 1);
            }
            break;

            case Dir.up: {
                int north = GetOpacity(ref blocks, blockData, x, y + 1, z + 1);
                int south = GetOpacity(ref blocks, blockData, x, y + 1, z - 1);
                int east  = GetOpacity(ref blocks, blockData, x + 1, y + 1, z);
                int west  = GetOpacity(ref blocks, blockData, x - 1, y + 1, z);
                uv2_0.y = CalcAO(north, west, ref blocks, blockData, x - 1, y + 1, z + 1);
                uv2_1.y = CalcAO(north, east, ref blocks, blockData, x + 1, y + 1, z + 1);
                uv2_2.y = CalcAO(south, east, ref blocks, blockData, x + 1, y + 1, z - 1);
                uv2_3.y = CalcAO(south, west, ref blocks, blockData, x - 1, y + 1, z - 1);
            }
            break;

            case Dir.north: {
                int up   = GetOpacity(ref blocks, blockData, x, y + 1, z + 1);
                int down = GetOpacity(ref blocks, blockData, x, y - 1, z + 1);
                int east = GetOpacity(ref blocks, blockData, x + 1, y, z + 1);
                int west = GetOpacity(ref blocks, blockData, x - 1, y, z + 1);
                uv2_0.y = CalcAO(down, east, ref blocks, blockData, x + 1, y - 1, z + 1);
                uv2_1.y = CalcAO(up, east, ref blocks, blockData, x + 1, y + 1, z + 1);
                uv2_2.y = CalcAO(up, west, ref blocks, blockData, x - 1, y + 1, z + 1);
                uv2_3.y = CalcAO(down, west, ref blocks, blockData, x - 1, y - 1, z + 1);
            }
            break;

            default:
                break;
            }
        }

        data.uv2s.Add(uv2_0);
        data.uv2s.Add(uv2_1);
        data.uv2s.Add(uv2_2);
        data.uv2s.Add(uv2_3);

        // do anisotropy flip
        if (uv2_0.y + uv2_2.y > uv2_1.y + uv2_3.y)
        {
            data.AddQuadTriangles();
        }
        else
        {
            data.AddFlippedQuadTriangles();
        }
    }
コード例 #6
0
ファイル: MeshBuilder.cs プロジェクト: buckslice/shardcraft
    static void AddBlockFaces(int x, int y, int z, ref NativeMeshData data, ref NativeArray3x3 <Block> blocks, ref NativeArray3x3 <Light> lights, NativeArray <BlockData> blockData)
    {
        bool isLight = LightCalculator.GetIsLight(lights.Get(x, y, z).torch);

        if (!BlockData.RenderSolid(blockData, blocks.Get(x - 1, y, z), Dir.east))
        {
            AddWestFace(x, y, z, ref data);
            AddUVs(x, y, z, ref data, ref blocks, blockData, Dir.west, isLight);
            data.AddFaceColor(LightCalculator.GetColorFromLight(lights.Get(x - 1, y, z)));
            data.AddFaceNormal(Dirs.norm3f[Dirs.WEST]);
            data.faces.Add(new Face {
                pos = (ushort)(x + z * Chunk.SIZE + y * Chunk.SIZE * Chunk.SIZE), dir = Dir.west
            });
        }
        if (!BlockData.RenderSolid(blockData, blocks.Get(x, y - 1, z), Dir.up))
        {
            AddDownFace(x, y, z, ref data);
            AddUVs(x, y, z, ref data, ref blocks, blockData, Dir.down, isLight);
            data.AddFaceColor(LightCalculator.GetColorFromLight(lights.Get(x, y - 1, z)));
            data.AddFaceNormal(Dirs.norm3f[Dirs.DOWN]);
            data.faces.Add(new Face {
                pos = (ushort)(x + z * Chunk.SIZE + y * Chunk.SIZE * Chunk.SIZE), dir = Dir.down
            });
        }
        if (!BlockData.RenderSolid(blockData, blocks.Get(x, y, z - 1), Dir.north))
        {
            AddSouthFace(x, y, z, ref data);
            AddUVs(x, y, z, ref data, ref blocks, blockData, Dir.south, isLight);
            data.AddFaceColor(LightCalculator.GetColorFromLight(lights.Get(x, y, z - 1)));
            data.AddFaceNormal(Dirs.norm3f[Dirs.SOUTH]);
            data.faces.Add(new Face {
                pos = (ushort)(x + z * Chunk.SIZE + y * Chunk.SIZE * Chunk.SIZE), dir = Dir.south
            });
        }
        if (!BlockData.RenderSolid(blockData, blocks.Get(x + 1, y, z), Dir.west))
        {
            AddEastFace(x, y, z, ref data);
            AddUVs(x, y, z, ref data, ref blocks, blockData, Dir.east, isLight);
            data.AddFaceColor(LightCalculator.GetColorFromLight(lights.Get(x + 1, y, z)));
            data.AddFaceNormal(Dirs.norm3f[Dirs.EAST]);
            data.faces.Add(new Face {
                pos = (ushort)(x + z * Chunk.SIZE + y * Chunk.SIZE * Chunk.SIZE), dir = Dir.east
            });
        }
        if (!BlockData.RenderSolid(blockData, blocks.Get(x, y + 1, z), Dir.down))
        {
            AddUpFace(x, y, z, ref data);
            AddUVs(x, y, z, ref data, ref blocks, blockData, Dir.up, isLight);
            data.AddFaceColor(LightCalculator.GetColorFromLight(lights.Get(x, y + 1, z)));
            data.AddFaceNormal(Dirs.norm3f[Dirs.UP]);
            data.faces.Add(new Face {
                pos = (ushort)(x + z * Chunk.SIZE + y * Chunk.SIZE * Chunk.SIZE), dir = Dir.up
            });
        }
        if (!BlockData.RenderSolid(blockData, blocks.Get(x, y, z + 1), Dir.south))
        {
            AddNorthFace(x, y, z, ref data);
            AddUVs(x, y, z, ref data, ref blocks, blockData, Dir.north, isLight);
            data.AddFaceColor(LightCalculator.GetColorFromLight(lights.Get(x, y, z + 1)));
            data.AddFaceNormal(Dirs.norm3f[Dirs.NORTH]);
            data.faces.Add(new Face {
                pos = (ushort)(x + z * Chunk.SIZE + y * Chunk.SIZE * Chunk.SIZE), dir = Dir.north
            });
        }
    }