/// <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)); }
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); }
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); }