public int ApplyDecomposition(Decomposition decomp) { var numUnBoundArgs = 0; subSteps = decomp.SubSteps.ToList(); subOrderings = decomp.SubOrderings.ToList(); subLinks = decomp.SubLinks.ToList(); // For each variable term, find and substitute decomp term foreach (var term in Terms) { var decompTerm = decomp.Terms.FirstOrDefault(dterm => term.Variable.Equals(dterm.Variable)); if (decompTerm == null) { numUnBoundArgs++; // need to pick some object to substitute. Any will do. continue; } AddBinding(term.Variable, decompTerm.Constant); } // Check Equality Constraints if (!NonEqualTermsAreNonequal()) { return(-1); } // Also add bindings to Initial and Goal step. foreach (var effect in InitialStep.Effects) { foreach (var term in effect.Terms) { var compTerm = Terms.FirstOrDefault(cterm => term.Variable.Equals(cterm.Variable)); if (compTerm == null) { throw new System.Exception(); } term.Constant = compTerm.Constant; } } foreach (var precon in GoalStep.Preconditions) { foreach (var term in precon.Terms) { var compTerm = Terms.FirstOrDefault(cterm => term.Variable.Equals(cterm.Variable)); if (compTerm == null) { throw new System.Exception(); } term.Constant = compTerm.Constant; } } var unlistedDecompTerms = decomp.Terms.Where(dt => !Terms.Any(t => dt.Equals(t))); foreach (var udt in unlistedDecompTerms) { Terms.Add(udt); } //foreach(var substep in SubSteps) //{ // foreach(var precon in substep.Preconditions) // { // if (substep.OpenConditions.Contains(precon)) // { // if (InitialStep.Effects.Contains(precon)) // { // SubLinks.Add(new CausalLink<IPlanStep>(precon, InitialStep, substep)); // } // } // } //} return(numUnBoundArgs); }
/// <summary> /// Loads a language from the provided XML document reference. /// </summary> /// <param name="xml">A reference to the transliterations XML document.</param> public void Load(ref XmlDocument xml) { if (!loaded) { XmlNode languageNode=xml.SelectSingleNode(string.Format(languageXPath,name)); XmlNodeList ipaMatches = languageNode.SelectNodes(transcriptionXPath); XmlNodeList romanizationMatches = languageNode.SelectNodes(romanizationXPath); XmlNodeList decompositionMatches = languageNode.SelectNodes(decompositionXPath); foreach (XmlNode m in ipaMatches) { // A little lenient, in that it allows for all or none of these attributes to exist XmlNodeList transcriptionExMatches = m.SelectNodes(transcriptionExXPath); string original = m.GetAttribute("Original"); string replacement = m.GetAttribute("Replacement"); string prefix = m.GetAttribute("Prefix"); string suffix = m.GetAttribute("Suffix"); Transcription t = new Transcription(original, replacement, prefix, suffix); foreach (XmlNode n in transcriptionExMatches) { string exOriginal = n.GetAttribute("Original"); string exReplacement = n.GetAttribute("Replacement"); string exPrefix = n.GetAttribute("Prefix"); string exSuffix = n.GetAttribute("Suffix"); t.AddException(exOriginal, exReplacement, exPrefix, exSuffix); } transcriptions.Add(t); } foreach (XmlNode m in romanizationMatches) { XmlNodeList transliterationMatches = m.SelectNodes(transliterationXPath); string romanizationName = m.GetAttribute("Name"); Romanization r = new Romanization(romanizationName); foreach (XmlNode n in transliterationMatches) { XmlNodeList transliterationExMatches = n.SelectNodes(transliterationExXPath); string original = n.GetAttribute("Original"); string replacement = n.GetAttribute("Replacement"); string prefix = n.GetAttribute("Prefix"); string suffix = n.GetAttribute("Suffix"); Transcription t= new Transcription(original, replacement,prefix,suffix); foreach (XmlNode o in transliterationExMatches) { string exOriginal = o.GetAttribute("Original"); string exReplacement = o.GetAttribute("Replacement"); string exPrefix = o.GetAttribute("Prefix"); string exSuffix = o.GetAttribute("Suffix"); t.AddException(exOriginal, exReplacement, exPrefix, exSuffix); } r.Transliterations.Add(t); } romanizations.Add(r); } foreach (XmlNode m in decompositionMatches) { XmlNodeList prevFactorsMatches = m.SelectNodes(prevFactorsXPath); int offset = int.Parse(m.GetAttribute("Offset")); int modulus = int.Parse(m.GetAttribute("Modulus")); int divisor = int.Parse(m.GetAttribute("Divisor")); int intercept = int.Parse(m.GetAttribute("Intercept")); int order = int.Parse(m.GetAttribute("Order")); int rangeMin = int.Parse(m.GetAttribute("RangeMin")); int rangeMax = int.Parse(m.GetAttribute("RangeMax")); Decomposition d = new Decomposition(offset, modulus, divisor, intercept, order, rangeMin, rangeMax); foreach (XmlNode n in prevFactorsMatches) { int index = int.Parse(n.GetAttribute("Index")); int multiplyBy = int.Parse(n.GetAttribute("MultiplyBy")); d.PrevFactors.Add(index, multiplyBy); } decompositions.Add(d); } } }
public static bool GenerateRevolvedShapeAsset(CSGBrushMeshAsset brushMeshAsset, CSGRevolvedShapeDefinition definition) { definition.Validate(); var surfaces = definition.surfaceAssets; var descriptions = definition.surfaceDescriptions; var shapeVertices = new List <Vector2>(); var shapeSegmentIndices = new List <int>(); GetPathVertices(definition.shape, definition.curveSegments, shapeVertices, shapeSegmentIndices); Vector2[][] polygonVerticesArray; int[][] polygonIndicesArray; if (!Decomposition.ConvexPartition(shapeVertices, shapeSegmentIndices, out polygonVerticesArray, out polygonIndicesArray)) { brushMeshAsset.Clear(); return(false); } // TODO: splitting it before we do the composition would be better var polygonVerticesList = polygonVerticesArray.ToList(); for (int i = polygonVerticesList.Count - 1; i >= 0; i--) { SplitPolygon(polygonVerticesList, i); } var subMeshes = new List <CSGBrushSubMesh>(); var horzSegments = definition.revolveSegments; //horizontalSegments; var horzDegreePerSegment = definition.totalAngle / horzSegments; // TODO: make this work when intersecting rotation axis // 1. split polygons along rotation axis // 2. if edge lies on rotation axis, make sure we don't create infinitely thin quad // collapse this quad, or prevent this from happening // TODO: share this code with torus generator for (int p = 0; p < polygonVerticesList.Count; p++) { var polygonVertices = polygonVerticesList[p]; // var segmentIndices = polygonIndicesArray[p]; var shapeSegments = polygonVertices.Length; var vertSegments = polygonVertices.Length; var descriptionIndex = new int[2 + vertSegments]; descriptionIndex[0] = 0; descriptionIndex[1] = 1; for (int v = 0; v < vertSegments; v++) { descriptionIndex[v + 2] = 2; } var horzOffset = definition.startAngle; for (int h = 1, pr = 0; h < horzSegments + 1; pr = h, h++) { var hDegree0 = (pr * horzDegreePerSegment) + horzOffset; var hDegree1 = (h * horzDegreePerSegment) + horzOffset; var rotation0 = Quaternion.AngleAxis(hDegree0, Vector3.forward); var rotation1 = Quaternion.AngleAxis(hDegree1, Vector3.forward); var subMeshVertices = new Vector3[vertSegments * 2]; for (int v = 0; v < vertSegments; v++) { subMeshVertices[v + vertSegments] = rotation0 * new Vector3(polygonVertices[v].x, 0, polygonVertices[v].y); subMeshVertices[v] = rotation1 * new Vector3(polygonVertices[v].x, 0, polygonVertices[v].y); } var subMesh = new CSGBrushSubMesh(); if (!CreateExtrudedSubMesh(subMesh, vertSegments, descriptionIndex, descriptionIndex, 0, 1, subMeshVertices, surfaces, descriptions)) { continue; } if (!subMesh.Validate()) { brushMeshAsset.Clear(); return(false); } subMeshes.Add(subMesh); } } brushMeshAsset.SubMeshes = subMeshes.ToArray(); brushMeshAsset.CalculatePlanes(); brushMeshAsset.SetDirty(); return(true); }
public void Execute() { float invIterations = 1f / (float)iterationCount; float inverseMass = 1f; // THIS SHOULD VARY BY ATOM! add native array of inversemasses to this overall solver for (var k = 0; k < iterationCount; k++) { for (var j = 0; j < distanceConstraints.Length; j++) { // TODO: could use local refs here to avoid stupid copying var dc = distanceConstraints[j]; var a = predicteds[dc.i0]; var b = predicteds[dc.i1]; var delta = a - b; var direction = math.normalize(delta); var C = math.length(delta) - dc.distance; var dstiffness = 1f - math.pow(1f - dc.stiffness, invIterations); if (C > -float.Epsilon && C < float.Epsilon) { continue; } predicteds[dc.i0] -= inverseMass / (inverseMass + inverseMass) * dstiffness * C * direction; predicteds[dc.i1] += inverseMass / (inverseMass + inverseMass) * dstiffness * C * direction; } for (var j = 0; j < shapeConstraints.Length; j++) { ShapeConstraint sc = shapeConstraints[j]; float dstiffness = 1f - Mathf.Pow(1f - sc.stiffness, invIterations); float totalMass = 0f; float3 centerOfMass = Vector3.zero; for (var i = sc.start; i < sc.end; i++) { centerOfMass += predicteds[i] * inverseMass; totalMass += inverseMass; } centerOfMass /= totalMass; // compute rest matrix float a00 = 0f; float a01 = 0f; float a02 = 0f; float a10 = 0f; float a11 = 0f; float a12 = 0f; float a20 = 0f; float a21 = 0f; float a22 = 0f; for (var i = sc.start; i < sc.end; i++) { float3 q = restPositions[i]; float3 p = predicteds[i] - centerOfMass; a00 += inverseMass * p.x * q.x; a01 += inverseMass * p.x * q.y; a02 += inverseMass * p.x * q.z; a10 += inverseMass * p.y * q.x; a11 += inverseMass * p.y * q.y; a12 += inverseMass * p.y * q.z; a20 += inverseMass * p.z * q.x; a21 += inverseMass * p.z * q.y; a22 += inverseMass * p.z * q.z; } float3x3 currentMatrix = new float3x3( a00, a01, a02, a10, a11, a12, a20, a21, a22 ); float3x3 covarianceMatrix = math.mul(currentMatrix, sc.inverseMassMatrix); float3x3 rotationMatrix = Decomposition.FastExtractRotationFrom(covarianceMatrix, 10); for (var i = sc.start; i < sc.end; i++) { float3 goal = centerOfMass + math.mul(rotationMatrix, restPositions[i]); predicteds[i] += (goal - predicteds[i]) * sc.stiffness * dstiffness; } } for (var i = 0; i < predicteds.Length; i++) { if (predicteds[i].y > 0) { continue; } var aboveGround = predicteds[i]; aboveGround.y = 0; predicteds[i] = aboveGround; } for (var j = 0; j < positionConstraints.Length; j++) { // TODO: could use local refs here to avoid stupid copying var pc = positionConstraints[j]; predicteds[pc.i] = pc.position; } } }
public static Decomposition TravelByCar() { // (: action travel - by - car // :parameters(?person - person ? from ? to - place) //:precondition(and(at ? person ? from)(not(= ? from ? to))) // :effect(and(at ? person ? to) // (not(at ? person ? from))) //:decomp( // :sub -params (? car - car ? s1 ? s2 ? s3 - step) // :requirements(and // (= ? s1(get -in -car ? person ? car ? from)) // (= ? s2(drive ? person ? car ? from ? to)) // (= ? s3(get -out -of - car ? person ? car ? to)) // (linked - by ? s1 ? s2(in ? person ? car)) // (linked - by ? s1 ? s3(in ? person ? car)) // (linked - by ? s2 ? s3(at ? car ? to))))) // Params var objTerms = new List <ITerm>() { new Term("?person") { Type = "person" }, new Term("?from") { Type = "place" }, new Term("?to") { Type = "place" }, new Term("?car") { Type = "car" } }; var litTerms = new List <IPredicate>(); var s1terms = new List <ITerm>() { objTerms[0], objTerms[3], objTerms[1] }; var s2terms = new List <ITerm>() { objTerms[0], objTerms[3], objTerms[1], objTerms[2] }; var s3terms = new List <ITerm>() { objTerms[0], objTerms[3], objTerms[2] }; var getInCar = new PlanStep(new Operator(new Predicate("get-in-car", s1terms, true))); var drive = new PlanStep(new Operator(new Predicate("drive", s2terms, true))); var getOutOfCar = new PlanStep(new Operator(new Predicate("get-out-of-car", s3terms, true))); var inPersonCar = new Predicate("in", new List <ITerm>() { objTerms[0], objTerms[3] }, true); var atCarTo = new Predicate("at", new List <ITerm>() { objTerms[3], objTerms[2] }, true); //new Operator() var substeps = new List <IPlanStep>() { getInCar, drive, getOutOfCar }; var sublinks = new List <CausalLink <IPlanStep> >() { new CausalLink <IPlanStep>(inPersonCar, getInCar, drive), new CausalLink <IPlanStep>(inPersonCar, getInCar, getOutOfCar), new CausalLink <IPlanStep>(atCarTo, drive, getOutOfCar) }; var suborderings = new List <BoltFreezer.Utilities.Tuple <IPlanStep, IPlanStep> >() { new BoltFreezer.Utilities.Tuple <IPlanStep, IPlanStep>(getInCar, drive), new BoltFreezer.Utilities.Tuple <IPlanStep, IPlanStep>(drive, getOutOfCar) }; var root = new Operator(new Predicate("travel-by-car", objTerms, true)); var decomp = new Decomposition(root, litTerms, substeps, suborderings, sublinks); return(decomp); }
static void Main(string[] args) { //последовательный алгоритм(Алгоритм 1.0) Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine(" Последовательный алгоритм"); Console.ResetColor(); Console.WriteLine("-------------------------------------------------------------------------------------"); Sequential.Start(); //Декомпозиция по файлам //параллельный алгоритм(Алгоритм 1.1-локальный буффер) Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine(" Параллельный алгоритм(Локальный буффер)"); Console.ResetColor(); Console.WriteLine("-------------------------------------------------------------------------------------"); Local thr2 = new Local(2); thr2.Start(); Local thr4 = new Local(4); thr4.Start(); Local thr6 = new Local(6); thr6.Start(); Local thr8 = new Local(8); thr8.Start(); Local thr10 = new Local(10); thr10.Start(); Local thr12 = new Local(12); thr12.Start(); //параллельный алгоритм(Алгоритм 1.2-глобальный буффер) Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine(" Параллельный алгоритм(Глобальный буффер)"); Console.ResetColor(); Console.WriteLine("-------------------------------------------------------------------------------------"); Global dthr2 = new Global(2); dthr2.Start(); Global dthr4 = new Global(4); dthr4.Start(); Global dthr6 = new Global(6); dthr6.Start(); Global dthr8 = new Global(8); dthr8.Start(); Global dthr10 = new Global(10); dthr10.Start(); Global dthr12 = new Global(12); dthr12.Start(); //Декомпозиция по задачам //параллельный алгоритм(Алгоритм 2.0) Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine(" Параллельный алгоритм(Декомпозиция по задачам)"); Console.ResetColor(); Console.WriteLine("-------------------------------------------------------------------------------------"); Decomposition dec2 = new Decomposition(1,1); dec2.Start(); Decomposition dec4 = new Decomposition(2,2); dec4.Start(); Decomposition dec6 = new Decomposition(3,3); dec6.Start(); Decomposition dec8 = new Decomposition(4, 4); dec8.Start(); Decomposition dec10 = new Decomposition(5, 5); dec10.Start(); Decomposition dec12 = new Decomposition(6, 6); dec12.Start(); Console.ReadKey(); }
internal static void ShowCharsWithComponent_SidePanel(char character) { Decomposition.GetCharactersWithComponent(character.ToString()).Update_ShownCharsWithComponent(character); }
public static Decomposition TravelByPlane() { // (: action travel - by - plane // :parameters(?person - person ? from ? to - place) //:precondition(and(at ? person ? from)(not(= ? from ? to))) // :effect(and(at ? person ? to) // (not(at ? person ? from))) //:decomp( // :sub -params (? plane - plane // ? s1 ? s2 ? s3 ? s4 - step) // :requirements(and // (= ? s1(buy - tickets ? person)) // (= ? s2(board - plane ? person ? plane ? from)) // (= ? s3(fly ? person ? plane ? from ? to)) // (= ? s4(deplane ? person ? plane ? to)) // (linked - by ? s1 ? s2(has - ticket ? person)) // (linked - by ? s2 ? s3(in ? person ? plane)) // (linked - by ? s2 ? s4(in ? person ? plane)) // (linked - by ? s3 ? s4(at ? plane ? to))))) // Params var objTerms = new List <ITerm>() { new Term("?person") { Type = "person" }, new Term("?from") { Type = "place" }, new Term("?to") { Type = "place" }, new Term("?plane") { Type = "plane" } }; var litTerms = new List <IPredicate>(); var buyTerms = new List <ITerm>() { objTerms[0] }; var boardTerms = new List <ITerm>() { objTerms[0], objTerms[3], objTerms[1] }; var flyTerms = new List <ITerm>() { objTerms[0], objTerms[3], objTerms[1], objTerms[2] }; var deplaneTerms = new List <ITerm>() { objTerms[0], objTerms[3], objTerms[2] }; var buy = new PlanStep(new Operator(new Predicate("buy", buyTerms, true))); var board = new PlanStep(new Operator(new Predicate("board", boardTerms, true))); var fly = new PlanStep(new Operator(new Predicate("fly", flyTerms, true))); var deplane = new PlanStep(new Operator(new Predicate("deplane", deplaneTerms, true))); var hasTicketPerson = new Predicate("has-ticket", new List <ITerm>() { objTerms[0] }, true); var inPersonPlane = new Predicate("in", new List <ITerm>() { objTerms[0], objTerms[3] }, true); var atPlaneTo = new Predicate("at", new List <ITerm>() { objTerms[3], objTerms[2] }, true); //new Operator() var substeps = new List <IPlanStep>() { buy, board, fly, deplane }; var sublinks = new List <CausalLink <IPlanStep> >() { new CausalLink <IPlanStep>(hasTicketPerson, buy, board), new CausalLink <IPlanStep>(inPersonPlane, board, fly), new CausalLink <IPlanStep>(inPersonPlane, board, deplane), new CausalLink <IPlanStep>(atPlaneTo, fly, deplane) }; var suborderings = new List <BoltFreezer.Utilities.Tuple <IPlanStep, IPlanStep> >() { new BoltFreezer.Utilities.Tuple <IPlanStep, IPlanStep>(buy, board), new BoltFreezer.Utilities.Tuple <IPlanStep, IPlanStep>(board, fly), new BoltFreezer.Utilities.Tuple <IPlanStep, IPlanStep>(fly, deplane) }; var root = new Operator(new Predicate("travel-by-plane", objTerms, true)); var decomp = new Decomposition(root, litTerms, substeps, suborderings, sublinks); return(decomp); }
public static Decomposition MultiMove() { // Params var objTerms = new List <ITerm>() { new Term("?agent") { Type = "steeringagent" }, //0 new Term("?from") { Type = "location" }, //1 new Term("?to") { Type = "location" }, //2 new Term("?intermediate") { Type = "location" } //3 }; var litTerms = new List <IPredicate>(); var atAgentOrigin = new Predicate("at", new List <ITerm>() { objTerms[0], objTerms[1] }, true); var atAgentInt = new Predicate("at", new List <ITerm>() { objTerms[0], objTerms[3] }, true); var atAgentDest = new Predicate("at", new List <ITerm>() { objTerms[0], objTerms[2] }, true); var move1 = new PlanStep(new Operator("", new List <IPredicate>() { atAgentOrigin }, new List <IPredicate> { atAgentInt })); var move2 = new PlanStep(new Operator("", new List <IPredicate>() { atAgentInt }, new List <IPredicate> { atAgentDest })); var substeps = new List <IPlanStep>() { move1, move2 }; var sublinks = new List <CausalLink <IPlanStep> >() { new CausalLink <IPlanStep>(atAgentInt, move1, move2) }; var suborderings = new List <Tuple <IPlanStep, IPlanStep> >() { new Tuple <IPlanStep, IPlanStep>(move1, move2) }; var root = new Operator(new Predicate("multimove", objTerms, true)); var decomp = new Decomposition(root, litTerms, substeps, suborderings, sublinks) { NonEqualities = new List <List <ITerm> >() { new List <ITerm>() { objTerms[1], objTerms[2] }, new List <ITerm>() { objTerms[2], objTerms[3] }, new List <ITerm>() { objTerms[1], objTerms[3] } } }; return(decomp); }
public static Decomposition Transport() { // Params var objTerms = new List <ITerm>() { new Term("?agent") { Type = "steeringagent" }, //0 new Term("?item") { Type = "block" }, //1 new Term("?from") { Type = "location" }, //2 new Term("?to") { Type = "location" }, //3 new Term("?adjacentfrom") { Type = "location" }, //4 new Term("?adjacentto") { Type = "location" } //5 }; var litTerms = new List <IPredicate>(); // pickup (?taker - agent ?block - block ?location - location ?takerLocation - location) var pickupterms = new List <ITerm>() { objTerms[0], objTerms[1], objTerms[2], objTerms[4] }; // This guaranteed move //var moveterms = new List<ITerm>() { objTerms[0], objTerms[4], objTerms[5] }; //(?putter - agent ?thing - block ?agentlocation - location ?newlocation - location) var putdownterms = new List <ITerm>() { objTerms[0], objTerms[1], objTerms[5], objTerms[3] }; var pickup = new PlanStep(new Operator(new Predicate("pickup", pickupterms, true))); // var travelOp = new Operator("", new List<IPredicate>(), new List<IPredicate>(){ atPersonTo}); var putdown = new PlanStep(new Operator(new Predicate("putdown", putdownterms, true))); var atAgentOrigin = new Predicate("at", new List <ITerm>() { objTerms[0], objTerms[4] }, true); var hasAgentThing = new Predicate("has", new List <ITerm>() { objTerms[0], objTerms[1] }, true); var atAgentDest = new Predicate("at", new List <ITerm>() { objTerms[0], objTerms[5] }, true); var move = new PlanStep(new Operator("", new List <IPredicate>() { atAgentOrigin }, new List <IPredicate> { atAgentDest })); //new Operator() var substeps = new List <IPlanStep>() { pickup, move, putdown }; var sublinks = new List <CausalLink <IPlanStep> >() { // new CausalLink<IPlanStep>(atAgentOrigin, pickup, move), new CausalLink <IPlanStep>(hasAgentThing, pickup, putdown), new CausalLink <IPlanStep>(atAgentDest, move, putdown), }; var suborderings = new List <Tuple <IPlanStep, IPlanStep> >() { new Tuple <IPlanStep, IPlanStep>(pickup, move), new Tuple <IPlanStep, IPlanStep>(move, putdown) }; var root = new Operator(new Predicate("transport", objTerms, true)); var decomp = new Decomposition(root, litTerms, substeps, suborderings, sublinks) { NonEqualities = new List <List <ITerm> >() { new List <ITerm>() { objTerms[2], objTerms[3] }, new List <ITerm>() { objTerms[2], objTerms[4] }, new List <ITerm>() { objTerms[3], objTerms[5] } } }; return(decomp); }
protected override void OnSpawn() { base.OnSpawn(); reactable = Decomposition.CreateRottenReactable(gameObject); GetComponent <KSelectable>().AddStatusItem(Db.Get().DuplicantStatusItems.Rotten); }
public static bool GenerateExtrudedShapeAsset(CSGBrushMeshAsset brushMeshAsset, Curve2D shape, Path path, int curveSegments, CSGSurfaceAsset[] surfaceAssets, ref SurfaceDescription[] surfaceDescriptions) { var shapeVertices = new List <Vector2>(); var shapeSegmentIndices = new List <int>(); GetPathVertices(shape, curveSegments, shapeVertices, shapeSegmentIndices); Vector2[][] polygonVerticesArray; int[][] polygonIndicesArray; if (!Decomposition.ConvexPartition(shapeVertices, shapeSegmentIndices, out polygonVerticesArray, out polygonIndicesArray)) { return(false); } // TODO: make each extruded quad split into two triangles when it's not a perfect plane, // split it to make sure it's convex // TODO: make it possible to smooth (parts) of the shape // TODO: make materials work well // TODO: make it possible to 'draw' shapes on any surface // TODO: make path work as a spline, with subdivisions // TODO: make this work well with twisted rotations // TODO: make shape/path subdivisions be configurable / automatic var subMeshes = new List <CSGBrushSubMesh>(); for (int p = 0; p < polygonVerticesArray.Length; p++) { var polygonVertices = polygonVerticesArray[p]; var segmentIndices = polygonIndicesArray[p]; var shapeSegments = polygonVertices.Length; for (int s = 0; s < path.segments.Length - 1; s++) { var pathPointA = path.segments[s]; var pathPointB = path.segments[s + 1]; int subSegments = 1; var offsetQuaternion = pathPointB.rotation * Quaternion.Inverse(pathPointA.rotation); var offsetEuler = offsetQuaternion.eulerAngles; if (offsetEuler.x > 180) { offsetEuler.x = 360 - offsetEuler.x; } if (offsetEuler.y > 180) { offsetEuler.y = 360 - offsetEuler.y; } if (offsetEuler.z > 180) { offsetEuler.z = 360 - offsetEuler.z; } var maxAngle = Mathf.Max(offsetEuler.x, offsetEuler.y, offsetEuler.z); if (maxAngle != 0) { subSegments = Mathf.Max(1, (int)Mathf.Ceil(maxAngle / 5)); } if ((pathPointA.scale.x / pathPointA.scale.y) != (pathPointB.scale.x / pathPointB.scale.y) && (subSegments & 1) == 1) { subSegments += 1; } for (int n = 0; n < subSegments; n++) { var matrix0 = PathPoint.Lerp(ref path.segments[s], ref path.segments[s + 1], n / (float)subSegments); var matrix1 = PathPoint.Lerp(ref path.segments[s], ref path.segments[s + 1], (n + 1) / (float)subSegments); // TODO: this doesn't work if top and bottom polygons intersect // => need to split into two brushes then, invert one of the two brushes var invertDot = Vector3.Dot(matrix0.MultiplyVector(Vector3.forward).normalized, (matrix1.MultiplyPoint(shapeVertices[0]) - matrix0.MultiplyPoint(shapeVertices[0])).normalized); if (invertDot == 0.0f) { continue; } Vector3[] vertices; if (invertDot < 0) { var m = matrix0; matrix0 = matrix1; matrix1 = m; } if (!GetExtrudedVertices(polygonVertices, matrix0, matrix1, out vertices)) { continue; } var subMesh = new CSGBrushSubMesh(); CreateExtrudedSubMesh(subMesh, shapeSegments, segmentIndices, 0, 1, vertices, surfaceAssets, surfaceDescriptions); subMeshes.Add(subMesh); } } } brushMeshAsset.SubMeshes = subMeshes.ToArray(); brushMeshAsset.CalculatePlanes(); brushMeshAsset.OnValidate(); brushMeshAsset.SetDirty(); return(true); }
public static Tuple <Dictionary <int, Orient>, Dictionary <int, string> > GetOrientsAndLocations(Decomposition decomp, Dictionary <string, Vector3> locationMap) { var orientDict = new Dictionary <int, Orient>(); var locationDict = new Dictionary <int, string>(); foreach (var substep in decomp.SubSteps) { var orientEnum = MapToNearestOrientation(substep as PlanStep, locationMap); orientDict[substep.ID] = orientEnum; string earliestTermHack = ""; foreach (var term in substep.Terms) { if (term.Type.Equals("Location")) { earliestTermHack = term.Constant; break; } } locationDict[substep.ID] = earliestTermHack; } return(new Tuple <Dictionary <int, Orient>, Dictionary <int, string> >(orientDict, locationDict)); }