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)); }
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(); }
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(); }
public ChunkRegionSystem(VoxelWorld voxelWorld) : base(voxelWorld) { _VoxelWorld = voxelWorld; _ChunksRequiringRemesh = new Queue <Chunk>(); _ChunksPendingDisposal = new Stack <Chunk>(); _LoadableChunks = new HashSet <Vector3i>(); }
/// <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); } }
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); } }
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(); } }
protected override void OnInit(Parameters parameters) { random = Entity.Simulation.GetComponentManager <DeterministicRandom>(); voxelComponent = Entity.GetComponent <VoxelComponent>(); voxelWorld = voxelComponent.World; SelectTarget(); }
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 }
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; }
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); }
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; }
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); }
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"); }
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); }
/// <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(); }
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)); }
/// 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); } }
private void Update() { current_world_position = VoxelWorld.PositionToWorldPosition(transform.position); if (multithreading) { ThreadedUpdate(); return; } RegularUpdate(); }
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); }
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)); }
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; }
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); }
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(); }
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); } }
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"); }
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 ); } } } }
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 ); }
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( ); }