Пример #1
0
    public void SetVoxel(int x, int y, int z, Voxel voxel)
    {
        int idx = x + y * (Width) + z * (Width) * (Height);

        Voxels[idx] = new VoxelNode(voxel);
        //Voxels[idx].SetVoxel(voxel);
    }
Пример #2
0
    public void SetVoxelNode(int x, int y, int z, VoxelNode vox)
    {
        int cx = WorldToChunk(x);
        int cz = WorldToChunk(z);
        int tx = x % World.ChunkSize;
        int tz = z % World.ChunkSize;

        ChunkVoxels[cx, cz].SetVoxelNode(tx, y, tz, vox);

        //Debug.Log(tx + "," + y);
        try
        {
            //  ChunkVoxels[cx, cz].SetVoxelNode(tx, y, tz, vox);
        }catch (System.Exception e)
        {
            Debug.Log(x + "," + y + "," + z);
            Debug.Log(cx + ", " + cz + "," + tx + "," + tz);
        }



        if (tx == 0 && tz == 0 && cx > 0 && cz > 0)
        {
            ChunkVoxels[cx - 1, cz - 1].SetVoxelNode(World.ChunkSize, y, World.ChunkSize, vox);

            ChunkVoxels[cx - 1, cz].SetVoxelNode(World.ChunkSize, y, tz, vox);

            ChunkVoxels[cx, cz - 1].SetVoxelNode(tx, y, World.ChunkSize, vox);
        }
        else if (tx == 0 && cx > 0)
        {
            ChunkVoxels[cx - 1, cz].SetVoxelNode(World.ChunkSize, y, tz, vox);
        }
        else if (tz == 0 && cz > 0)
        {
            ChunkVoxels[cx, cz - 1].SetVoxelNode(tx, y, World.ChunkSize, vox);
        }

        /*
         * if(tx==World.ChunkSize-1 && tz==World.ChunkSize-1 && cx<ChunkSize.x -1 && cz < ChunkSize.z - 1)
         * {
         *  int dChunkHeight = (int)(ChunkBaseHeights[cx, cz] - ChunkBaseHeights[cx + 1, cz + 1]);
         *  ChunkVoxels[cx + 1, cz + 1].SetVoxel(0, Mathf.Clamp(y + dChunkHeight,0,World.ChunkHeight), 0, vox);
         * }else if (tx == World.ChunkSize - 1&& cx < ChunkSize.x - 1  )
         * {
         *  int dChunkHeight = (int)(ChunkBaseHeights[cx, cz] - ChunkBaseHeights[cx + 1, cz]);
         *  ChunkVoxels[cx + 1, cz].SetVoxel(0, Mathf.Clamp(y + dChunkHeight, 0, World.ChunkHeight), tz, vox);
         * }else if ( tz == World.ChunkSize - 1 &&cz < ChunkSize.z - 1)
         * {
         *  int dChunkHeight = (int)(ChunkBaseHeights[cx, cz] - ChunkBaseHeights[cx , cz + 1]);
         *  ChunkVoxels[cx, cz + 1].SetVoxel(tx, Mathf.Clamp(y + dChunkHeight, 0, World.ChunkHeight), 0, vox);
         * }
         *
         */
    }
Пример #3
0
    public static bool ContainsVoxel(this VoxelNode node, Voxel query)
    {
        if (node.Voxel == query)
        {
            return(true);
        }
        if (node.OtherVoxels == null)
        {
            return(false);
        }

        return(node.OtherVoxels.Contains(query));
    }
Пример #4
0
    public void AddVoxel(int x, int y, int z, Voxel voxel)
    {
        int idx = x + y * (Width) + z * (Width) * (Height);

        if (!Voxels[idx].IsNode)
        {
            Voxels[idx] = new VoxelNode(voxel);
        }
        else
        {
            Voxels[idx].AddVoxel(voxel);
        }
    }
Пример #5
0
 public static void AddVoxel(this VoxelNode node, Voxel add)
 {
     if (node.Voxel == add)
     {
         return;
     }
     if (node.OtherVoxels == null)
     {
         node.OtherVoxels = new List <Voxel>();
         node.OtherVoxels.Add(add);
     }
     else if (!node.OtherVoxels.Contains(add))
     {
         node.OtherVoxels.Add(add);
     }
 }
Пример #6
0
    void addTriangle(VoxelNode a, VoxelNode b, VoxelNode c)
    {
        if (_vertices.Count > 64990)
        {
            nextChildMesh();
        }
        if (smooth_normal)
        {
            //a
            if (!_voxelPointIndexTable.ContainsKey(a))
            {
                _voxelPointIndexTable.Add(a, _vertices.Count);
                addVertex(a);
            }

            //b
            if (!_voxelPointIndexTable.ContainsKey(b))
            {
                _voxelPointIndexTable.Add(b, _vertices.Count);
                addVertex(b);
            }

            //c
            if (!_voxelPointIndexTable.ContainsKey(c))
            {
                _voxelPointIndexTable.Add(c, _vertices.Count);
                addVertex(c);
            }
            _triangles.Add(_voxelPointIndexTable [a]);
            _triangles.Add(_voxelPointIndexTable [b]);
            _triangles.Add(_voxelPointIndexTable [c]);
        }
        else
        {
            _triangles.Add(_vertices.Count);
            addVertex(a);

            _triangles.Add(_vertices.Count);
            addVertex(b);

            _triangles.Add(_vertices.Count);
            addVertex(c);
        }
    }
Пример #7
0
    public void AddBuilding(Building b, BuildingVoxels vox, Vec2i pos)
    {
        float minHeight = 0;

        //SetTiles(pos.x, pos.z, b.Width, b.Height, b.BuildingTiles);
        for (int x = 0; x < b.Width; x++)
        {
            for (int z = 0; z < b.Height; z++)
            {
                int cx = WorldToChunk(x);
                int cz = WorldToChunk(z);

                int deltaHeight = ChunkBases != null ? (int)(minHeight - ChunkBases[cx, cz].Height) : 0;

                SetTile(x + pos.x, z + pos.z, b.BuildingTiles[x, z]);
                SetHeight(x + pos.x, z + pos.z, minHeight);



                for (int y = 0; y < vox.Height; y++)
                {
                    VoxelNode voxNode = vox.GetVoxelNode(x, y, z);
                    if (voxNode.IsNode)
                    {
                        //Debug.Log("Adding vox node: " + voxNode);
                        SetVoxelNode(x + pos.x, y, z + pos.z, vox.GetVoxelNode(x, y, z));
                    }
                }
            }
        }
        foreach (WorldObjectData obj in b.GetBuildingExternalObjects())
        {
            obj.SetPosition(obj.Position + pos.AsVector3());
            //We (should) already have checked for object validity when creating the building
            AddObject(obj, true);
        }
    }
Пример #8
0
    /// <summary>
    ///
    /// </summary>
    /// <param name="genRan">The RNG used for this building</param>
    /// <param name="obj">The object to place in the building</param>
    /// <param name="height">The height above the ground the object should sit</param>
    /// <param name="vox">The voxel data of this building. Only required if 'requireWallBacking' is true</param>
    /// <param name="build">The building to place the object in</param>
    /// <param name="distFromWall">The distance from a wall the object should be placed</param>
    /// <param name="wallIndex">Defines the wall we should attempt to place this object on. The 'i'th wall defines the wall
    /// connecting build.BoundingWall[i] -> build.BoundingWall[i+1]. If left as default value (-1), an index will be randomly generated</param>
    /// <param name="requireWallBacking">If true, then we will search for a point on the wall that is backed against a wall.
    /// Used to stop certain objects being placed in front of windows</param>
    /// <param name="forcePlace">If true, then we do not check for intersection with other objects in the building</param>
    /// <param name="attemptsCount">The number of attempts made to place the object on this wall</param>
    /// <returns>True if object is placed sucesfully, false otherwise</returns>
    public static bool PlaceObjectAgainstWall(GenerationRandom genRan, WorldObjectData obj, float height,
                                              BuildingVoxels vox, Building build, float distFromWall = 0, bool requireWallBacking = false, int distToEntr = 2,
                                              bool forcePlace = false, int attemptsCount = 5)
    {
        if (build.InsideWallPoints == null)
        {
            build.InsideWallPoints = FindInsideWallBoundryPoints(vox, build);
        }

        //Check attempts count
        attemptsCount--;
        if (attemptsCount == 0)
        {
            return(false);
        }

        float wallDisp = genRan.Random();
        //Define the position as the start pos + lambda*dir
        //Select a random position from all wall points
        Vec2i pos = genRan.RandomFromArray(build.InsideWallPoints);

        //If too close to entrance, try another placement
        if (build.Entrance != null && pos.QuickDistance(build.Entrance) < distToEntr * distToEntr)
        {
            return(PlaceObjectAgainstWall(genRan, obj, height, vox, build, distFromWall, requireWallBacking, distToEntr, forcePlace, attemptsCount));
        }
        //If the object is too close to any of the corners, try again
        foreach (Vec2i v in build.BoundingWall)
        {
            if (v.QuickDistance(pos) < 2)
            {
                return(PlaceObjectAgainstWall(genRan, obj, height, vox, build, distFromWall, requireWallBacking, distToEntr, forcePlace, attemptsCount));
            }
        }

        Vec2i faceDirection = GetWallPointDirection(build, pos);

        //If we require a backing wall, we check the position
        if (requireWallBacking)
        {
            Vec2i wPos = pos - faceDirection;
            for (int y = 0; y < 4; y++)
            {
                VoxelNode vn = vox.GetVoxelNode(wPos.x, y, wPos.z);
                //If there is no node (nothing set) then this position is not valid
                if (!vn.IsNode)
                {
                    return(PlaceObjectAgainstWall(genRan, obj, height, vox, build, distFromWall, requireWallBacking, distToEntr, forcePlace, attemptsCount));
                }
                if (vn.Voxel == Voxel.glass || vn.Voxel == Voxel.none)
                {
                    return(PlaceObjectAgainstWall(genRan, obj, height, vox, build, distFromWall, requireWallBacking, distToEntr, forcePlace, attemptsCount));
                }
            }
        }
        Vector3 finPos   = pos.AsVector3() + faceDirection.AsVector3() * distFromWall + Vector3.up * height;
        float   rotation = Vec2i.Angle(Vec2i.Forward, faceDirection);

        obj.SetPosition(finPos).SetRotation(rotation);
        if (!forcePlace)
        {
            foreach (WorldObjectData obj_ in build.GetBuildingExternalObjects())
            {
                if (obj.Intersects(obj_))
                {
                    return(PlaceObjectAgainstWall(genRan, obj, height, vox, build, distFromWall, requireWallBacking, distToEntr, forcePlace, attemptsCount));
                }
            }
        }


        //obj.SetPosition(finPos);
        build.AddInternalObject(obj);
        return(true);
    }
Пример #9
0
 public static void ClearVoxel(this VoxelNode node)
 {
     node.OtherVoxels.Clear();
     node.Voxel = Voxel.none;
 }
Пример #10
0
    public static void SetVoxel(this VoxelNode node, Voxel set)
    {
        node.Voxel = set;

        // Debug.Log("setting voxel: " + set);
    }
Пример #11
0
    /// <summary>
    /// Creates a pre loaded chunk from chunk data.
    /// This entire function is run in a thread
    /// </summary>
    /// <param name="cData"></param>
    /// <returns></returns>
    private PreLoadedChunk GeneratePreLoadedChunk(ChunkData chunk, int lod = 1)
    {
        //We create a thread safe mesh for the terrain
        // PreMesh terrainMesh = GenerateMarchingCubesTerrain(chunk);
        ChunkData[] neighbors = ChunkRegionManager.GetNeighbors(new Vec2i(chunk.X, chunk.Z));

        PreMesh terrainMesh = GenerateSmoothTerrain(chunk, neighbors, lod);

        terrainMesh.RecalculateNormals();
        Debug.Log("[ChunkLoader] Terrain mesh for " + chunk + " created - " + CurrentVerticies.Count + " verticies", Debug.CHUNK_LOADING);
        //Create the base pre-loaded chunk
        PreLoadedChunk preChunk = new PreLoadedChunk(new Vec2i(chunk.X, chunk.Z), terrainMesh, chunk);

        //if we have no voxel data, return just the terrain map
        if (chunk.VoxelData == null)
        {
            return(preChunk);
        }


        int maxHeight = 0;

        if (neighbors != null)
        {
            foreach (ChunkData cd in neighbors)
            {
                if (cd != null && cd.VoxelData != null)
                {
                    if (maxHeight < cd.VoxelData.TotalHeight())
                    {
                        maxHeight = cd.VoxelData.TotalHeight();
                    }
                }
            }
        }



        //If the chunk hasn't had its boundry points defined, we do it now
        if (!chunk.VoxelData.HasBoundryVoxels)
        {
            for (int y = 0; y < maxHeight; y++)
            {
                for (int i = 0; i < World.ChunkSize; i++)
                {
                    if (neighbors[0] != null && neighbors[0].VoxelData != null)
                    {
                        VoxelNode node = neighbors[0].VoxelData.GetVoxelNode(i, y, 0);
                        if (node.IsNode)
                        {
                            chunk.VoxelData.SetVoxelNode(i, y, World.ChunkSize, node);
                        }
                    }
                    if (neighbors[2] != null && neighbors[2].VoxelData != null)
                    {
                        VoxelNode node = neighbors[2].VoxelData.GetVoxelNode(0, y, i);
                        if (node.IsNode)
                        {
                            chunk.VoxelData.SetVoxelNode(World.ChunkSize, y, i, node);
                        }
                    }
                }
                if (neighbors[1] != null && neighbors[1].VoxelData != null)
                {
                    VoxelNode node = neighbors[1].VoxelData.GetVoxelNode(0, y, 0);
                    if (node.IsNode)
                    {
                        chunk.VoxelData.SetVoxelNode(World.ChunkSize, y, World.ChunkSize, node);
                    }
                }
            }
            chunk.VoxelData.HasBoundryVoxels = true;
        }

        //Next we generate all relevent voxel meshes
        foreach (Voxel v in MiscUtils.GetValues <Voxel>())
        {
            if (v == Voxel.none)
            {
                continue;
            }
            //If the chunk has this type of voxel in it
            if (chunk.VoxelData.VoxelTypeBounds.TryGetValue(v, out VoxelBounds vb))
            {
                //Clear all lists to prepair
                CurrentVerticies.Clear();
                CurrentTriangles.Clear();
                CurrentColours.Clear();
                CurrentUVs.Clear();
                //Generate the voxel mesh
                //MarchingCubes.Generate(chunk.VoxelData.Voxels, vb, v, World.ChunkSize+1, World.ChunkHeight+1, World.ChunkSize+1, CurrentVerticies, CurrentTriangles);
                //MarchingCubes.Generate(chunk.VoxelData.Voxels, vb, v, World.ChunkSize + 1, chunk.VoxelData.TotalHeight(), World.ChunkSize + 1, CurrentVerticies, CurrentTriangles);
                //MarchingCubes.Generate(chunk.VoxelData.AllVoxels, vb, v, World.ChunkSize + 1, chunk.VoxelData.TotalHeight(), World.ChunkSize + 1, CurrentVerticies, CurrentTriangles);

                MarchingCubes.Generate(chunk.VoxelData.AllVoxels, vb, v, World.ChunkSize + 1, chunk.VoxelData.TotalHeight(), World.ChunkSize + 1, CurrentVerticies, CurrentTriangles);


                PreMesh voxelMesh = new PreMesh();
                voxelMesh.Verticies = CurrentVerticies.ToArray();
                voxelMesh.Triangles = CurrentTriangles.ToArray();
                voxelMesh.UV        = CreateUV(voxelMesh);
                voxelMesh.RecalculateNormals();
                //Add it the the pre loaded chunk
                preChunk.VoxelMesh.Add(v, voxelMesh);
            }
        }

        /*
         * if(chunk.WorldObjects != null)
         * {
         *
         *  lock (ObjectsToLoadLock)
         *  {
         *      Debug.Log("[ChunkLoader] Chunk " + chunk.X + "," + chunk.Z + " has " + chunk.WorldObjects.Count + " objects to load", Debug.CHUNK_LOADING);
         *      ObjectsToLoad.AddRange(chunk.WorldObjects);
         *  }
         *
         * }*/



        return(preChunk);
    }
Пример #12
0
 public virtual void UpdateNeighbours(VoxelNode octreeNode)
 {
 }
Пример #13
0
 void addVertex(VoxelNode node)
 {
     _vertices.Add(node.toVector());
     _uvs.Add(node.toUV(_voxels.GetLength(0), _voxels.GetLength(2)));
 }
Пример #14
0
    public void ClearVoxel(int x, int y, int z)
    {
        int idx = x + y * (Width) + z * (Width) * (Height);

        Voxels[idx] = new VoxelNode(Voxel.none);
    }