Example #1
0
        public void Dig(CsgNode shape, BoundingSphere shapeBoundary, DigMode digMode, IEnumerable <int> materialFilter)
        {
            CsgNode digShape = null;

            // constraintDiffNode performs the constraint as a CSG operation
            // by cutting away anything of thge digging shape not inside the allowed area.
            CsgOpDiff constraintDiffNode = new CsgOpDiff();

            // Assemble difference operation by applying all drone constraints.
            player.AddDroneConstraints(constraintDiffNode, shapeBoundary.Center);

            // When placing material, add a safety margin around the player to prevent it from physically glitching trough the terrain
            if (digMode == DigMode.Add)
            {
                playerNode.SetParameterFloat("playerRadius", player.Character.CharacterDiameter * 0.5f + 0.2f);
                playerNode.SetParameterVec3("playerPosition", player.Character.Position);
                playerNode.SetParameterVec3("digDirX", new vec3(1, 0, 0));
                playerNode.SetParameterVec3("digDirZ", new vec3(0, 0, 1));
                playerNode.SetParameterVec3("digDirY", new vec3(0, 0, player.Character.BodyHeight * 0.5f + 0.2f));
                constraintDiffNode.AddNode(playerNode);
            }

            // We apply the constraint by substracting it from the given shape.
            CsgOpConcat constraintedShape = new CsgOpConcat();

            constraintedShape.AddNode(shape);
            constraintedShape.AddNode(constraintDiffNode);
            digShape = constraintedShape;

            CsgNode digNode = null;

            // Depending on the digging mode, we either add or substract the digging shape from the terrain.
            if (digMode == DigMode.Substract)
            {
                digNode = new CsgOpDiff(digShape);
            }
            else
            {
                digNode = new CsgOpUnion(digShape);
            }

            // Filter for tools
            CsgNode filterNode = digNode;

            if (materialFilter != null)
            {
                CsgFilterNode filter = new CsgFilterNode(true, digNode);
                foreach (int mat in materialFilter)
                {
                    filter.AddMaterial(mat);
                }
                filter.AddMaterial(0); // Air must be white-listed, too!
                filterNode = filter;
            }

            // Float elimination
            CsgOpConcat collapser = new CsgOpConcat(filterNode);

            collapser.AddNode(new CsgCollapseNode());

            // Callback for statistical purposes.
            CsgStatCallback finalNode = new CsgStatCallback(collapser, 4, 4);

            finalNode.AddSimpleVolumeCallback("UpvoidMiner", UpvoidMiner.ModDomain, "UpvoidMiner.DiggingController", "StatCallback");
            finalNode.AddVolumeChangePointCallback("UpvoidMiner", UpvoidMiner.ModDomain, "UpvoidMiner.DiggingController", "PointCallback");

            world.Terrain.ModifyTerrain(shapeBoundary, finalNode);
        }
Example #2
0
        /// <summary>
        /// Creates the CSG node network for the terrain generation.
        /// </returns>
        public CsgNode createTerrain()
        {
            // Load and return a CsgNode based on the "Hills" expression resource. This will create some generic perlin-based hills.
            CsgOpConcat concat = new CsgOpConcat();

            {
                CsgOpUnion    union        = new CsgOpUnion();
                StringBuilder hillsDefines = new StringBuilder();
                // Introduce variables.
                hillsDefines.Append("pos = vec3(x, y, z);");
                // Import perlin noise.
                hillsDefines.Append("perlins(x,y,z) $= ::Perlin;");
                hillsDefines.Append("perlin(v) = perlins(v.x, v.y, v.z);");
                // Hill structue.
                //hillsDefines.Append("Hills = perlins(x / 300, 0.00001 * y, z / 300) + perlins(x / 100, 0.00001 * y, z / 100) * .5 + perlins(x / 30, 0.00001 * y, z / 30) * .25 + perlins(x / 10, 0.00001 * y, z / 10) * .05;");
                hillsDefines.Append("Hills = perlins(x / 300, y / 300, z / 300) + perlins(x / 100, y / 100, z / 100) * .5 + perlins(x / 30, y / 30, z / 30) * .25 + perlins(x / 10, y / 10, z / 10) * .05;");
                hillsDefines.Append("Hills = (Hills + 1).pow2 * 50;");
                string hillsDef = hillsDefines.ToString();

                CsgOpConcat groundTerrain = new CsgOpConcat();
                {
                    CsgOpUnion groundTerrainFull = new CsgOpUnion();
                    groundTerrainFull.AddNode(new CsgExpression(terrainDirt.Index, "-1", UpvoidMiner.ModDomain));
                    groundTerrainFull.AddNode(new CsgExpression(terrainDesert.Index, hillsDef + "3 * perlins(x / 300, z / 300, y / 100)", UpvoidMiner.ModDomain));

                    CsgOpDiff groundTerrainDiff = new CsgOpDiff();
                    groundTerrainDiff.AddNode(new CsgExpression(1, "-y-90", UpvoidMiner.ModDomain));

                    groundTerrain.AddNode(groundTerrainFull);
                    groundTerrain.AddNode(groundTerrainDiff);
                }

                union.AddNode(new CsgExpression(terrainDirt.Index, hillsDef + "y + Hills", UpvoidMiner.ModDomain));
                union.AddNode(groundTerrain);
                union.AddNode(new CsgExpression(terrainRock.Index, hillsDef + "y + Hills + (5 + perlins(x / 5, z / 6, y / 7) * 3 + perlins(z / 45, y / 46, x / 47) * 13)", UpvoidMiner.ModDomain));
                concat.AddNode(union);
            }

            {
                CsgOpDiff     diff        = new CsgOpDiff();
                StringBuilder caveDefines = new StringBuilder();
                // Introduce variables.
                caveDefines.Append("pos = vec3(x, y, z);");
                // Import perlin noise.
                caveDefines.Append("perlins(x,y,z) $= ::Perlin;");
                caveDefines.Append("perlin(v) = perlins(v.x, v.y, v.z);");
                // Cave structue.
                //hillsDefines.Append("Hills = perlins(x / 300, 0.00001 * y, z / 300) + perlins(x / 100, 0.00001 * y, z / 100) * .5 + perlins(x / 30, 0.00001 * y, z / 30) * .25 + perlins(x / 10, 0.00001 * y, z / 10) * .05;");
                caveDefines.Append("CaveDensity = clamp(perlins(x / 30, y / 30, z / 30) * 4, 0, 1);");
                caveDefines.Append("CaveDensity = CaveDensity * clamp((y + 100) * .2, 0, 1);");
                caveDefines.Append("Caves = (perlins(x / 17, y / 17, z / 17) + perlins(x / 6, y / 6, z / 6) * .5 - .2) + (5 - CaveDensity * 5);");
                string caveDef = caveDefines.ToString();

                diff.AddNode(new CsgExpression(1, caveDef + "Caves", UpvoidMiner.ModDomain));
                concat.AddNode(diff);
            }

            //concat.AddNode(new CsgAutomatonNode(Resources.UseAutomaton("Trees", UpvoidMiner.ModDomain), world, 4));
            //concat.AddNode(new CsgAutomatonNode(Resources.UseAutomaton("Cacti", UpvoidMiner.ModDomain), world, 4));
            //concat.AddNode(new CsgAutomatonNode(Resources.UseAutomaton("Surface", UpvoidMiner.ModDomain), world, 4));
            concat.AddNode(new CsgCollapseNode());


            return(concat);
        }