public void AddQuadFlipped(Vector3 p0, Vector3 p1, Vector3 p2, Vector3 p3, Vector3 normal)
    {
        int v0 = AddVert(VoxelWorld.TransformPoint(p0));
        int v1 = AddVert(VoxelWorld.TransformPoint(p1));
        int v2 = AddVert(VoxelWorld.TransformPoint(p2));
        int v3 = AddVert(VoxelWorld.TransformPoint(p3));

        faces.Add(v2);
        faces.Add(v1);
        faces.Add(v0);

        faces.Add(v3);
        faces.Add(v2);
        faces.Add(v0);

        uvs.Add(new Vector2(0, 0));
        uvs.Add(new Vector2(0, 1));
        uvs.Add(new Vector2(1, 1));
        uvs.Add(new Vector2(1, 0));

        normals.Add(normal);
        normals.Add(normal);
        normals.Add(normal);
        normals.Add(normal);

        colors.Add(drawingColor);
        colors.Add(drawingColor);
        colors.Add(drawingColor);
        colors.Add(drawingColor);
    }
        // Initialization
        private void Initialize()
        {
            VoxelWorld = new VoxelWorld(4582);

            UpdateJobs    = new BlockingCollection <ChunkUpdateJob>(new ConcurrentStack <ChunkUpdateJob>());
            _meshResults  = new ConcurrentStack <ChunkMeshResult>();
            _lightResults = new ConcurrentStack <ChunkLightResult>();

            // Initialize the voxel dictionary
            VoxelDictionary.InitializeVoxelDictionary();

            // Instantiate a new runtime texture atlas
            AtlasGenerator = new RuntimeTextureAtlas();

            // Instantiate mesh workers proportional to system thread count
            var workerCount = Environment.ProcessorCount > 4 ? Environment.ProcessorCount - 2 : 2;

            _meshExtractors = new ChunkUpdateWorker[workerCount];
            for (var i = 0; i < _meshExtractors.Length; i++)
            {
                _meshExtractors[i] = new ChunkUpdateWorker(UpdateJobs, _meshResults);
            }

            // Start the chunk generation routine
            StartCoroutine(nameof(GenerateChunks));
        }
Beispiel #3
0
    public void Start()
    {
        Inst = this;

        VoxelWidth = ChunksWide * ChunkVoxelSize;
        VoxelHeight = ChunksHigh * ChunkVoxelSize;
        VoxelDepth = ChunksDeep * ChunkVoxelSize;

        VoxelTypeDefs = new Dictionary<VoxelType, VoxelTypeDefinition>();
        VoxelTypeDefs[VoxelType.Air] = VoxelTypeDefAir;
        VoxelTypeDefs[VoxelType.Grass] = VoxelTypeDefGrass;
        VoxelTypeDefs[VoxelType.Dirt] = VoxelTypeDefDirt;
        VoxelTypeDefs[VoxelType.Stone] = VoxelTypeDefStone;
        VoxelTypeDefs[VoxelType.Bedrock] = VoxelTypeDefBedRk;

        VoxelTypeDefs.Values.ToList().ForEach(def => def.RecalcUVSet());

        InstantiateChunks();

        GenerateWorldVoxels(GenerateVoxel_Pass1);
        GenerateWorldVoxels(GenerateVoxel_Pass2);

        Initialized = true;

        Refresh();
    }
Beispiel #4
0
    public void Start()
    {
        Inst = this;

        VoxelWidth  = ChunksWide * ChunkVoxelSize;
        VoxelHeight = ChunksHigh * ChunkVoxelSize;
        VoxelDepth  = ChunksDeep * ChunkVoxelSize;

        VoxelTypeDefs = new Dictionary <VoxelType, VoxelTypeDefinition>();
        VoxelTypeDefs[VoxelType.Air]     = VoxelTypeDefAir;
        VoxelTypeDefs[VoxelType.Grass]   = VoxelTypeDefGrass;
        VoxelTypeDefs[VoxelType.Dirt]    = VoxelTypeDefDirt;
        VoxelTypeDefs[VoxelType.Stone]   = VoxelTypeDefStone;
        VoxelTypeDefs[VoxelType.Bedrock] = VoxelTypeDefBedRk;

        VoxelTypeDefs.Values.ToList().ForEach(def => def.RecalcUVSet());

        InstantiateChunks();

        GenerateWorldVoxels(GenerateVoxel_Pass1);
        GenerateWorldVoxels(GenerateVoxel_Pass2);

        Initialized = true;

        Refresh();
    }
Beispiel #5
0
 public ChunkRegionSystem(VoxelWorld voxelWorld) : base(voxelWorld)
 {
     _VoxelWorld            = voxelWorld;
     _ChunksRequiringRemesh = new Queue <Chunk>();
     _ChunksPendingDisposal = new Stack <Chunk>();
     _LoadableChunks        = new HashSet <Vector3i>();
 }
Beispiel #6
0
        /// <summary>
        /// Creates a new chunk of voxels.
        /// </summary>
        public Chunk(VoxelWorld world, Vector2Int position)
        {
            // Set world reference
            _world = world;

            // Set position
            Position      = position;
            WorldPosition = position * CHUNK_LENGTH;


            _biomeMap  = new int[CHUNK_LENGTH, CHUNK_LENGTH];
            _heightMap = new int[CHUNK_LENGTH * CHUNK_LENGTH];

            // Initialize voxel data array
            _voxels = new Voxel[CHUNK_LENGTH * CHUNK_HEIGHT * CHUNK_LENGTH];

            // Initialize light map and BFS queues
            _lightMap    = new byte[CHUNK_LENGTH * CHUNK_HEIGHT * CHUNK_LENGTH];
            LightSources = new Dictionary <Vector3Int, int>();

            // Initialize voxel edit queue
            _voxelEdits = new ConcurrentQueue <VoxelUpdate>();

            for (var i = 0; i < _voxels.Length; i++)
            {
                _voxels[i] = new Voxel(0);
            }
        }
Beispiel #7
0
 private void LoadChunk(VoxelWorld _voxel_world, intVector3 _position)
 {
     if (_voxel_world.GetChunk(_position.x, _position.y, _position.z) == null)
     {
         _voxel_world.CreateChunk(_position.x, _position.y, _position.z);
     }
 }
Beispiel #8
0
 public override void _Ready()
 {
     tree        = GetTree();
     crosshair   = GetNode <CenterContainer>("Crosshair");
     pause       = GetNode <Control>("Pause");
     options     = GetNode <Options>("Options");
     voxel_world = GetNode <VoxelWorld>("../VoxelWorld");
 }
 public ChunkUpdateJob(int id, VoxelWorld world, Chunk chunk, Action <ChunkMeshResult> meshCallback, Action <ChunkLightResult> lightCallback)
 {
     Id            = id;
     World         = world;
     Chunk         = chunk;
     MeshCallback  = meshCallback;
     LightCallback = lightCallback;
 }
 private void OnEnable()
 {
     world = target as VoxelWorld;
     if (Application.isPlaying == false)
     {
         world.VariablesCheck();
     }
 }
Beispiel #11
0
    protected override void OnInit(Parameters parameters)
    {
        random         = Entity.Simulation.GetComponentManager <DeterministicRandom>();
        voxelComponent = Entity.GetComponent <VoxelComponent>();
        voxelWorld     = voxelComponent.World;

        SelectTarget();
    }
Beispiel #12
0
    private void ReuseChunk(VoxelWorld _voxel_world, intVector3 _position)
    {
        if (_voxel_world.GetChunk(_position.x, _position.y, _position.z) != null)
        {
            return;
        }

        _voxel_world.ReuseChunk(GetChunkFromPool(), _position);//reuse chunk if available
    }
Beispiel #13
0
			internal override void InitFaceCullData( VoxelSector Sector )
			{
				Sector.Culler = this;
				this.world = Sector.world;
				FaceCulling = new byte[Sector.DataSize];
				int n;
				for( n = 0; n < Sector.DataSize; n++ )
					FaceCulling[n] = 0xFF;
			}
Beispiel #14
0
        public FlatGenerator(VoxelWorld world, SimplexNoise noise) : base(world, noise)
        {
            stone       = ResourceStore.Blocks["stone"];
            dirt        = ResourceStore.Blocks["dirt"];
            grass       = ResourceStore.Blocks["grass"];
            grass_decal = ResourceStore.Blocks["grass_decal"];

            ores = GetBlocksOfType(BlockSpawnType.Ore);
        }
Beispiel #15
0
 void EnableAllChunks(VoxelWorld voxelWorld)
 {
     for (int x = 0; x <= startingSize.x; x++)
     {
         for (int z = 0; z <= startingSize.y; z++)
         {
             world.GetChunk(new Vector2Int(x - startingSize.x / 2, z - startingSize.y / 2)).gameObject.SetActive(true);
         }
     }
 }
    private void Awake()
    {
        if (singleton != null)
        {
            Destroy(gameObject);
            return;
        }

        singleton = this;
    }
Beispiel #17
0
    Container crosshair;     // CenterContainer

    public override void _Ready()
    {
        gravity = (float)ProjectSettings.GetSetting("physics/3d/default_gravity");
        head    = GetNode <Spatial>("Head");
        raycast = GetNode <RayCast>("Head/RayCast");
        selected_block_texture = GetNode <TextureRect>("SelectedBlock");
        voxel_world            = GetNode <VoxelWorld>("../VoxelWorld");
        crosshair = GetNode <Container>("../PauseMenu/Crosshair");
        Input.SetMouseMode(Input.MouseMode.Captured);
    }
Beispiel #18
0
 public ClassicGenerator(VoxelWorld world, SimplexNoise noise) : base(world, noise)
 {
     stone       = GetBlockData("stone");
     dirt        = GetBlockData("dirt");
     grass       = GetBlockData("grass");
     grass_decal = GetBlockData("grass_decal");
     water       = GetBlockData("water");
     sand        = GetBlockData("sand");
     iron_ore    = GetBlockData("iron_ore");
 }
Beispiel #19
0
        void OnWizardCreate()
        {
            shapes[selected].CalculateDensity();
            GameObject terrain = new GameObject("Terrain");

            terrain.transform.position = Vector3.zero;
            VoxelWorld vw = terrain.AddComponent <VoxelWorld>();

            vw.CreateWorld(shapes[selected].worldWidth, shapes[selected].worldLength, shapes[selected].worldHeight,
                           shapes[selected].chunkSize, shapes[selected].isolevel, shapes[selected].mat, shapes[selected].density);
        }
Beispiel #20
0
        /// <summary>
        /// Initializes the chunk and generates the mesh.
        /// </summary>
        /// <param name="coordinate">The coordinate of this chunk</param>
        /// <param name="voxelWorld">The world that "owns" this chunk</param>
        public void Initialize(int3 coordinate, VoxelWorld voxelWorld)
        {
            _voxelWorld = voxelWorld;

            transform.position = coordinate.ToVectorInt() * voxelWorld.WorldSettings.ChunkSize;
            name = GetName(coordinate);

            ChunkCoordinate = coordinate;

            GenerateMesh();
        }
Beispiel #21
0
        public ProceduralGenerator(VoxelWorld world)
        {
            this.world = world;
            noise      = new SimplexNoise(world.seed);
            generators = new Dictionary <GeneratorType, Generator>();

            generators.Add(GeneratorType.Classic, new ClassicGenerator(world, noise));
            generators.Add(GeneratorType.Flat, new FlatGenerator(world, noise));
            generators.Add(GeneratorType.Noise, new NoiseGenerator(world, noise));
            generators.Add(GeneratorType.Test, new TestGenerator(world, noise));
        }
Beispiel #22
0
        /// Create this chunk and put it in the pool
        public void Create(VoxelWorld world)
        {
            this.world = world;

            chunks = new ChunkSection[VoxelWorld.ChunkHeight];
            for (int i = 0; i < chunks.Length; i++)
            {
                chunks[i] = Instantiate(chunkFab).GetComponent <ChunkSection>();
                chunks[i].Create(this, world);
            }
        }
Beispiel #23
0
    private void Update()
    {
        current_world_position = VoxelWorld.PositionToWorldPosition(transform.position);

        if (multithreading)
        {
            ThreadedUpdate();
            return;
        }

        RegularUpdate();
    }
Beispiel #24
0
        public VoxelChunk GenerateChunk(VoxelChunk chunk, VoxelWorld world)
        {
            var chunkPos = chunk.WorldPosition * VoxelWorld.Configuration.ChunkSegmentSize;

            for (int x = 0; x < VoxelWorld.Configuration.ChunkSegmentSize; x++)
            {
                for (int z = 0; z < VoxelWorld.Configuration.ChunkSegmentSize; z++)
                {
                    var worldPos = chunkPos + new Int2(x, z);

                    var turbX = TurbX.GetValue(worldPos.X / 48f, worldPos.Y / 48f) * 12f;
                    var turbY = TurbY.GetValue(worldPos.X / 48f, worldPos.Y / 48f) * 12f;

                    var worldPosTurb = new Vector2(worldPos.X + turbX, worldPos.Y + turbY);

                    var alt_base  = GetInterpolated(worldPos, (cb) => cb.AltBase);
                    var chaos     = GetInterpolated(worldPos, (cb) => cb.Chaos);
                    var temp      = GetInterpolated(worldPos, (cb) => cb.Temp);
                    var humidity  = GetInterpolated(worldPos, (cb) => cb.Humidity);
                    var rockiness = GetInterpolated(worldPos, (cb) => cb.Rockiness);

                    var river = 0;

                    var riverless_alt = GetInterpolated(worldPos, (cb) => cb.Alt) +
                                        Mathf.Abs(Small.GetValue(worldPosTurb.X / 150f, worldPosTurb.Y / 150f)) *
                                        Mathf.Max(chaos, 0.025f) * 64f +
                                        Mathf.Abs(Small.GetValue(worldPosTurb.X / 450f, worldPosTurb.Y / 450f)) *
                                        (1f - chaos) * (1f - humidity) * 94f;

                    var chunkBase = GetChunkBase(worldPos);

                    var is_cliffs   = chunkBase.IsCliffs;
                    var near_cliffs = chunkBase.NearCliffs;

                    var alt = riverless_alt - (Mathf.Cos((1 - river) * Mathf.Pi) + 1) * 0.5f * 24f;
                    while (alt > 0)
                    {
                        alt--;
                        chunk.SetBlock(x, (int)alt, z, new Block {
                            Color = Color32.White, IsTransparent = false, Id = 0
                        }, false, false);
                    }
                }
            }

            world.UpdateQueue.Enqueue(new ReMeshChunk(chunk));
            world.UpdateQueue.Enqueue(new ReMeshChunk(chunkPos + new Int2(0, -1)));
            world.UpdateQueue.Enqueue(new ReMeshChunk(chunkPos + new Int2(0, 1)));
            world.UpdateQueue.Enqueue(new ReMeshChunk(chunkPos + new Int2(-1, 0)));
            world.UpdateQueue.Enqueue(new ReMeshChunk(chunkPos + new Int2(1, 0)));
            return(chunk);
        }
Beispiel #25
0
 void Start()
 {
     world = GameObject.Instantiate(VoxelWorld.prefab);
     world.gameController = this;
     for (int x = 0; x <= startingSize.x; x++)
     {
         for (int z = 0; z <= startingSize.y; z++)
         {
             // Subtract half of starting size to make the world centered over origin
             world.CreateChunk(new Vector2Int(x - startingSize.x / 2, z - startingSize.y / 2));
         }
     }
     StartCoroutine(GenerateIteratively(world));
 }
Beispiel #26
0
 IEnumerator GenerateIteratively(VoxelWorld world)
 {
     for (int x = 0; x <= startingSize.x; x++)
     {
         for (int z = 0; z <= startingSize.y; z++)
         {
             // Subtract half of starting size to make the world centered over origin
             world.GetChunk(new Vector2Int(x - startingSize.x / 2, z - startingSize.y / 2)).Draw();
             yield return(null);
         }
     }
     playerTransform = Instantiate(playerPrefab, Vector3.up * 100f, Quaternion.identity).transform;
     loading         = false;
 }
Beispiel #27
0
    public static Chunk CreateChunk(Vector2Int position, VoxelWorld world)
    {
        Chunk newChunk = GameObject.Instantiate(prefab);

        newChunk.position = position;
        newChunk.world    = world;
        Vector3 location = new Vector3(position.x, 0f, position.y);

        location.x *= size.x * 2f;
        location.y *= size.y * 2f;
        location.z *= size.z * 2f;
        newChunk.transform.position = location;
        newChunk.transform.parent   = world.transform;
        return(newChunk);
    }
Beispiel #28
0
    void Start()
    {
        // Create a new world and determine the chunk the player is in
        world = new VoxelWorld(chunkPrefab);

        currentChunkX = Mathf.FloorToInt(player.position.x / 16);
        currentChunkZ = Mathf.FloorToInt(player.position.z / 16);

        currentChunkId = currentChunkX + "." + currentChunkZ;
        lastChunkId    = currentChunkId;

        //world.PerformWorldUpdateAccordingToPlayerPosition(currentChunkId);
        // Create and update the meshes around the player
        world.LoadChunksAccordingToPlayerPosition(currentChunkId);
        world.UpdateAllMeshes();
    }
Beispiel #29
0
        void Update()
        {
            world = WorldManager.ActiveWorld;

            if (controller.locked && (Input.GetMouseButtonDown(0) || Input.GetMouseButtonDown(1)))
            {
                RaycastHit hit;
                Ray        ray = new Ray(transform.position, transform.forward);
                if (Physics.Raycast(ray, out hit, 10f))
                {
                    if (hit.transform.CompareTag("Chunk"))
                    {
                        if (!Input.GetKey(KeyCode.LeftAlt) && !Input.GetMouseButtonDown(1))
                        {
                            Block placed;
                            var   chunk = world.PlaceBlock(hit, selected, out placed, false);
                            chunk.blocks.GetCustomBlock <RotatedBlock>(placed, b => b.SetRotation(rotation), true);
                        }
                        else
                        {
                            world.PlaceBlock(hit, null, true);
                        }
                    }
                }
            }

            if (Input.GetKeyDown(KeyCode.E))
            {
                if (!controller.locked)
                {
                    controller.Lock();
                    blockList.Disable();
                }
                else
                {
                    controller.Unlock();
                    blockList.Enable();
                }
            }

            if (Input.GetKeyDown(KeyCode.Escape))
            {
                UnityEngine.SceneManagement.SceneManager.LoadScene(0);
            }
        }
Beispiel #30
0
 void Cull(Transform playerTransform, VoxelWorld voxelWorld)
 {
     for (int x = 0; x <= startingSize.x; x++)
     {
         for (int z = 0; z <= startingSize.y; z++)
         {
             // Subtract half of starting size to make the world centered over origin
             Chunk chunk = world.GetChunk(new Vector2Int(x - startingSize.x / 2, z - startingSize.y / 2));
             if (getVisible(playerTransform, chunk))
             {
                 chunk.gameObject.SetActive(true);
             }
             else
             {
                 chunk.gameObject.SetActive(false);
             }
         }
     }
 }
    protected override unsafe void OnUpdate()
    {
        if (!IsInitialized)
        {
            VoxelWorld = GetSingleton <VoxelWorld>();
            ChunkMap   = new NativeArray2D <Entity>(VoxelWorld.ChunkSize.x, VoxelWorld.ChunkSize.z, Allocator.Persistent);

            if (!EntityManager.Exists(VoxelWorld.Entity))
            {
                throw new InvalidOperationException();
            }

            for (int x = 0; x < VoxelWorld.MaxChunks; x++)
            {
                for (int z = 0; z < VoxelWorld.MaxChunks; z++)
                {
                    var entity = EntityManager.Instantiate(VoxelWorld.ChunkPrefab);
                    var chunk  = EntityManager.GetComponentData <VoxelChunk>(entity);
                    chunk.NeedsUpdate      = 1;
                    chunk.Entity           = entity;
                    chunk.VoxelWorldEntity = VoxelWorld.Entity;

                    chunk.X = x;
                    chunk.Z = z;

                    EntityManager.SetComponentData(entity, chunk);
                    ChunkMap[x, z] = entity;
                }
            }

            //Entities.ForEach((Entity e, ref VoxelChunk chunk) =>
            //{

            //});

            IsInitialized = true;
        }
    }
    public override void _Ready()
    {
        voxel_world = GetParent() as VoxelWorld;
        var t = GlobalTransform;

        t.origin        = chunk_position * CHUNK_SIZE;
        GlobalTransform = t;
        Name            = chunk_position.ToString();

        if (Settings.world_type == 0)
        {
            data = TerrainGenerator.random_blocks();
        }
        else
        {
            data = TerrainGenerator.flat(chunk_position);
        }
        // We can only add colliders in the main thread due to physics limitations.
        _generate_chunk_collider();

        // However, we can use a thread for mesh generation.
        _thread = new Godot.Thread();
        _thread.Start(this, "_generate_chunk_mesh");
    }
Beispiel #33
0
		internal static void SectorUpdateFaceCulling( VoxelWorld world, VoxelSector Sector, bool Isolated )
		{
			VoxelType[] VoxelTypeTable;
			VoxelSector MissingSector;

			ushort[] tmpp;
			int i;

			if( Isolated ) MissingSector = VoxelWorld.WorkingEmptySector;
			else MissingSector = VoxelWorld.WorkingFullSector;

			// (VoxelSector.FACEDRAW_Operations.ABOVE | VoxelSector.FACEDRAW_Operations.BELOW | VoxelSector.FACEDRAW_Operations.LEFT | VoxelSector.FACEDRAW_Operations.RIGHT | VoxelSector.FACEDRAW_Operations.AHEAD | VoxelSector.FACEDRAW_Operations.BEHIND);
			for( i = 0; i < 27; i++ ) SectorTable[i] = MissingSector;
			SectorTable[0] = Sector; if( SectorTable[0] == null ) { return; }
			SectorTable[1] = Sector.near_sectors[(int)VoxelSector.RelativeVoxelOrds.LEFT - 1]; if( SectorTable[1] == null ) { SectorTable[1] = MissingSector; SectorTable[0].PartialCulling |= VoxelSector.FACEDRAW_Operations.LEFT; }
			SectorTable[2] = Sector.near_sectors[(int)VoxelSector.RelativeVoxelOrds.RIGHT - 1]; if( SectorTable[2] == null ) { SectorTable[2] = MissingSector; SectorTable[0].PartialCulling |= VoxelSector.FACEDRAW_Operations.RIGHT; }
			SectorTable[3] = Sector.near_sectors[(int)VoxelSector.RelativeVoxelOrds.BEHIND - 1]; if( SectorTable[3] == null ) { SectorTable[3] = MissingSector; SectorTable[0].PartialCulling |= VoxelSector.FACEDRAW_Operations.BEHIND; }
			SectorTable[6] = Sector.near_sectors[(int)VoxelSector.RelativeVoxelOrds.AHEAD - 1]; if( SectorTable[6] == null ) { SectorTable[6] = MissingSector; SectorTable[0].PartialCulling |= VoxelSector.FACEDRAW_Operations.AHEAD; }
			SectorTable[9] = Sector.near_sectors[(int)VoxelSector.RelativeVoxelOrds.BELOW - 1]; if( SectorTable[9] == null ) { SectorTable[9] = MissingSector; SectorTable[0].PartialCulling |= VoxelSector.FACEDRAW_Operations.BELOW; }
			SectorTable[18] = Sector.near_sectors[(int)VoxelSector.RelativeVoxelOrds.ABOVE - 1]; if( SectorTable[18] == null ) { SectorTable[18] = MissingSector; SectorTable[0].PartialCulling |= VoxelSector.FACEDRAW_Operations.ABOVE; }
			for( i = 0; i < 27; i++ ) SectorDataTable[i] = SectorTable[i].Data.Data;


			int xc, yc, zc;
			int xp, yp, zp;
			int xpp, ypp, zpp;
			VoxelSector.FACEDRAW_Operations info;
				int MainVoxelDrawInfo;

			//SectorTable[0].Flag_Void_Regular = true;
			//SectorTable[0].Flag_Void_Transparent = true;
			VoxelTypeTable = world.VoxelTypeManager.VoxelTable;

			for( xc = 0; xc < VoxelSector.ZVOXELBLOCSIZE_X; xc++ )
			{
				xp = xc + 1; xpp = xc + 2;
				for( zc = 0; zc < VoxelSector.ZVOXELBLOCSIZE_Z; zc++ )
				{
					byte[] STableX = VoxelSector.STableX;
					byte[] STableY = VoxelSector.STableY;
					byte[] STableZ = VoxelSector.STableZ;
					ushort[] OfTableX = VoxelSector.OfTableX;
					ushort[] OfTableY = VoxelSector.OfTableY;
					ushort[] OfTableZ = VoxelSector.OfTableZ;
					zp = zc + 1; zpp = zc + 2;

					// Prefetching the bloc matrix (only 2 rows)
					//    BlocMatrix[1][0] = SectorDataTable[(VoxelSector.STableX[xc ]+STableY[0]+STableZ[zc ])][OfTableX[xc]+OfTableY[0]+OfTableZ[zc]];
					BlocMatrix[1][1] = SectorDataTable[( STableX[xp] + STableY[0] + STableZ[zc] )][OfTableX[xp] + OfTableY[0] + OfTableZ[zc]];
					//    BlocMatrix[1][2] = SectorDataTable[(STableX[xpp]+STableY[0]+STableZ[zc ])][OfTableX[xpp]+OfTableY[0]+OfTableZ[zc ]]
					BlocMatrix[1][3] = SectorDataTable[( STableX[xc] + STableY[0] + STableZ[zp] )][OfTableX[xc] + OfTableY[0] + OfTableZ[zp]];
					BlocMatrix[1][4] = SectorDataTable[( STableX[xp] + STableY[0] + STableZ[zp] )][OfTableX[xp] + OfTableY[0] + OfTableZ[zp]];
					BlocMatrix[1][5] = SectorDataTable[( STableX[xpp] + STableY[0] + STableZ[zp] )][OfTableX[xpp] + OfTableY[0] + OfTableZ[zp]];
					//    BlocMatrix[1][6] = SectorDataTable[(STableX[xc ]+STableY[0]+STableZ[zpp])][OfTableX[xc ]+OfTableY[0]+OfTableZ[zpp]]
					BlocMatrix[1][7] = SectorDataTable[( STableX[xp] + STableY[0] + STableZ[zpp] )][OfTableX[xp] + OfTableY[0] + OfTableZ[zpp]];
					//    BlocMatrix[1][8] = SectorDataTable[(STableX[xpp]+STableY[0]+STableZ[zpp])][OfTableX[xpp]+OfTableY[0]+OfTableZ[zpp]]

					//    BlocMatrix[2][0] = SectorDataTable[(STableX[xc ]+STableY[1]+STableZ[zc ])][OfTableX[xc ]+OfTableY[1]+OfTableZ[zc ]]
					BlocMatrix[2][1] = SectorDataTable[( STableX[xp] + STableY[1] + STableZ[zc] )][OfTableX[xp] + OfTableY[1] + OfTableZ[zc]];
					//    BlocMatrix[2][2] = SectorDataTable[(STableX[xpp]+STableY[1]+STableZ[zc ])][OfTableX[xpp]+OfTableY[1]+OfTableZ[zc ]]
					BlocMatrix[2][3] = SectorDataTable[( STableX[xc] + STableY[1] + STableZ[zp] )][OfTableX[xc] + OfTableY[1] + OfTableZ[zp]];
					BlocMatrix[2][4] = SectorDataTable[( STableX[xp] + STableY[1] + STableZ[zp] )][OfTableX[xp] + OfTableY[1] + OfTableZ[zp]];
					BlocMatrix[2][5] = SectorDataTable[( STableX[xpp] + STableY[1] + STableZ[zp] )][OfTableX[xpp] + OfTableY[1] + OfTableZ[zp]];
					//    BlocMatrix[2][6] = SectorDataTable[(STableX[xc ]+STableY[1]+STableZ[zpp])][OfTableX[xc ]+OfTableY[1]+OfTableZ[zpp]]
					BlocMatrix[2][7] = SectorDataTable[( STableX[xp] + STableY[1] + STableZ[zpp] )][OfTableX[xp] + OfTableY[1] + OfTableZ[zpp]];
					//    BlocMatrix[2][8] = SectorDataTable[(STableX[xpp]+STableY[1]+STableZ[zpp])][OfTableX[xpp]+OfTableY[1]+OfTableZ[zpp]]

					for( yc = 0; yc < VoxelSector.ZVOXELBLOCSIZE_Y; yc++ )
					{
						yp = yc + 1; ypp = yc + 2;

						// Scrolling bloc matrix by exchangingypp references.
						tmpp = BlocMatrix[0];
						BlocMatrix[0] = BlocMatrix[1];
						BlocMatrix[1] = BlocMatrix[2];
						BlocMatrix[2] = tmpp;

						// Fetching a new bloc of data slice;

						//      BlocMatrix[2][0] = SectorDataTable[(STableX[xc ]+STableY[ypp]+STableZ[zc ])].Data;    [OfTableX[xc ]+OfTableY[ypp]+OfTableZ[zc ]]
						BlocMatrix[2][1] = SectorDataTable[( STableX[xp] + STableY[ypp] + STableZ[zc] )][OfTableX[xp] + OfTableY[ypp] + OfTableZ[zc]];
						//      BlocMatrix[2][2] = SectorDataTable[(STableX[xpp]+STableY[ypp]+STableZ[zc ])].Data;	   [OfTableX[xpp]+OfTableY[ypp]+OfTableZ[zc ]]
						BlocMatrix[2][3] = SectorDataTable[( STableX[xc] + STableY[ypp] + STableZ[zp] )][OfTableX[xc] + OfTableY[ypp] + OfTableZ[zp]];
						BlocMatrix[2][4] = SectorDataTable[( STableX[xp] + STableY[ypp] + STableZ[zp] )][OfTableX[xp] + OfTableY[ypp] + OfTableZ[zp]];
						BlocMatrix[2][5] = SectorDataTable[( STableX[xpp] + STableY[ypp] + STableZ[zp] )][OfTableX[xpp] + OfTableY[ypp] + OfTableZ[zp]];
						//      BlocMatrix[2][6] = SectorDataTable[(STableX[xc ]+STableY[ypp]+STableZ[zpp])].Data;	   [OfTableX[xc ]+OfTableY[ypp]+OfTableZ[zpp]]
						BlocMatrix[2][7] = SectorDataTable[( STableX[xp] + STableY[ypp] + STableZ[zpp] )][OfTableX[xp] + OfTableY[ypp] + OfTableZ[zpp]];
						//      BlocMatrix[2][8] = SectorDataTable[(STableX[xpp]+STableY[ypp]+STableZ[zpp])].Data;	   [OfTableX[xpp]+OfTableY[ypp]+OfTableZ[zpp]]

						// Compute face culling info
						info = 0;
						if( BlocMatrix[1][4] > 0 )
						{

							MainVoxelDrawInfo = VoxelTypeTable[BlocMatrix[1][4]].properties.DrawInfo;
							VoxelSector.FACEDRAW_Operations[] SubTable = IntFaceStateTable[MainVoxelDrawInfo & VoxelGlobalSettings.ZVOXEL_DRAWINFO_CULLINGBITS];

							info |= ( ( SubTable[VoxelTypeTable[BlocMatrix[1][1]].properties.DrawInfo & VoxelGlobalSettings.ZVOXEL_DRAWINFO_CULLINGBITS] ) & VoxelSector.FACEDRAW_Operations.BEHIND );
							info |= ( ( SubTable[VoxelTypeTable[BlocMatrix[1][7]].properties.DrawInfo & VoxelGlobalSettings.ZVOXEL_DRAWINFO_CULLINGBITS] ) & VoxelSector.FACEDRAW_Operations.AHEAD );
							info |= ( ( SubTable[VoxelTypeTable[BlocMatrix[1][3]].properties.DrawInfo & VoxelGlobalSettings.ZVOXEL_DRAWINFO_CULLINGBITS] ) & VoxelSector.FACEDRAW_Operations.LEFT );
							info |= ( ( SubTable[VoxelTypeTable[BlocMatrix[1][5]].properties.DrawInfo & VoxelGlobalSettings.ZVOXEL_DRAWINFO_CULLINGBITS] ) & VoxelSector.FACEDRAW_Operations.RIGHT );
							info |= ( ( SubTable[VoxelTypeTable[BlocMatrix[0][4]].properties.DrawInfo & VoxelGlobalSettings.ZVOXEL_DRAWINFO_CULLINGBITS] ) & VoxelSector.FACEDRAW_Operations.BELOW );
							info |= ( ( SubTable[VoxelTypeTable[BlocMatrix[2][4]].properties.DrawInfo & VoxelGlobalSettings.ZVOXEL_DRAWINFO_CULLINGBITS] ) & VoxelSector.FACEDRAW_Operations.ABOVE );
						}

						// Write face culling info to face culling table

						Sector.Culler.setFaceCulling( Sector, OfTableX[xp] + OfTableY[yp] + OfTableZ[zp], info );

					}
				}
			}

		}
Beispiel #34
0
		internal static VoxelSector.FACEDRAW_Operations SectorUpdateFaceCulling_Partial( VoxelWorld world, VoxelSector Sector
					, VoxelSector.FACEDRAW_Operations FacesToDraw, bool Isolated )
		{
			VoxelType[] VoxelTypeTable;
			VoxelSector MissingSector;
			VoxelSector Sector_In, Sector_Out;
			int i;
			VoxelSector.FACEDRAW_Operations CuledFaces;
			int Off_Ip, Off_In, Off_Op, Off_Out, Off_Aux;
			VoxelSector.VoxelData VoxelData_In, VoxelData_Out;
			byte[] VoxelFC_In;
			int x, y, z;
			VoxelSector.FACEDRAW_Operations FaceState;
			//extern ushort IntFaceStateTable[][8];

			x = Sector.Pos_x;
			y = Sector.Pos_y;
			z = Sector.Pos_z;

			if( Isolated ) MissingSector = VoxelWorld.WorkingEmptySector;
			else MissingSector = VoxelWorld.WorkingFullSector;

			VoxelTypeTable = world.VoxelTypeManager.VoxelTable;

			Sector_In = Sector; if( Sector_In == null ) return ( 0 );
			Sector_Out = null;  // again a redundant assignment
			CuledFaces = 0;

			// Top Side

			if( ( FacesToDraw & VoxelSector.FACEDRAW_Operations.ABOVE ) != 0 )
				if( ( Sector_Out = Sector.near_sectors[(int)VoxelSector.RelativeVoxelOrds.ABOVE - 1] ) != null )
				{
					VoxelData_In = Sector_In.Data;
					VoxelData_Out = Sector_Out.Data;
					VoxelFC_In = Sector_In.Culler.GetData();

					for( Off_Ip = (int)VoxelSector.ZVOXELBLOCSIZE_Y - 1, Off_Op = 0; 
						Off_Ip < ( VoxelSector.ZVOXELBLOCSIZE_Y * VoxelSector.ZVOXELBLOCSIZE_X ); 
						Off_Ip += (int)VoxelSector.ZVOXELBLOCSIZE_Y, 
						Off_Op += (int)VoxelSector.ZVOXELBLOCSIZE_Y ) // x (0..15)
					{
						for( Off_Aux = 0; 
							Off_Aux < ( VoxelSector.ZVOXELBLOCSIZE_X * VoxelSector.ZVOXELBLOCSIZE_Y * VoxelSector.ZVOXELBLOCSIZE_Z ); 
							Off_Aux += (int)( VoxelSector.ZVOXELBLOCSIZE_X * VoxelSector.ZVOXELBLOCSIZE_Y ) ) // z (0..15)
						{
							Off_In = Off_Ip + Off_Aux;
							Off_Out = Off_Op + Off_Aux;
							FaceState = IntFaceStateTable[VoxelTypeTable[VoxelData_In.Data[Off_In]].properties.DrawInfo & VoxelGlobalSettings.ZVOXEL_DRAWINFO_CULLINGBITS][VoxelTypeTable[VoxelData_Out.Data[Off_Out]].properties.DrawInfo & VoxelGlobalSettings.ZVOXEL_DRAWINFO_CULLINGBITS];
							if( FaceState != 0 ) VoxelFC_In[Off_In] |= (byte)VoxelSector.FACEDRAW_Operations.ABOVE;
							else VoxelFC_In[Off_In] &= (byte)( ( ~(int)VoxelSector.FACEDRAW_Operations.ABOVE ) & 0xFF );
						}
					}
					CuledFaces |= VoxelSector.FACEDRAW_Operations.ABOVE;
				}
			// Bottom Side

			if( ( FacesToDraw & VoxelSector.FACEDRAW_Operations.BELOW ) != 0 )
				if( ( Sector_Out = Sector.near_sectors[(int)VoxelSector.RelativeVoxelOrds.BELOW - 1] ) != null )
				{
					VoxelData_In = Sector_In.Data;
					VoxelData_Out = Sector_Out.Data;
					VoxelFC_In = Sector_In.Culler.GetData();

					for( Off_Ip = 0, Off_Op = (int)VoxelSector.ZVOXELBLOCSIZE_Y - 1; 
						 Off_Ip < ( VoxelSector.ZVOXELBLOCSIZE_Y * VoxelSector.ZVOXELBLOCSIZE_Z ); 
						 Off_Ip += (int)VoxelSector.ZVOXELBLOCSIZE_Y, 
						 Off_Op += (int)VoxelSector.ZVOXELBLOCSIZE_Y ) // x (0..15)
					{
						for( Off_Aux = 0; 
							 Off_Aux < ( VoxelSector.ZVOXELBLOCSIZE_X * VoxelSector.ZVOXELBLOCSIZE_Y * VoxelSector.ZVOXELBLOCSIZE_Z ); 
							 Off_Aux += (int)( VoxelSector.ZVOXELBLOCSIZE_X * VoxelSector.ZVOXELBLOCSIZE_Y ) ) // z (0..15)
						{
							Off_In = Off_Ip + Off_Aux;
							Off_Out = Off_Op + Off_Aux;
							ushort Voxel_In = VoxelData_In.Data[Off_In];
							ushort Voxel_Out = VoxelData_Out.Data[Off_Out];
							//ZVoxelType * VtIn =  VoxelTypeTable[ Voxel_In ];
							//ZVoxelType * VtOut = VoxelTypeTable[ Voxel_Out ];


							FaceState = IntFaceStateTable[VoxelTypeTable[Voxel_In].properties.DrawInfo & VoxelGlobalSettings.ZVOXEL_DRAWINFO_CULLINGBITS][VoxelTypeTable[Voxel_Out].properties.DrawInfo & VoxelGlobalSettings.ZVOXEL_DRAWINFO_CULLINGBITS];

							//FaceState = IntFaceStateTable[ VoxelTypeTable[ VoxelData_In.Data[Off_In] ].DrawInfo & VoxelGlobalSettings.ZVOXEL_DRAWINFO_CULLINGBITS ][ VoxelTypeTable[ VoxelData_Out.Data[Off_Out] ].DrawInfo & VoxelGlobalSettings.ZVOXEL_DRAWINFO_CULLINGBITS ];
							if( FaceState != 0 ) VoxelFC_In[Off_In] |= (byte)VoxelSector.FACEDRAW_Operations.BELOW;
							else VoxelFC_In[Off_In] &= (byte)( (int)~VoxelSector.FACEDRAW_Operations.BELOW & 0xFF );
						}
					}
					CuledFaces |= VoxelSector.FACEDRAW_Operations.BELOW;
				}
					// Left Side

					if( ( FacesToDraw & VoxelSector.FACEDRAW_Operations.LEFT ) != 0 )
				if( ( Sector_Out = Sector.near_sectors[(int)VoxelSector.RelativeVoxelOrds.LEFT - 1] ) != null )
				{
					VoxelData_In = Sector_In.Data;
					VoxelData_Out = Sector_Out.Data;
					VoxelFC_In = Sector_In.Culler.GetData();
					// VoxelData_In[63]=1;
					// VoxelData_In[63 + VoxelSector.ZVOXELBLOCSIZE_Y*15 ]=14; // x
					// VoxelData_In[63 + VoxelSector.ZVOXELBLOCSIZE_Y * VoxelSector.ZVOXELBLOCSIZE_X * 15] = 13; // z

					for( Off_Ip = 0, Off_Op = (int)(VoxelSector.ZVOXELBLOCSIZE_Y * ( VoxelSector.ZVOXELBLOCSIZE_X - 1 )); 
						Off_Ip < ( VoxelSector.ZVOXELBLOCSIZE_Y * VoxelSector.ZVOXELBLOCSIZE_X * VoxelSector.ZVOXELBLOCSIZE_Z ); 
						Off_Ip += (int)( VoxelSector.ZVOXELBLOCSIZE_Y * VoxelSector.ZVOXELBLOCSIZE_X ), 
						Off_Op += (int)( VoxelSector.ZVOXELBLOCSIZE_Y * VoxelSector.ZVOXELBLOCSIZE_X ) ) // z (0..15)
					{
						for( Off_Aux = 0; Off_Aux < VoxelSector.ZVOXELBLOCSIZE_Y; Off_Aux++ ) // y (0..63)
						{
							Off_In = Off_Ip + Off_Aux;
							Off_Out = Off_Op + Off_Aux;
							//VoxelData_In[Off_In]=1; VoxelData_Out[Off_Out]=14;
							FaceState = IntFaceStateTable[VoxelTypeTable[VoxelData_In.Data[Off_In]].properties.DrawInfo & VoxelGlobalSettings.ZVOXEL_DRAWINFO_CULLINGBITS][VoxelTypeTable[VoxelData_Out.Data[Off_Out]].properties.DrawInfo & VoxelGlobalSettings.ZVOXEL_DRAWINFO_CULLINGBITS];
							if( FaceState != 0 ) VoxelFC_In[Off_In] |= (byte)VoxelSector.FACEDRAW_Operations.LEFT;
							else VoxelFC_In[Off_In] &= (byte)( (int)~VoxelSector.FACEDRAW_Operations.LEFT & 0xFF );
						}
					}
					CuledFaces |= VoxelSector.FACEDRAW_Operations.LEFT;
				}

			// Right Side

			if( ( FacesToDraw & VoxelSector.FACEDRAW_Operations.RIGHT ) != 0 )
				if( ( Sector_Out = Sector.near_sectors[(int)VoxelSector.RelativeVoxelOrds.RIGHT - 1] ) != null )
				{
					VoxelData_In = Sector_In.Data;
					VoxelData_Out = Sector_Out.Data;
					VoxelFC_In = Sector_In.Culler.GetData();

					for( Off_Ip = (int)( VoxelSector.ZVOXELBLOCSIZE_Y * ( VoxelSector.ZVOXELBLOCSIZE_X - 1 )), Off_Op = 0; 
						Off_Op < ( VoxelSector.ZVOXELBLOCSIZE_Y * VoxelSector.ZVOXELBLOCSIZE_X * VoxelSector.ZVOXELBLOCSIZE_Z ); 
						Off_Ip += (int)( VoxelSector.ZVOXELBLOCSIZE_Y * VoxelSector.ZVOXELBLOCSIZE_X ), Off_Op += (int)( VoxelSector.ZVOXELBLOCSIZE_Y * VoxelSector.ZVOXELBLOCSIZE_X ) ) // z (0..15)
					{
						for( Off_Aux = 0; Off_Aux < VoxelSector.ZVOXELBLOCSIZE_Y; Off_Aux++ ) // y (0..63)
						{
							Off_In = Off_Ip + Off_Aux;
							Off_Out = Off_Op + Off_Aux;
							FaceState = IntFaceStateTable[VoxelTypeTable[VoxelData_In.Data[Off_In]].properties.DrawInfo & VoxelGlobalSettings.ZVOXEL_DRAWINFO_CULLINGBITS][VoxelTypeTable[VoxelData_Out.Data[Off_Out]].properties.DrawInfo & VoxelGlobalSettings.ZVOXEL_DRAWINFO_CULLINGBITS];
							if( FaceState != 0 ) VoxelFC_In[Off_In] |= (byte)VoxelSector.FACEDRAW_Operations.RIGHT; else VoxelFC_In[Off_In] &= (byte)( (int)~VoxelSector.FACEDRAW_Operations.RIGHT & 0xFF );
						}
					}
					CuledFaces |= VoxelSector.FACEDRAW_Operations.RIGHT;
				}

			// Front Side

			if( ( FacesToDraw & VoxelSector.FACEDRAW_Operations.AHEAD ) != 0 )
				if( ( Sector_Out = Sector.near_sectors[(int)VoxelSector.RelativeVoxelOrds.AHEAD - 1] ) != null )
				{
					VoxelData_In = Sector_In.Data;
					VoxelData_Out = Sector_Out.Data;
					VoxelFC_In = Sector_In.Culler.GetData();

					for( Off_Ip = (int)( VoxelSector.ZVOXELBLOCSIZE_Y * VoxelSector.ZVOXELBLOCSIZE_X * ( VoxelSector.ZVOXELBLOCSIZE_Z - 1 ) ), Off_Op = 0;
						Off_Op < ( VoxelSector.ZVOXELBLOCSIZE_Y * VoxelSector.ZVOXELBLOCSIZE_X );
						Off_Ip += (int)VoxelSector.ZVOXELBLOCSIZE_Y, Off_Op += (int)VoxelSector.ZVOXELBLOCSIZE_Y ) // x (0..15)
					{
						for( Off_Aux = 0; Off_Aux < VoxelSector.ZVOXELBLOCSIZE_Y; Off_Aux++ ) // y (0..63)
						{
							Off_In = Off_Ip + Off_Aux;
							Off_Out = Off_Op + Off_Aux;
							FaceState = IntFaceStateTable[VoxelTypeTable[VoxelData_In.Data[Off_In]].properties.DrawInfo & VoxelGlobalSettings.ZVOXEL_DRAWINFO_CULLINGBITS][VoxelTypeTable[VoxelData_Out.Data[Off_Out]].properties.DrawInfo & VoxelGlobalSettings.ZVOXEL_DRAWINFO_CULLINGBITS];
							if( FaceState != 0 ) VoxelFC_In[Off_In] |= (byte)VoxelSector.FACEDRAW_Operations.AHEAD;
							else VoxelFC_In[Off_In] &= (byte)( (int)~VoxelSector.FACEDRAW_Operations.AHEAD & 0xFF );
						}
					}
					CuledFaces |= VoxelSector.FACEDRAW_Operations.AHEAD;
				}

			// Back Side

			if( ( FacesToDraw & VoxelSector.FACEDRAW_Operations.BEHIND ) != 0 )
				if( ( Sector_Out = Sector.near_sectors[(int)VoxelSector.RelativeVoxelOrds.BEHIND - 1] ) != null )
						{
							VoxelData_In = Sector_In.Data;
							VoxelData_Out = Sector_Out.Data;
							VoxelFC_In = Sector_In.Culler.GetData();
							for( Off_Ip = 0, Off_Op = (int)( VoxelSector.ZVOXELBLOCSIZE_Y * VoxelSector.ZVOXELBLOCSIZE_X * ( VoxelSector.ZVOXELBLOCSIZE_Z - 1 ) );
								Off_Ip < ( VoxelSector.ZVOXELBLOCSIZE_Y * VoxelSector.ZVOXELBLOCSIZE_X );
								Off_Ip += (int)VoxelSector.ZVOXELBLOCSIZE_Y, Off_Op += (int)VoxelSector.ZVOXELBLOCSIZE_Y ) // x (0..15)
							{
								for( Off_Aux = 0; Off_Aux < VoxelSector.ZVOXELBLOCSIZE_Y; Off_Aux++ ) // y (0..63)
								{
									Off_In = Off_Ip + Off_Aux;
									Off_Out = Off_Op + Off_Aux;
									FaceState = IntFaceStateTable[VoxelTypeTable[VoxelData_In.Data[Off_In]].properties.DrawInfo & VoxelGlobalSettings.ZVOXEL_DRAWINFO_CULLINGBITS][VoxelTypeTable[VoxelData_Out.Data[Off_Out]].properties.DrawInfo & VoxelGlobalSettings.ZVOXEL_DRAWINFO_CULLINGBITS];
									if( FaceState != 0 ) VoxelFC_In[Off_In] |= (byte)VoxelSector.FACEDRAW_Operations.BEHIND; else VoxelFC_In[Off_In] &= (byte)( (int)~VoxelSector.FACEDRAW_Operations.BEHIND & 0xFF );
								}
							}
							CuledFaces |= VoxelSector.FACEDRAW_Operations.BEHIND;
						}

			//Sector.PartialCulling ^= CuledFaces & ( VoxelSector.FACEDRAW_Operations.ABOVE | VoxelSector.FACEDRAW_Operations.BELOW | VoxelSector.FACEDRAW_Operations.LEFT | VoxelSector.FACEDRAW_Operations.RIGHT | VoxelSector.FACEDRAW_Operations.AHEAD | VoxelSector.FACEDRAW_Operations.BEHIND );
			//Sector.PartialCulling &= ( VoxelSector.FACEDRAW_Operations.ABOVE | VoxelSector.FACEDRAW_Operations.BELOW | VoxelSector.FACEDRAW_Operations.LEFT | VoxelSector.FACEDRAW_Operations.RIGHT | VoxelSector.FACEDRAW_Operations.AHEAD | VoxelSector.FACEDRAW_Operations.BEHIND );
			if( CuledFaces != 0 )
			{
				//Log.log( "Sector {0} {1} {2} is dirty", Sector.Pos_x, Sector.Pos_y, Sector.Pos_z );
				Sector_Out.Flag_Render_Dirty = true;
                Sector_In.Flag_Render_Dirty = true;
			}

			return ( CuledFaces );
		}
Beispiel #35
0
		internal override void Render( Display display, VoxelGameEnvironment game, VoxelWorld world )
		{
			HighPerfTimer Timer = new HighPerfTimer();
			HighPerfTimer Timer_SectorRefresh = new HighPerfTimer();
			long Time;
			uint RenderedSectors;
			int i;
			int in_centerX, in_centerY, in_centerZ;

			Timer.Start();

			Stat_RenderDrawFaces = 0;
			Stat_FaceTop = 0;
			Stat_FaceBottom = 0;
			Stat_FaceLeft = 0;
			Stat_FaceRight = 0;
			Stat_FaceFront = 0;
			Stat_FaceBack = 0;

			// Stats reset
			GameStats Stat = GameEnv.GameStat;

			if( Stat == null )
				return;

			// Precomputing values for faster math

			// Update per cycle.
			int UpdatePerCycle = 2;
			int n;

			if( Stat_RefreshWaitingSectorCount < 50 ) UpdatePerCycle = 1;
			if( Stat_RefreshWaitingSectorCount < 500 ) UpdatePerCycle = 2;
			else if( Stat.SectorRefresh_TotalTime < 32 ) UpdatePerCycle = 5;
			Stat_RefreshWaitingSectorCount = 0;

			// Stat Reset

			Stat.SectorRefresh_Count = 0;
			Stat.SectorRefresh_TotalTime = 0;
			Stat.SectorRefresh_MinTime = 0;
			Stat.SectorRefresh_MaxTime = 0;
			Stat.SectorRender_Count = 0;
			Stat.SectorRender_TotalTime = 0;
			Stat.SectorRefresh_Waiting = 0;

			// Renderwaiting system

			for( i = 0; i < 64; i++ ) RefreshToDo[i] = 0;
			for( i = 63; i > 0; i-- )
			{
				n = RefreshWaiters[i];
				if( n > UpdatePerCycle ) n = UpdatePerCycle;
				UpdatePerCycle -= n;
				RefreshToDo[i] = n;
			}
			RefreshToDo[0] = UpdatePerCycle;

			for( i = 0; i < 64; i++ ) RefreshWaiters[i] = 0;

			// Computing Frustum and Setting up Projection
			int Sector_x, Sector_y, Sector_z;
			int x, y, z;

			VoxelSector Sector;
			int Priority, PriorityBoost;
			uint Sector_Refresh_Count;

			// Transforming Camera coords to sector coords. One Voxel is 256 observer units. One sector is 16x16x32.
			btVector3 origin;
			Camera.location.getOrigin( out origin );

			Sector_x = ( (int)origin.x >> ( world.VoxelBlockSizeBits + VoxelSector.ZVOXELBLOCSHIFT_X ) );
			Sector_y = ( (int)origin.y >> ( world.VoxelBlockSizeBits + VoxelSector.ZVOXELBLOCSHIFT_Y ) );
			Sector_z = ( (int)origin.z >> ( world.VoxelBlockSizeBits + VoxelSector.ZVOXELBLOCSHIFT_Z ) );

			in_centerX = (int)origin.x & VoxelSector.ZVOXELBLOCMASK_X;
			in_centerY = (int)origin.y & VoxelSector.ZVOXELBLOCMASK_Y;
			in_centerZ = (int)origin.z & VoxelSector.ZVOXELBLOCMASK_Z;


			// Rendering loop
			// Preparation and first rendering pass

			RenderedSectors = 0;
			Sector_Refresh_Count = 0;
			int voxelSizeBits = world.VoxelBlockSizeBits;
			float voxelSize = world.VoxelBlockSize;
			SectorSphere.SphereEntry SectorSphereEntry;
			uint SectorsToProcess = SectorSphere.GetEntryCount();

			btVector3 Cv;
			btVector3 Cv2;
			Cv2.w = 0;
			Cv.w = 0;

			for( int Entry = 0; Entry < SectorsToProcess; Entry++ )
			{
				SectorSphere.GetEntry( Entry, out SectorSphereEntry );

				x = SectorSphereEntry.x + Sector_x;
				y = SectorSphereEntry.y + Sector_y;
				z = SectorSphereEntry.z + Sector_z;

				// for (x = Start_x ; x <= End_x ; x++)
				// for (y = Start_y; y <= End_y ; y++)
				// for (z = Start_z; z <= End_z ; z++)

				// try to see if sector is visible

				bool SectorVisible;

				Cv.x = (float)( ( x ) << ( voxelSizeBits + VoxelSector.ZVOXELBLOCSHIFT_X ) );
				Cv.y = (float)( ( y ) << ( voxelSizeBits + VoxelSector.ZVOXELBLOCSHIFT_Y ) );
				Cv.z = (float)( ( z ) << ( voxelSizeBits + VoxelSector.ZVOXELBLOCSHIFT_Z ) );

				SectorVisible = false;
				Cv2.x = ( 0 * VoxelSector.ZVOXELBLOCSIZE_X * voxelSize ); Cv2.y = ( 0 * VoxelSector.ZVOXELBLOCSIZE_Y * voxelSize ); Cv2.z = ( 0 * VoxelSector.ZVOXELBLOCSIZE_Z * voxelSize );
				Cv2.Add( ref Cv, out Cv2 ); SectorVisible |= Is_PointVisible( ref Camera.location, ref Cv2 );
				Cv2.x = ( 1 * VoxelSector.ZVOXELBLOCSIZE_X * voxelSize ); Cv2.y = ( 0 * VoxelSector.ZVOXELBLOCSIZE_Y * voxelSize ); Cv2.z = ( 0 * VoxelSector.ZVOXELBLOCSIZE_Z * voxelSize );
				Cv2.Add( ref Cv, out Cv2 ); SectorVisible |= Is_PointVisible( ref Camera.location, ref Cv2 );
				Cv2.x = ( 1 * VoxelSector.ZVOXELBLOCSIZE_X * voxelSize ); Cv2.y = ( 0 * VoxelSector.ZVOXELBLOCSIZE_Y * voxelSize ); Cv2.z = ( 1 * VoxelSector.ZVOXELBLOCSIZE_Z * voxelSize );
				Cv2.Add( ref Cv, out Cv2 ); SectorVisible |= Is_PointVisible( ref Camera.location, ref Cv2 );
				Cv2.x = ( 0 * VoxelSector.ZVOXELBLOCSIZE_X * voxelSize ); Cv2.y = ( 0 * VoxelSector.ZVOXELBLOCSIZE_Y * voxelSize ); Cv2.z = ( 1 * VoxelSector.ZVOXELBLOCSIZE_Z * voxelSize );
				Cv2.Add( ref Cv, out Cv2 ); SectorVisible |= Is_PointVisible( ref Camera.location, ref Cv2 );
				Cv2.x = ( 0 * VoxelSector.ZVOXELBLOCSIZE_X * voxelSize ); Cv2.y = ( 1 * VoxelSector.ZVOXELBLOCSIZE_Y * voxelSize ); Cv2.z = ( 0 * VoxelSector.ZVOXELBLOCSIZE_Z * voxelSize );
				Cv2.Add( ref Cv, out Cv2 ); SectorVisible |= Is_PointVisible( ref Camera.location, ref Cv2 );
				Cv2.x = ( 1 * VoxelSector.ZVOXELBLOCSIZE_X * voxelSize ); Cv2.y = ( 1 * VoxelSector.ZVOXELBLOCSIZE_Y * voxelSize ); Cv2.z = ( 0 * VoxelSector.ZVOXELBLOCSIZE_Z * voxelSize );
				Cv2.Add( ref Cv, out Cv2 ); SectorVisible |= Is_PointVisible( ref Camera.location, ref Cv2 );
				Cv2.x = ( 1 * VoxelSector.ZVOXELBLOCSIZE_X * voxelSize ); Cv2.y = ( 1 * VoxelSector.ZVOXELBLOCSIZE_Y * voxelSize ); Cv2.z = ( 1 * VoxelSector.ZVOXELBLOCSIZE_Z * voxelSize );
				Cv2.Add( ref Cv, out Cv2 ); SectorVisible |= Is_PointVisible( ref Camera.location, ref Cv2 );
				Cv2.x = ( 0 * VoxelSector.ZVOXELBLOCSIZE_X * voxelSize ); Cv2.y = ( 1 * VoxelSector.ZVOXELBLOCSIZE_Y * voxelSize ); Cv2.z = ( 1 * VoxelSector.ZVOXELBLOCSIZE_Z * voxelSize );
				Cv2.Add( ref Cv, out Cv2 ); SectorVisible |= Is_PointVisible( ref Camera.location, ref Cv2 );

				Sector = world.FindSector( x, y, z );
				Priority = RadiusZones.GetZone( x - Sector_x, y - Sector_y, z - Sector_z );
				PriorityBoost = ( SectorVisible && Priority <= 2 ) ? 1 : 0;
				// Go = true;

				if( Sector != null )
				{
					if( Sector.transparent_geometry.transparent_render_sorting != SectorSphereEntry.relative_pos )
					{
						Sector.transparent_geometry.transparent_render_sorting = SectorSphereEntry.relative_pos;
						Sector.Flag_Render_Dirty_Transparent = true;
						Sector.transparent_geometry.sortedX = -1;
					}
					if( SectorSphereEntry.relative_pos == VoxelSector.RelativeVoxelOrds.INCENTER )
					{
						if( center_sorted_x != in_centerX
							|| center_sorted_y != in_centerY
							|| center_sorted_z != in_centerZ )
						{
							Sector.Flag_Render_Dirty_Transparent = true;
							BuildSortListInSector( in_centerX, in_centerY, in_centerZ );
						}
					}


					Sector.Flag_IsVisibleAtLastRendering = SectorVisible || Priority >= 3;
					// Display lists preparation
					if( ( Sector.Flag_Render_Dirty  || Sector.Flag_Render_Dirty_Transparent )
						&& GameEnv.Enable_NewSectorRendering )
					{

						// if (Sector_Refresh_Count < 5 || Priority==4)
						if( ( RefreshToDo[Sector.RefreshWaitCount] != 0 ) || Sector.Flag_HighPriorityRefresh )
						{

							if ( VoxelGlobalSettings.COMPILEOPTION_FINETIMINGTRACKING )
								Timer_SectorRefresh.Start();

							RefreshToDo[Sector.RefreshWaitCount]--;
							Sector.Flag_HighPriorityRefresh = false;

							//Log.log( "Draw sector geometry {0} {1} {2}", Sector.Pos_x, Sector.Pos_y, Sector.Pos_z );

							MakeSectorRenderingData( Sector );

							MakeSectorRenderingData_Sorted( Sector, SectorSphereEntry.relative_pos
														, in_centerX, in_centerY, in_centerZ );
							//Log.log( "Drew sector geometry {0} {1} {2}", Sector.Pos_x, Sector.Pos_y, Sector.Pos_z );

							Sector_Refresh_Count++;
							Sector.RefreshWaitCount = 0;
							Stat.SectorRefresh_Count++;

							if( VoxelGlobalSettings.COMPILEOPTION_FINETIMINGTRACKING )
							{
								Timer_SectorRefresh.End(); Time = Timer_SectorRefresh.GetResult(); Stat.SectorRefresh_TotalTime += (uint)Time;
								if( Time < Stat.SectorRefresh_MinTime ) Stat.SectorRefresh_MinTime = (uint)Time;
								if( Time > Stat.SectorRefresh_MaxTime ) Stat.SectorRefresh_MaxTime = (uint)Time;
							}
						}
						else
						{
							Sector.RefreshWaitCount++;
							if( Sector.RefreshWaitCount > 31 ) Sector.RefreshWaitCount = 31;
							if( Priority == 4 ) Sector.RefreshWaitCount++;
							RefreshWaiters[Sector.RefreshWaitCount]++;
							Stat_RefreshWaitingSectorCount++;
							Stat.SectorRefresh_Waiting++;
						}

					}


					// Rendering first pass
					if( Sector.Flag_IsVisibleAtLastRendering
						&& ( !Sector.Flag_Void_Regular )
						)
					{
						if( VoxelGlobalSettings.COMPILEOPTION_FINETIMINGTRACKING )
							Timer_SectorRefresh.Start();

						Sector.solid_geometry.SetupUniforms( world.TextureAtlas.OpenGl_TextureRef );
						Sector.solid_geometry.DrawBuffer();
						//glCallList( ( (ZRender_Interface_displaydata*)Sector.DisplayData ).DisplayList_Regular[current_gl_camera] );

						Stat.SectorRender_Count++; RenderedSectors++;

						if( VoxelGlobalSettings.COMPILEOPTION_FINETIMINGTRACKING ) {
							Timer_SectorRefresh.End(); Time = Timer_SectorRefresh.GetResult(); Stat.SectorRender_TotalTime += (uint)Time;
						}
					}
				}
				else
				{
					if( GameEnv.Enable_LoadNewSector )
						world.RequestSector( x, y, z, Priority + PriorityBoost );
					if( VoxelGlobalSettings.COMPILEOPTION_DRAW_MISSING_SECTORS )
					{
						GL.Disable( EnableCap.DepthTest );
						if( SectorVisible ) // culling 
							Render_EmptySector( display, world, x, y, z, 1.0f, 0.3f, 0.1f );
						GL.Enable( EnableCap.DepthTest );
					}
					//return;
				}
			}

			// Second pass rendering
			//GL.Disable( EnableCap.DepthTest );
			//GL.DepthMask( false );
			//glDepthMask( GL_FALSE );

#if !USE_GLES2
			GL.AlphaFunc( AlphaFunction.Greater, 0.2f );
			GL.Enable( EnableCap.AlphaTest );
#endif
			Display.EnableBlending( true );

			for( int Entry = 0; Entry < SectorsToProcess; Entry++ )
			{
				SectorSphere.GetEntry( Entry, out SectorSphereEntry );

				x = SectorSphereEntry.x + Sector_x;
				y = SectorSphereEntry.y + Sector_y;
				z = SectorSphereEntry.z + Sector_z;

				Sector = world.FindSector( x, y, z );
				// printf("Sector : %ld %ld %ld %lu\n", x, y, z, (uint)(Sector != 0));9
				if( Sector != null )
				{
					if( Sector.Flag_IsVisibleAtLastRendering
					   && ( !Sector.Flag_Void_Transparent )
					   )
					{
						if( VoxelGlobalSettings.COMPILEOPTION_FINETIMINGTRACKING )
							Timer_SectorRefresh.Start();

						Sector.transparent_geometry.SetupUniforms( world.TextureAtlas.OpenGl_TextureRef );
						Sector.transparent_geometry.DrawBuffer();
						//glCallList( ( (ZRender_Interface_displaydata*)Sector.DisplayData ).DisplayList_Transparent[current_gl_camera] );
						Stat.SectorRender_Count++;

						if( VoxelGlobalSettings.COMPILEOPTION_FINETIMINGTRACKING )
						{
							Timer_SectorRefresh.End(); Time = Timer_SectorRefresh.GetResult();
							Stat.SectorRender_TotalTime += (uint)Time;
						}
					}

				}
			}
			GL.Enable( EnableCap.DepthTest );
			Display.EnableBlending( false );

			Timer.End();

			/*printf("Frame Time : %lu Rend Sects: %lu Draw Faces :%lu Top:%lu Bot:%lu Le:%lu Ri:%lu Front:%lu Back:%lu\n",Timer.GetResult(), RenderedSectors, Stat_RenderDrawFaces, Stat_FaceTop, Stat_FaceBottom,
				   Stat_FaceLeft,Stat_FaceRight,Stat_FaceFront,Stat_FaceBack);*/

			//printf("RenderedSectors : %lu\n",RenderedSectors);
			//SDL_GL_SwapBuffers( );
		}