예제 #1
0
        /// <summary>
        /// Configure the CSG Expression of a vertical constraint (including 'shadow').
        /// </summary>
        private void configureVerticalConstraintExpression(vec3 refPos, Drone first, Drone second, CsgExpression expr)
        {
            // Calculate primary plane.
            vec3 start = first.CurrentPosition;
            vec3 end   = second.CurrentPosition;
            vec3 mid   = (start + end) / 2f;

            vec3 up     = new vec3(0, 1, 0);
            vec3 dir    = end - start;
            vec3 normal = vec3.cross(dir, up);

            vec3 d      = refPos - mid;
            bool invert = vec3.dot(d, normal) < 0;

            if (invert)
            {
                normal *= -1f;
            }

            expr.SetParameterVec3("plane1Normal", normal);
            expr.SetParameterFloat("plane1Dis", vec3.dot(normal, mid));

            // Caluclate first shadow plane
            vec3 s1Pos    = start;
            vec3 s1Normal = vec3.cross(up, s1Pos - refPos);

            if (invert)
            {
                s1Normal *= -1f;
            }

            expr.SetParameterVec3("plane2Normal", s1Normal);
            expr.SetParameterFloat("plane2Dis", vec3.dot(s1Normal, s1Pos));

            // Caluclate second shadow plane
            vec3 s2Pos    = end;
            vec3 s2Normal = vec3.cross(s2Pos - refPos, up);

            if (invert)
            {
                s2Normal *= -1f;
            }

            expr.SetParameterVec3("plane3Normal", s2Normal);
            expr.SetParameterFloat("plane3Dis", vec3.dot(s2Normal, s2Pos));
        }
예제 #2
0
        public void DigCylinder(vec3 worldNormal, vec3 position, float radius, IEnumerable <int> filterMaterials, int terrainMaterialId = 1, DigMode digMode = DigMode.Substract)
        {
            cylinderNode.MaterialIndex = terrainMaterialId;
            cylinderNode.SetParameterFloat("digRadius", radius);
            cylinderNode.SetParameterVec3("digPosition", position);

            vec3 dx, dy, dz;

            player.AlignmentSystem(worldNormal, out dx, out dy, out dz);
            cylinderNode.SetParameterVec3("digDirX", dx);
            cylinderNode.SetParameterVec3("digDirY", dy);
            cylinderNode.SetParameterVec3("digDirZ", dz);

            Dig(cylinderNode, new BoundingSphere(position, radius * 1.5f), digMode, filterMaterials);
        }
예제 #3
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);
        }