/// <summary> /// Adds all csg constraints to a diff node. /// </summary> public void AddCsgConstraints(CsgOpDiff diffNode, vec3 refPos) { Drone refDrone = ReferenceDrone; switch (refDrone.Type) { case DroneType.Chain: for (int i = 0; i < drones.Count - 1; ++i) { Drone first = drones[i]; Drone second = drones[i + 1]; CsgExpression expr = constraintExpression[i]; configureVerticalConstraintExpression(refPos, first, second, expr); diffNode.AddNode(expr); } break; default: Debug.Fail("Not implemented/Invalid"); break; } }
public DiggingController(World world, Player player) { Debug.Assert(instance == null, "Singleton is violated"); instance = this; this.world = world; this.player = player; string digParas = "digRadius:float, digPosition:vec3, digDirX:vec3, digDirY:vec3, digDirZ:vec3"; string sphereExpression = "-digRadius + distance(vec3(x,y,z), digPosition)"; sphereNode = new CsgExpression(1, sphereExpression, UpvoidMiner.ModDomain, digParas); string boxExpression = @"p = vec3(x,y,z) - digPosition; dx = abs(dot(p, digDirX)); dy = abs(dot(p, digDirY)); dz = abs(dot(p, digDirZ)); -digRadius + max(dx, max(dy, dz))"; boxNode = new CsgExpression(1, boxExpression, UpvoidMiner.ModDomain, digParas); string cylinderExpression = @"p = vec3(x,y,z) - digPosition; dx = abs(dot(p, digDirX)); dy = abs(dot(p, digDirY)); dz = abs(dot(p, digDirZ)); -digRadius + max(dy, length(vec2(dx, dz)))"; cylinderNode = new CsgExpression(1, cylinderExpression, UpvoidMiner.ModDomain, digParas); string playerExpression = @"p = vec3(x,y,z) - playerPosition; dx = abs(dot(p, digDirX)); dy = abs(dot(p, digDirY)); dz = abs(dot(p, digDirZ)); -playerRadius + max(dy, length(vec2(dx, dz)))"; playerNode = new CsgExpression(1, playerExpression, UpvoidMiner.ModDomain, "playerRadius:float, playerPosition:vec3, digDirX:vec3, digDirY:vec3, digDirZ:vec3"); }
/// <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)); }