/// <summary> /// Creates the central structure and duplicates the rear shape of the wings /// </summary> /// <param name="param">Parameter.</param> /// <param name="parent">Parent.</param> static void RecursiveCreateFronts(ParallelSpaceshipParameters param, SkeletonNode parent, int leftLength) { // create new SkeletonNode var scalefactor = Random.Range(1 - param.scalefactor, 1 + param.scalefactor); var distance = Random.Range(param.minDistance, param.maxDistance); var position = parent.transform.position + parent.transform.forward * distance; // select node type PartType type; if (leftLength > 0 && parent.wingNodes.Count > 0 && param.structuralProbability >= Random.value) { type = PartType.Intersection; } else { type = PartType.Cockpit; } var frontNode = SkeletonNode.Create(position, scalefactor, type); parent.AddFront(frontNode); // create subwing structure foreach (var wing in parent.wingNodes) { if (type == PartType.Cockpit) { distance = Random.Range(param.minDistance, param.maxDistance); } RecursiveCreateSubwings(param, wing, parent, distance); } // prevent unwinged intersections if (parent.wingNodes.Count == 0) { frontNode.type = PartType.Cockpit; } // recursive create next frontNode else if (type == PartType.Intersection) { RecursiveCreateFronts(param, frontNode, leftLength - 1); } }
/// <summary> /// Duplicates the shape of the wings for each row /// </summary> /// <param name="param">Parameter.</param> /// <param name="parent">Parent.</param> /// <param name="gParent">G parent.</param> /// <param name="distance">Distance.</param> static void RecursiveCreateSubwings(ParallelSpaceshipParameters param, SkeletonNode parent, SkeletonNode gParent, float distance) { var scalefactor = Random.Range(1 - param.scalefactor, 1 + param.scalefactor); var position = parent.transform.position + parent.transform.forward * distance; // select node type PartType type; if (gParent.frontNode.type != PartType.Intersection || param.structuralProbability <= Random.value) { type = PartType.Cockpit; } else { type = PartType.Intersection; } var subwingNode = SkeletonNode.Create(position, scalefactor, type); parent.AddFront(subwingNode); // add connection if (type == PartType.Intersection) { gParent.frontNode.AddWing(subwingNode); } // recursive create subwings foreach (var wing in parent.wingNodes) { if (type == PartType.Cockpit) { distance = Random.Range(param.minDistance, param.maxDistance); } RecursiveCreateSubwings(param, wing, parent, distance); } }
/// <summary> /// Creates the shape of the wings at the rear section of the skeleton /// </summary> /// <param name="param">Parameter.</param> /// <param name="parent">Parent.</param> static void RecursiveCreateWings(ParallelSpaceshipParameters param, SkeletonNode parent, int leftWings) { var nWings = param.maxWings; while (nWings > 0 && leftWings > 0 && param.wingProbability >= Random.value) { var scalefactor = Random.Range(1 - param.scalefactor, 1 + param.scalefactor); var distance = Random.Range(param.minDistance, param.maxDistance); var xRot = Random.Range(param.minXAngle, param.maxXAngle); var yRot = Random.Range(param.minYAngle, param.maxYAngle) + 90F; var zRot = 0F; // ! var position = parent.transform.position + (Quaternion.Euler(xRot, yRot, zRot) * parent.transform.forward * distance); parent.AddWing(SkeletonNode.Create(position, scalefactor, PartType.Engine)); nWings--; } foreach (var wing in parent.wingNodes) { RecursiveCreateWings(param, wing, leftWings - 1); } }
static IEnumerable <Part> RecursivePlaceSupports(SkeletonNode parent, IEnumerable <Part> prefabs) { var placedParts = new List <Part>(); var connector = GetRandomPart(prefabs, PartType.Connector); if (connector == null) { return(new Part[0]); } var start = parent.transform.position; var r = connector.radius; foreach (var wing in parent.wingNodes) { var v = wing.transform.position - start; // calculate scale factor var f = v.magnitude / (2 * r); var n = Mathf.Floor(f); n += (v.magnitude % (2 * r) > r) ? 1 : 0; var scale = f / n; var rotation = Quaternion.LookRotation(v); while (n > 0) { var position = start + (v.normalized * r * scale) * (2 * n - 1); Instantiate(connector, position, rotation, placedParts, scale); n--; } // recursive call wings placedParts.AddRange(RecursivePlaceSupports(wing, prefabs)); } return(placedParts); }
public void AddFront(SkeletonNode front) { frontNode = front; }
static IEnumerable <Part> RecursivePlaceStructural(ParallelSpaceshipParameters param, SkeletonNode parent, IEnumerable <Part> prefabs, Part rear = null) { var placedParts = new List <Part>(); var frontPosition = parent.frontNode.transform.position; var rearPosition = parent.transform.position; var vector = frontPosition - rearPosition; var rotation = parent.transform.rotation; // place rear connector & engine by probability if (rear == null) { var intersection = GetRandomPart(prefabs, PartType.Intersection); if (intersection == null) { return(placedParts); } rear = Instantiate(intersection, rearPosition, rotation, placedParts, parent.scalefactor); if (param.engineProbability > Random.value) { // place engine var engine = GetRandomPart(prefabs, PartType.Engine); if (engine == null) { return(placedParts); } var enginePos = rearPosition - vector.normalized * (rear.radius + engine.radius * parent.scalefactor); Instantiate(engine, enginePos, rotation, placedParts, parent.scalefactor); } } // place front depending on type PartType frontType; if (parent.frontNode.type == PartType.Intersection) { frontType = parent.frontNode.type; } else if (param.cockpitProbability >= Random.value) { frontType = PartType.Cockpit; } else { frontType = PartType.Ending; } var frontPart = GetRandomPart(prefabs, frontType); if (frontPart == null) { return(placedParts); } var front = Instantiate(frontPart, frontPosition, rotation, placedParts, parent.frontNode.scalefactor); // update positions & vector rearPosition += vector.normalized * rear.radius; frontPosition -= vector.normalized * front.radius; vector = frontPosition - rearPosition; // calculate median scaling of vector parts var scale = (parent.scalefactor + parent.frontNode.scalefactor) / 2; // virtualize parts for vector var fillers = new List <Part>(); var filled = 0F; do { var part = GetRandomPart(prefabs, PartType.Structural); if (part == null) { return(placedParts); } fillers.Add(part); filled += 2 * part.radius * scale; } while (filled < (vector.magnitude - filled) * fillers.Count * 2); // median part radius > left space // calculate final scalefactor scale *= vector.magnitude / filled; // fill vector with parts foreach (var prefab in fillers) { var partPos = rearPosition + vector.normalized * prefab.radius * scale; var part = Instantiate(prefab, partPos, rotation, placedParts, scale); // reposition insert point rearPosition += vector.normalized * 2 * part.radius; } // call next if (parent.frontNode.frontNode != null) { placedParts.AddRange(RecursivePlaceStructural(param, parent.frontNode, prefabs, front)); } return(placedParts); }
static IEnumerable <Part> PlaceStructurals(ParallelSpaceshipParameters param, SkeletonNode parent, IEnumerable <Part> prefabs) { var placedParts = new List <Part>(); placedParts.AddRange(RecursivePlaceStructural(param, parent, prefabs)); foreach (var wing in parent.wingNodes) { placedParts.AddRange(PlaceStructurals(param, wing, prefabs)); } return(placedParts); }
public static IEnumerable <Part> PlaceParts(ParallelSpaceshipParameters param, SkeletonNode rootNode, IEnumerable <Part> prefabs) { var parts = new List <Part>(); parts.AddRange(PlaceSupports(rootNode, prefabs)); parts.AddRange(PlaceStructurals(param, rootNode, prefabs)); return(parts); }