Esempio n. 1
0
    /// <summary>
    /// Renders a chunk from its data. If the chunk is rendered
    /// for the first time. It adds it to the scene. If not, it
    /// just replaces its mesh with the new one.
    /// </summary>
    /// <param name="firstRender"></param>
    public void Render(bool firstRender)
    {
        if (firstRender)
        {
            for (int i = 0; i < SUBCHUNK_COUNT; i++)
            {
                // Create each sub chunks and place them
                var subChunk = m_SubChunks[i];
                subChunk.Name = i.ToString();
                subChunk.Translate(new Vector3(0, i * CHUNK_SIZE, 0));

                // Creates the mesh.
                subChunk.Mesh = Renderer.Render(subChunk);

                // If the subchunk is not empty, create the collision.
                if (subChunk.Mesh != null)
                {
                    subChunk.CreateTrimeshCollision();
                }

                // Place each voxel sprite in the chunk.
                foreach (VoxelSprite voxelSprite in subChunk.GetDecorations())
                {
                    if (voxelSprite is null)
                    {
                        continue;
                    }

                    var newMesh = new MeshInstance();
                    newMesh.Scale = new Vector3(1f / 8f, 1f / 8f, 1f / 8f);
                    newMesh.AddToGroup("decoration");
                    newMesh.MaterialOverride = Renderer.GetWavingShader;
                    newMesh.SetDeferred("translation", voxelSprite.Position);
                    newMesh.Mesh = voxelSprite.Mesh;
                    subChunk.CallDeferred("add_child", newMesh);
                }

                this.CallDeferred("add_child", subChunk);

                // Creating a visibility notifier per chunk.
                // This is useful for the frustrum culling.
                // Connect the signals to the methods on the subchunk.
                //visibilityNotifier.Connect("camera_entered", subChunk, "CameraEntered", null, 1);
                //visibilityNotifier.Connect("camera_exited", subChunk, "CameraExited", null, 1);
            }
        }
        else
        {
            for (int i = 0; i < SUBCHUNK_COUNT; i++)
            {
                var subChunk = m_SubChunks[i];
                subChunk.Mesh = Renderer.Render(subChunk);

                // removes old collisions
                foreach (Node node in subChunk.GetChildren())
                {
                    node.CallDeferred("queue_free");
                }
                // Update collisions too
                if (subChunk.Mesh != null)
                {
                    subChunk.CreateTrimeshCollision();
                }
            }

            needUpdate = false;
        }
    }
Esempio n. 2
0
    private void Render(Chunk pChunk)
    {
        // If chunk is already loaded.
        if (LoadedChunks.ContainsKey(pChunk.Offset))
        {
            return;
        }

        SurfaceTool = new SurfaceTool();
        SurfaceTool.Begin(Mesh.PrimitiveType.Triangles);

        // Adding material
        Material mat = VoxMaterial.Duplicate() as Material;

        SurfaceTool.SetMaterial(mat);

        // Creating the mesh. Voxel by voxel
        for (int y = 0; y < Chunk.ChunkSize.y; y++)
        {
            for (int x = 0; x < Chunk.ChunkSize.x; x++)
            {
                for (int z = 0; z < Chunk.ChunkSize.z; z++)
                {
                    if (!pChunk.Voxels[x, y, z].Active)
                    {
                        continue;
                    }

                    CreateVoxel(SurfaceTool, x, y, z, pChunk);
                }
            }
        }

        // Reduces vertex size
        SurfaceTool.Index();

        // Creating instance
        MeshInstance chunk = new MeshInstance
        {
            Mesh        = SurfaceTool.Commit(),
            Name        = pChunk.Offset.ToString(),
            Translation = new Vector3(pChunk.Offset.x * Chunk.ChunkSize.x, 0, pChunk.Offset.y * Chunk.ChunkSize.z)
        };

        // Creating collisions
        //chunk.CreateTrimeshCollision();


        // Tagging the chunk
        chunk.AddToGroup("Chunk");

        // Chunk is now loaded. Adding to the scene.
        LoadedChunks.TryAdd(pChunk.Offset, pChunk);
        this.CallDeferred("add_child", chunk);

        if (pChunk.VoxelSprite.Count < 64)
        {
            // Adding voxelsprite
            foreach (VoxelSprite voxSprite in pChunk.VoxelSprite)
            {
                var meshInstance = new MeshInstance();
                meshInstance.SetDeferred("mesh", voxSprite.Mesh);

                // Adding next frame to avoid locking problems.
                chunk.CallDeferred("add_child", meshInstance);

                // Moving next frame because not in tree yet
                meshInstance.SetDeferred("translation", voxSprite.Position);

                // Applying wind shader.
                meshInstance.SetDeferred("material_override", GrassMaterial);

                // Scaling down because its a decoration
                meshInstance.Scale = meshInstance.Scale /= 8;
            }
        }



        // Fade in animation.
        //var t2 = new Tween();
        //chunk.AddChild(t2);
        //t2.InterpolateProperty(mat, "albedo_color", new Color(1, 1, 1, 0f), new Color(1, 1, 1, 1f), 1f, Tween.TransitionType.Linear, Tween.EaseType.InOut);
        //t2.Start();

        SurfaceTool.Clear();
    }