//builds all the appropriate transportation segments in the surface unit /* private void buildTransport(SurfaceUnit su) * { * //Debug.Log("what??"); * //find transport segments(roads) to generate * //SurfaceUnit startTU = UnitConverter.SPtoSP( * //surface unit to start the loop in * * //start and ends in the loop * //convert the top right and bottom right corners of the su to the transport units they lie in * int tuStartu = SUtoTU(su.u); * int tuStartv = SUtoTU(su.v); * int tuEndu = SUtoTU(su.u+1); * int tuEndv = SUtoTU(su.v+1); * * //Debug.Log(tuStartu + " " + tuStartv + " " + tuEndu + " " + tuEndv); * * for(int i = tuStartu-1; i<=tuEndu; i++) * { * for(int j = tuStartv-1; j<=tuEndv; j++) * { * //build the road units * //Debug.Log("looping"); * //the trasport unit to examine * TUBase bu = transport.getBase(new SurfaceUnit(su.side, i, j)); * //Debug.Log("where's my road?!?!?!?!?"); * //Debug.Log(bu==null); * if(bu!=null) * { * if(bu.conRight) * { * //the transport unit to the right of this one * TUBase bu2 = transport.getBase(new SurfaceUnit(su.side, i+1, j)); * * if(bu2!=null)//only build it if both base units exist * buildTransportSegment(bu,bu2,bu.RightLev); * } * if(bu.conUp) * { * //the transport unit above this one * TUBase bu2 = transport.getBase(new SurfaceUnit(su.side, i, j+1)); * if(bu2!=null) * buildTransportSegment(bu,bu2,bu.UpLev); * } * if(bu.conUpRight) * { * //the transport unit above this one * TUBase bu2 = transport.getBase(new SurfaceUnit(su.side, i+1, j+1)); * if(bu2!=null) * buildTransportSegment(bu,bu2,bu.UpRightLev); * } * if(bu.conUpLeft) * { * //the transport unit above this one * TUBase bu2 = transport.getBase(new SurfaceUnit(su.side, i-1, j+1)); * if(bu2!=null) * buildTransportSegment(bu,bu2,bu.UpLeftLev); * } * * } * } * } * }*/ //if the surface unit given is out of range of the side it should be on, the proper side and coordinates are returned //it will probably be the same public SurfaceUnit sideCheck(SurfaceUnit su, int sideLength) { //half the side length int halfside = sideLength / 2; //if it is withing the bounds of a side(usually the case), it does not have to be modified if (su.u >= -halfside && su.u < halfside && su.v >= -halfside && su.v < halfside) { return(su); } //all cases for back side if (su.side == PSide.BACK) { //if the u value is to far to the right, it is on the very left of the right side if (su.u >= halfside) { return(new SurfaceUnit(PSide.RIGHT, -halfside, su.v)); } } else if (su.side == PSide.RIGHT) { //if the u value is to far to the right, it is on the very left of the right side if (su.u < halfside) { return(new SurfaceUnit(PSide.BACK, halfside - 1, su.v)); } } //if no other conditions are met, just return an empty one return(new SurfaceUnit(PSide.NONE, 0, 0)); }
//returns the adjusted version of a mid unit accounting for side rotation //returns the unit in the dir direction relative to the given su public TransportUnit getAdjustedMid(SurfaceUnit su) { //half the side length int halfside = midperglob / 2; //if it is withing the bounds of a side(usually the case), it does not have to be modified if (su.u >= -halfside && su.u < halfside && su.v >= -halfside && su.v < halfside) { return(getMid(su)); } //all cases for back side if (su.side == PSide.BACK) { //if the u value is to far to the right, it is on the very left of the right side if (su.u >= halfside) { return(getMid(new SurfaceUnit(PSide.RIGHT, -halfside, su.v))); } } else if (su.side == PSide.RIGHT) { //if the u value is to far to the right, it is on the very left of the right side if (su.u < halfside) { return(getMid(new SurfaceUnit(PSide.BACK, halfside - 1, su.v))); } } //if no other conditions are met, just return null return(null); }
//returns the large unit at a specified su, creates one if it does not exist(every large unit will exist) public TULarge getLarge(SurfaceUnit su) { //quick hopefully temporary check, see getMid for details if (su.u < -halfgtuw || su.u >= halfgtuw || su.v < -halfgtuw || su.v >= halfgtuw) { return(null); } TULarge lu = null; //if it is in the list, return it if (largeTUs.TryGetValue(su, out lu)) { return(lu); } //if not, build one and return it TULarge tu = new TULarge(); //get this large unit's rng tu.rng = RandomHandler.transportRandom(su, TLev.LARGE); tu.conPoint = new Vector2((su.u + (float)tu.rng.NextDouble()) * sideLengthLarge, (su.v + (float)tu.rng.NextDouble()) * sideLengthLarge); tu.conUp = true; tu.conRight = true; tu.indexI = su.u; tu.indexJ = su.v; largeTUs.Add(su, tu); return(tu); }
//returns the mid unit at the specified su or null if one does not exist public TransportUnit getMid(SurfaceUnit su) { //quick check to see if this mid is out of range on the side //later it will be transformed into a unit of other side in order to connect sides if (su.u < -halfmidperglob || su.u >= halfmidperglob || su.v < -halfmidperglob || su.v >= halfmidperglob) { return(null); } TransportUnit mu = null; //if it is in the mid list, return it if (midTUs.TryGetValue(su, out mu)) { return(mu); } //if it's not in the mid list, check if a large unit will contain it //the coordinates of the proposed large unit SurfaceUnit lus = getLargeSU(su); //retrieve the large unit TULarge lu = getLarge(lus); //Debug.Log("proposed " + lus); //if the lu has already been populated, the mu will never exist, so return null if (lu.populated) { return(null); } else { populateLarge(lu, lus); //populate it with mid units(later will be moved to a separate function) /* int startu = lus.u*largeTUWidth; * int startv = lus.v*largeTUWidth; * //loop through all mid units in the large unit and create them * for(int i = startu; i<startu+largeTUWidth; i++) * { * for(int j = startv; j<startv+largeTUWidth; j++) * { * //create a new base unit, set its properties, and add it to the base list * TransportUnit newTU = new TransportUnit(); * newTU.conUp = true;//Random.value>0.5f; * newTU.conRight = true;//Random.value>0.5f; * newTU.indexI = i; * newTU.indexJ = j; * newTU.conPoint = new Vector2((i+0.5f)*midTUWidth + Random.value-0.5f,(j+0.5f)*midTUWidth + Random.value-0.5f); * //newTU.conPoint = new Vector2((i+0.5f)*midTUWidth,(j+0.5f)*midTUWidth); * //newTU.conPoint = new Vector2((i+Random.value)*midTUWidth,(j+Random.value)*midTUWidth); * midTUs.Add(new SurfaceUnit(su.side, i, j), newTU); * } * }*/ lu.populated = true; //use recursion to return to the top of the function and return the newly created(or not) mid unit return(getMid(su)); } }
//returns the mid unit from midTUs at index u,v and creates one if necessary private TransportUnit buildMid(int i, int j, PSide side) { TransportUnit mu = null; SurfaceUnit su = new SurfaceUnit(side, i, j); //Debug.Log(su); if (!midTUs.TryGetValue(su, out mu)) { mu = new TransportUnit(); mu.indexI = i; mu.indexJ = j; midTUs.Add(su, mu); indexList.Add(mu); } return(mu); }
public Dictionary <SurfaceUnit, TUBase> populate(TransportUnit mu, SurfaceUnit su) { //nullify baseList so it can be reused for this mid unit baseList = null; midU = mu; //an array of base transport units that will eventually be returned //baseList = new TransportUnit[midTUWidth, midTUWidth]; baseList = new Dictionary <SurfaceUnit, TUBase>(); midU = mu; baseIndexI = midU.indexI * midTUWidth; baseIndexJ = midU.indexJ * midTUWidth; fill(mu, su); return(baseList); }
//deletes all obects in a surface unit if no more world units are in it public void deleteSurface(SurfaceUnit su) { SurfaceHolder sh = null; surfList.TryGetValue(su, out sh); sh.wuCount--; //if there are no more world units that exist in the surface unit, delete the surface unit and all objects in it if (sh.wuCount == 0) { foreach (WorldObject wo in sh.objects) { Build.destroyObject(wo); } surfList.Remove(su); } }
//returns the base unit from baseList at index u,v and creates one if necessary private TUBase getBase(int i, int j) { /*if(baseList[i,j] == null) * baseList[i,j] = new TransportUnit(); * * return baseList[i,j];*/ TUBase bu = null; SurfaceUnit su = new SurfaceUnit(PSide.NONE, i, j); //Debug.Log(su); if (!baseList.TryGetValue(su, out bu)) { bu = new TUBase(); bu.indexI = i; bu.indexJ = j; //tran.baseTUs.Add(su, bu); baseList.Add(su, bu); } return(bu); }
protected override SurfaceUnit __DoSubstraction(SurfaceUnit right) { return new Metre2(Value - right.Value); }
protected override SurfaceUnit __DoAddition(SurfaceUnit right) { return new Metre2(Value + right.Value); }
//returns an rng for each transport unit public static System.Random transportRandom(SurfaceUnit su, TLev lev) { System.Random rand = new System.Random((int)hash.GetHash(su.u, su.v, (int)su.side, (int)lev, 1)); return(rand); }
//returns an rng for each surface unit public static System.Random surfaceRandom(SurfaceUnit su) { //system.random takes a seed that is calculated from the hash function //1 is the planet num, will eventually need a way to calculate this return(new System.Random((int)hash.GetHash(su.u, su.v, (int)su.side, 1))); }
//will return a TransportUnit object from the requested a base unit //OH YES THIS USES RECURSION OH MAN!!!!!!!!!!!!!!!! I'M SO PROUD OF MYSELF!!!!! public TUBase getBase(SurfaceUnit su) { //quick test check, see getMid\ if (su.u < -halfSideLength || su.u >= halfSideLength || su.v < -halfSideLength || su.v >= halfSideLength) { return(null); } //if(su.side==PSide.NONE) // return null; //the base unit to be returned eventually TUBase bu = null; //if the base unit exists in the list, return it if (baseTUs.TryGetValue(su, out bu)) { return(bu); } //if the base unit is not in the list, check if a mid unit is //the coordinates of the mid unit SurfaceUnit mus = getMidSU(su); //retrieve the actual mid unit (or not if it will never exist) TransportUnit mu = getMid(mus); //if the mid unit will never exist, the base unit will never exist if (mu == null) { return(null); } //if the mu has already been populated, the base unit will never exist if (mu.populated) { return(null); } else { //populate it /*int startu = mus.u*midTUWidth; * int startv = mus.v*midTUWidth; * for(int i = startu; i<startu+midTUWidth; i++) * { * for(int j = startv; j<startv+midTUWidth; j++) * { * //create a new base unit, set its properties, and add it to the base list * TUBase newTU = new TUBase(); * newTU.conUp = Random.value>0.5f; * newTU.conRight = Random.value>0.5f; * newTU.conPoint = new Vector2(i + Random.value, j + Random.value); * newTU.conPointWorld = UnitConverter.getWP(new SurfacePos(su.side, newTU.conPoint.x, newTU.conPoint.y), * WorldManager.curPlanet.radius, sideLength); * * baseTUs.Add(new SurfaceUnit(su.side, i, j), newTU); * } * }*/ Dictionary <SurfaceUnit, TUBase> bases = midfill.populate(mu, mus); foreach (KeyValuePair <SurfaceUnit, TUBase> pair in bases) { //Debug.Log(su.side+" " + pair.Key.u + " " + pair.Key.v); SurfaceUnit newKey = new SurfaceUnit(su.side, pair.Key.u, pair.Key.v); //if the key is not already in the list, add it if (!baseTUs.ContainsKey(newKey)) { //find the world connection point Vector3 conPointWorld = UnitConverter.getWP(new SurfacePos(su.side, pair.Value.conPoint.x, pair.Value.conPoint.y), UniverseSystem.curPlanet.radius, sideLength); conPointWorld = planet.noise.altitudePos(conPointWorld); //Debug.Log(su.side+" " + pair.Key.u + " " + pair.Key.v + " "); pair.Value.conPointWorld = conPointWorld; baseTUs.Add(newKey, pair.Value); } //Debug.Log(pair.Key); } mu.populated = true; //use recursion to return to the top of the function and get the base unit from the list(or not if it was not generated) return(getBase(su)); } }
//populates a large unit with mid units private void populateLarge(TULarge lu, SurfaceUnit lus) { //Debug.Log("built " + lus); //clear the index list indexList.Clear(); //find the mid unit that the large unit's conpoint falls in int powIndexX, powIndexY; GridMath.findMidIndexfromPoint(lu.conPoint, midTUWidth, out powIndexX, out powIndexY); TransportUnit powMid = buildMid(powIndexX, powIndexY, lus.side); powMid.conPoint = lu.conPoint; //same conpoint, or could change to not be, doesn't really matter powMid.conSet = true; TULarge rightLU = getLarge(new SurfaceUnit(lus.side, lus.u + 1, lus.v)); TULarge leftLU = getLarge(new SurfaceUnit(lus.side, lus.u - 1, lus.v)); TULarge upLU = getLarge(new SurfaceUnit(lus.side, lus.u, lus.v + 1)); TULarge downLU = getLarge(new SurfaceUnit(lus.side, lus.u, lus.v - 1)); //Vector2 conPointRight = rightLU.conPoint; //determine in which direction the streets should be built bool conRight = lu.conRight; bool conLeft = false; bool conUp = lu.conUp; bool conDown = false; //check for null large units if (leftLU != null) { conLeft = leftLU.conRight; } if (downLU != null) { conDown = downLU.conUp; } //list of the index of all the mid transport units that are connected in some way if (conRight) { buildMidCurve(lu, rightLU.conPoint, Dir.RIGHT, powMid, lus.side); } if (conLeft) { buildMidCurve(lu, leftLU.conPoint, Dir.LEFT, powMid, lus.side); } if (conUp) { buildMidCurve(lu, upLU.conPoint, Dir.UP, powMid, lus.side); } if (conDown) { buildMidCurve(lu, downLU.conPoint, Dir.DOWN, powMid, lus.side); } //build some level 2 streets coming off the level 1 streets or other level 2 streets int numStreets = 80; //(int)(Random.value*5); for (int i = 0; i < numStreets; i++) { int startNum = lu.rng.Next(0, indexList.Count); TransportUnit startMid = indexList[startNum]; buildLev2(lu, startMid, lu.rng.Next(2, 80), lus.side); } Vector3 topright = UnitConverter.getWP(new SurfacePos(lus.side, (lu.indexI + 1) * sideLengthLarge, (lu.indexJ + 1) * sideLengthLarge), 10000, sideLength); Vector3 topleft = UnitConverter.getWP(new SurfacePos(lus.side, (lu.indexI) * sideLengthLarge, (lu.indexJ + 1) * sideLengthLarge), 10000, sideLength); Vector3 botright = UnitConverter.getWP(new SurfacePos(lus.side, (lu.indexI + 1) * sideLengthLarge, (lu.indexJ) * sideLengthLarge), 10000, sideLength); Vector3 botleft = UnitConverter.getWP(new SurfacePos(lus.side, (lu.indexI) * sideLengthLarge, (lu.indexJ) * sideLengthLarge), 10000, sideLength); Debug.DrawLine(topleft, botleft, Color.red, Mathf.Infinity); Debug.DrawLine(topleft, topright, Color.red, Mathf.Infinity); Debug.DrawLine(topright, botright, Color.red, Mathf.Infinity); Debug.DrawLine(botright, botleft, Color.red, Mathf.Infinity); lu.populated = true; }
//returns the coordinates of a large unit that contain the mid unit whose coordinates are given private SurfaceUnit getLargeSU(SurfaceUnit msu) { return(new SurfaceUnit(msu.side, Mathf.FloorToInt((float)msu.u / largeTUWidth), Mathf.FloorToInt((float)msu.v / largeTUWidth))); }
//returns the coordinates of a mid unit that contain the base unit whose coordinates are given private SurfaceUnit getMidSU(SurfaceUnit bsu) { return(new SurfaceUnit(bsu.side, Mathf.FloorToInt((float)bsu.u / midTUWidth), Mathf.FloorToInt((float)bsu.v / midTUWidth))); }
//a working name //builds all the objects in a certain surface unit //or if it already exists, increase its wuCount public void CreateSurfaceObjects(SurfaceUnit su) { //creates an empty surface holder SurfaceHolder sh = null; //Debug.Log (su); //only make the objects in this unit if it has not already been generated //and add it to the list so it is not generated again if (!surfList.TryGetValue(su, out sh)) { sh = new SurfaceHolder(); curSH = sh; //connect class wide reference surfList.Add(su, sh); //instance a random number generator with seed based on the su position sent through a hash function //NOTE: the last 1 parameter is used as a kind of planet identifier, but this may not be needed //System.Random rand = new System.Random((int)WorldManager.hash.GetHash(su.u, su.v, (int)su.side, 1)); System.Random rand = RandomHandler.surfaceRandom(su); //NOTE: all objects that are in the rect list are always in the radial list //create a list of radial collisions //(x,y,radius) List <RadialCol> radCols = new List <RadialCol>(); //create a list of rectangular collisions //List<Vector4> rectCols = new List<Vector4>(); //first add all roads, then buildings, then natural things //build all transportation segments and add them to the collision lists //buildTransport(su); //create a list of samples List <Sub> samples = new List <Sub>(); for (int i = 0; i < numSamples; i++) { SurfacePos surfPos = new SurfacePos(su.side, su.u + (float)rand.NextDouble(), su.v + (float)rand.NextDouble()); //convert the surface position to world position Vector3 worldPos = UnitConverter.getWP(surfPos, radius, sideLength); //TODO: make function to only retrieve the substance and not vox val float val; Sub sub; planet.noise.getVoxData(worldPos, out val, out sub); //Debug.Log(sub); samples.Add(sub); } foreach (Blueprint bp in blueprints) { int amount = bp.getAmount(samples, new WorldPos(), rand.NextDouble()); for (int i = 0; i < amount; i++) { //possibly later method to build all object in this su within the blueprint class and return a list //WorldObject wo = bp.buildObject(rand); Mesh mesh = bp.buildObject(rand.Next()); //choose random x and y position within the su float u = (float)rand.NextDouble(); float v = (float)rand.NextDouble(); //choose random rotation(will not be random for things like buildings later) Quaternion surfRot = Quaternion.Euler((float)rand.NextDouble() * 360, (float)rand.NextDouble() * 360, (float)rand.NextDouble() * 360); //the global surfaceposition of the object SurfacePos surfPos = new SurfacePos(su.side, su.u + u, su.v + v); //convert the surface position and rotation to world position and rotation Vector3 worldPos = UnitConverter.getWP(surfPos, radius, sideLength); Quaternion worldRot = getWorldRot(worldPos, surfRot, su.side); //adjust from point on sphere to correct altitude worldPos = planet.noise.altitudePos(worldPos); //build(intantiate) the actual gameobject MobileObjects wo = Build.buildObject <Rock>(worldPos, worldRot); //wo.setReferences(); wo.Render(); wo.setMesh(mesh); sh.objects.Add(wo); //add it to the surface holder list } } /*int count = rand.Next(30); * * * // MyDebug.placeMarker(UnitConverter.getWP(new SurfacePos(su.side, su.u, su.v), radius, sideLength)); * for(int i = 0; i<count; i++) * { * //Vector3 pos = new Vector3( * //choose random x and y position within the su * //Vector2 surfPos = new Vector2((float)rand.NextDouble(), (float)rand.NextDouble()); * float u = (float)rand.NextDouble(); * float v = (float)rand.NextDouble(); * * //choose random rotation(will not be random for things like buildings later) * Quaternion surfRot = Quaternion.Euler(0, (float)rand.NextDouble()*360, 0); * //Debug.Log(surfRot.eulerAngles); * //temp radius of tree used for testing * float wuRadius = 2; * //radius in world units/length of a surface unit = radius in surface units(less than 1) * float suRadius = wuRadius/suLength; * //Debug.Log("suRadius is " + suRadius); * * bool isColliding = false; * foreach(RadialCol oth in radCols) * { * //distance formula(move to struct later) * //if the distance between the two centers - their radii is less than zero, they are colliding * if(Mathf.Sqrt((oth.u-u)*(oth.u-u)+(oth.v-v)*(oth.v-v))-suRadius-oth.radius<0) * { * isColliding = true; * //Debug.Log("samwell"); * break; * } * } * //for the time being, if something is colliding, just discard it * //later it may be moved slightly or completely repositioned * if(isColliding) * { * continue; * } * * //add this obect to the radial collision list * //later, create the RadialCol object initially(replace x y and suRadius) * radCols.Add(new RadialCol(u,v,suRadius)); * * //surfacepos of the tree * SurfacePos treeSurf = new SurfacePos(su.side, su.u + u, su.v + v); * //Debug.Log (u + " " + v + " " + su.u + " " + su.v); * //convert to world unit and rotation * Vector3 worldPos = UnitConverter.getWP(treeSurf, radius, sideLength); * Quaternion worldRot = getWorldRot(worldPos, surfRot, su.side); * //Debug.Log (treeSurf+ " " + worldPos + " " + surfRot.eulerAngles + " " + worldRot); * * //adjust the pos to the correct altitude, later move to function * //worldPos = worldPos.normalized*planet.noise.getAltitude(worldPos); * worldPos = planet.noise.altitudePos(worldPos); * * //GameObject.Instantiate(tree, treeWorld, Quaternion.identity); * //build the tree object(adds it to builtobjects list and maybe eventually add it to the render list * //buildObject<TestTree>(worldPos, worldRot, sh).init(); * * //build(intantiate) the object * WorldObject wo = Build.buildObject<TestTree>(worldPos, worldRot); * wo.Render(); * sh.objects.Add(wo);//add it to the surface holder list * //wo.init();//initailize it (normally has parameters) * * }*/ /*GameObject go = Resources.Load("Test things/rottest") as GameObject; * Vector3 pos = UnitConverter.getWP(new SurfacePos(su.side, su.u+0.5f, su.v+0.5f), radius, sideLength); * Quaternion rot = getWorldRot(pos, Quaternion.identity, su.side); * * GameObject.Instantiate(go, pos, rot);*/ curSH = null; //disconnect reference to avoid possible confusion later/catch errors } //increase the worldunit count of the surface holder sh.wuCount++; }
//fills a mid unit with base units //NOTE: target refers to the intersection while build direction refers to an unmodified straight street path public void fill(TransportUnit mu, SurfaceUnit su) { //set the conPoint of the base unit that contains the mid unit's conPoint int powIndexX = Mathf.FloorToInt(mu.conPoint.x); int powIndexY = Mathf.FloorToInt(mu.conPoint.y); TUBase powUnit = getBase(powIndexX, powIndexY); powUnit.conPoint = mu.conPoint; powUnit.conSet = true; //MyDebug.placeMarker(UnitConverter.getWP(new SurfacePos(su.side, powUnit.conPoint.x, powUnit.conPoint.y), // WorldManager.curPlanet.radius, 64*16), 3); //Debug.Log(mu.conPoint + " " + powUnit.conPoint); //Debug.Log(powIndexX + " " + powIndexY); //the mid transport units to the left and bottom of the current mid unit //TransportUnit leftTU = tran.getAdjustedMid(new SurfaceUnit(su.side,su.u - 1, su.v)); TransportUnit leftTU = tran.getMid(new SurfaceUnit(su.side, su.u - 1, su.v)); TransportUnit downTU = tran.getMid(new SurfaceUnit(su.side, su.u, su.v - 1)); TransportUnit rightTU = tran.getMid(new SurfaceUnit(su.side, su.u + 1, su.v)); TransportUnit upTU = tran.getMid(new SurfaceUnit(su.side, su.u, su.v + 1)); //the directions a street will connect to from the center bool conRight = false; bool conLeft = false; bool conUp = false; bool conDown = false; //the conPoint of the mid unit above, below, to the right and left of this one //have to initially set them to something whether they are used or not Vector2 conPointRight = Vector2.zero; Vector2 conPointLeft = Vector2.zero; Vector2 conPointUp = Vector2.zero; Vector2 conPointDown = Vector2.zero; //initialize street levels int rightLev = 0; int leftLev = 0; int upLev = 0; int downLev = 0; //check if each mid unit exists, and set connections as necesary HOW DO YOU SPELL NECESSARY?!?!?!?!?!?!??!???! if (rightTU != null) { conPointRight = rightTU.conPoint; conRight = mu.conRight; rightLev = mu.RightLev; } if (leftTU != null) { conPointLeft = leftTU.conPoint; conLeft = leftTU.conRight; //if the unit to the left connects to the right, then this unit will connect to the left leftLev = leftTU.RightLev; } if (upTU != null) { conPointUp = upTU.conPoint; conUp = mu.conUp; upLev = mu.UpLev; } if (downTU != null) { conPointDown = downTU.conPoint; conDown = downTU.conUp; downLev = downTU.UpLev; } //Debug.Log(conPointUp + " " + conPointRight + " " + conPointLeft + " " + conPointDown); //the slope that all streets aim for when they converge in the middle float targetSlopeRight = 0; float targetSlopeLeft = 0; float targetSlopeUp = 0; float targetSlopeDown = 0; //sets all the target slopes based on what sides connect if (conUp && conDown && conRight && conLeft) { //form a 4 way perpindicular intersection //vector representing the direction from the bottom to top street point Vector2 DownUpVec = conPointUp - conPointDown; //vector representing the direction from the left to right street point Vector2 LeftRightVec = conPointRight - conPointLeft; //the vector perpindicular to the the left right vector used to find the target inter line Vector2 LeftRightPerp = new Vector2(-LeftRightVec.y, LeftRightVec.x); //opposite reciprocal //the target vector that the street coming from above will aim for at the intersection Vector2 targetVecUpDown = (DownUpVec.normalized + LeftRightPerp.normalized) / 2; //the slope the roads going from up to down should have at the intersection, average of up down slope and slope perpindicular to left right slope //float targetSlopeUpDown = (slopeUpDown + slopeLeftRightR)/2; //float targetSlopeLeftRight = (slopeLeftRight + slopeUpDownR)/2; float targetSlopeUpDown = targetVecUpDown.y / targetVecUpDown.x; // Debug.Log(targetSlopeUpDown); //adjust the slope if infinite if (targetSlopeUpDown == Mathf.Infinity) { targetSlopeUpDown = 100; //float.MinValue; } // Debug.Log(targetSlopeUpDown); //float targetSlopeUpDown = findSlope(conPointUp, conPointDown); float targetSlopeLeftRight = -1 / targetSlopeUpDown; //perpindicular to vertical target slope targetSlopeRight = targetSlopeLeft = targetSlopeLeftRight; targetSlopeUp = targetSlopeDown = targetSlopeUpDown; //Debug.Log(targetSlopeUp + " " + targetSlopeRight); } else if (conUp && conDown) //if the top and bottom are connected but all four sides are not { targetSlopeUp = targetSlopeDown = GridMath.findSlope(conPointUp, conPointDown); if (conRight) { targetSlopeRight = GridMath.perp(targetSlopeUp); //this street will come in aand connect perpindicular to the up and down street } else if (conLeft) { targetSlopeLeft = GridMath.perp(targetSlopeUp); } } else if (conRight && conLeft) //if the left and right are connected but all four sides are not { targetSlopeRight = targetSlopeLeft = GridMath.findSlope(conPointRight, conPointLeft); if (conUp) { targetSlopeUp = GridMath.perp(targetSlopeRight); //this street will come in aand connect perpindicular to the right and left street(has no influence on the slope) } else if (conDown) { targetSlopeDown = GridMath.perp(targetSlopeRight); } } else if (conUp && conRight) //if the street connects up and right but nowhere else { targetSlopeUp = targetSlopeRight = GridMath.findSlope(conPointUp, conPointRight); } else if (conUp && conLeft) { targetSlopeUp = targetSlopeLeft = GridMath.findSlope(conPointUp, conPointLeft); } else if (conDown && conRight) { targetSlopeDown = targetSlopeRight = GridMath.findSlope(conPointDown, conPointRight); } else if (conDown && conLeft) //if the street connects down and left but nowhere else { targetSlopeDown = targetSlopeLeft = GridMath.findSlope(conPointDown, conPointLeft); } else if (conUp) //if it only connects to the top mid unit, make slope between the top bl point and this bl point { targetSlopeUp = GridMath.findSlope(conPointUp, mu.conPoint); } else if (conDown) { targetSlopeDown = GridMath.findSlope(conPointDown, mu.conPoint); } else if (conRight) { targetSlopeRight = GridMath.findSlope(conPointRight, mu.conPoint); } else if (conLeft) { targetSlopeLeft = GridMath.findSlope(conPointLeft, mu.conPoint); } //Debug.Log(targetSlopeUp + " " + targetSlopeRight + " " + targetSlopeLeft + " " + targetSlopeDown); /*MyDebug.placeMarker(UnitConverter.getWP(new SurfacePos(PSide.TOP, conPointUp.x, conPointUp.y), * WorldManager.curPlanet.radius, 64*16)); * MyDebug.placeMarker(UnitConverter.getWP(new SurfacePos(PSide.TOP, conPointDown.x, conPointDown.y), * WorldManager.curPlanet.radius, 64*16)); * MyDebug.placeMarker(UnitConverter.getWP(new SurfacePos(PSide.TOP, conPointRight.x, conPointRight.y), * WorldManager.curPlanet.radius, 64*16)); * MyDebug.placeMarker(UnitConverter.getWP(new SurfacePos(PSide.TOP, conPointLeft.x, conPointLeft.y), * WorldManager.curPlanet.radius, 64*16)); */ /*if(targetSlopeUp==Mathf.Infinity || targetSlopeUp==float.NaN) * targetSlopeUp=500; * if(targetSlopeDown==Mathf.Infinity || targetSlopeDown==float.NaN) * targetSlopeDown=-500; * if(targetSlopeRight==float.NaN) * targetSlopeRight=0; * if(targetSlopeLeft==float.NaN) * targetSlopeLeft=0;*/ //actually build the streets if (conUp) { buildStreetCurve(conPointUp, targetSlopeUp, Dir.UP, powIndexX, powIndexY, mu, upLev); } if (conDown) //if the mid unit below connects up, make a street down { buildStreetCurve(conPointDown, targetSlopeDown, Dir.DOWN, powIndexX, powIndexY, mu, downLev); } if (conRight) { buildStreetCurve(conPointRight, targetSlopeRight, Dir.RIGHT, powIndexX, powIndexY, mu, rightLev); } if (conLeft) //if the mid unit below connects up, make a street down { buildStreetCurve(conPointLeft, targetSlopeLeft, Dir.LEFT, powIndexX, powIndexY, mu, leftLev); } }