public static void Portal(ref BuildRMesh dynamicMesh, Portal portal, Vector2 size, Vector3 offset, bool interior = true, SubmeshLibrary submeshLibrary = null) { if (submeshLibrary == null) { submeshLibrary = new SubmeshLibrary(); submeshLibrary.Add(portal); } Division root = portal.root; List <Panel> processNodes = new List <Panel>(); Dictionary <Panel, Panel[]> dataDic = new Dictionary <Panel, Panel[]>(); List <Panel> data = new List <Panel>(); Panel rootPanel = new Panel(root, new Rect(0, 0, size.x, size.y), 0); processNodes.Add(rootPanel); float totalDepth = 0; while (processNodes.Count > 0) { Panel current = processNodes[0]; Division division = current.division; List <Division> children = division.GetChildren; int childCount = children.Count; data.Add(current);//dump processed node into data. dataDic.Add(current, new Panel[childCount]); if (current.recess > totalDepth) { totalDepth = current.recess; } float childRatio = 0; for (int c = 0; c < childCount; c++) { childRatio += children[c].size; } for (int c = 0; c < childCount; c++) { Division child = children[c]; Rect newPanelrect = current.rect; float ratio = children[c].size / childRatio; if (division.divisionType == BuildR2.Portal.DivisionTypes.Horizontal) { newPanelrect.width = Mathf.Max(newPanelrect.width - division.frame * 2 - division.frame * (childCount - 1), 0) * ratio; newPanelrect.height = Mathf.Max(newPanelrect.height - division.frame * 2, 0); if (c > 0) { Panel lastPanel = processNodes[processNodes.Count - 1]; newPanelrect.x = lastPanel.rect.xMax + division.frame; } else { newPanelrect.x = current.rect.xMin + division.frame; } newPanelrect.y = current.rect.yMin + division.frame; } else { newPanelrect.width = Mathf.Max(newPanelrect.width - division.frame * 2, 0); newPanelrect.height = Mathf.Max(newPanelrect.height - division.frame * 2 - division.frame * (childCount - 1), 0) * ratio; if (c > 0) { Panel lastPanel = processNodes[processNodes.Count - 1]; newPanelrect.y = lastPanel.rect.y + lastPanel.rect.height + division.frame; } else { newPanelrect.y = current.rect.yMin + division.frame; } newPanelrect.x = current.rect.xMin + division.frame; } Panel childPanel = new Panel(child, newPanelrect, current.recess + division.recess); dataDic[current][c] = childPanel; processNodes.Add(childPanel); } processNodes.RemoveAt(0); } int dataCount = data.Count; Vector3 norm = Vector3.back; Vector4 tangent = BuildRMesh.CalculateTangent(Vector3.right); Vector4 tangentForward = BuildRMesh.CalculateTangent(Vector3.forward); Vector4 tangentBack = BuildRMesh.CalculateTangent(Vector3.back); Vector4 tangentInvert = BuildRMesh.CalculateTangent(Vector3.left); Vector3 useOffset = size * 0.5f; useOffset += offset; useOffset.y = -useOffset.y;//inverse - UX resaons for (int i = 0; i < dataCount; i++) { Panel panel = data[i]; Division division = panel.division; Rect panelRect = panel.rect; if (panelRect.width == 0 || panelRect.height == 0) { continue; } Vector3 v0 = new Vector3(panelRect.xMin, -panelRect.yMin, panel.recess) - useOffset; Vector3 v1 = new Vector3(panelRect.xMax, -panelRect.yMin, panel.recess) - useOffset; Vector3 v2 = new Vector3(panelRect.xMin, -panelRect.yMax, panel.recess) - useOffset; Vector3 v3 = new Vector3(panelRect.xMax, -panelRect.yMax, panel.recess) - useOffset; Surface usedSurface = GetSurface(portal, division); int useSubmesh = submeshLibrary.SubmeshAdd(usedSurface); // int useSubmesh = usedSurface != null ? Array.IndexOf(usedSurfaces, usedSurface) : 0; Vector2 uv0 = CalculateUV(usedSurface, v0); Vector2 uv1 = CalculateUV(usedSurface, v1); Vector2 uv2 = CalculateUV(usedSurface, v2); Vector2 uv3 = CalculateUV(usedSurface, v3); if (!division.hasChildren)//simple panel { Vector3[] verts = { v0, v1, v2, v3 }; Vector2[] uvs = { uv0, uv1, uv2, uv3 }; int[] tris = { 0, 1, 2, 1, 3, 2 }; Vector3[] norms = { norm, norm, norm, norm }; Vector4[] tangents = { tangent, tangent, tangent, tangent }; dynamicMesh.AddData(verts, uvs, tris, norms, tangents, useSubmesh); if (interior) { Vector3 interiorOffset = new Vector3(0, 0, (totalDepth - panel.recess) * 2); verts = new[] { v0 + interiorOffset, v1 + interiorOffset, v2 + interiorOffset, v3 + interiorOffset }; uvs = new[] { uv1, uv0, uv3, uv2 }; tris = new[] { 0, 2, 1, 1, 2, 3 }; norms = new[] { -norm, -norm, -norm, -norm }; tangents = new[] { tangentInvert, tangentInvert, tangentInvert, tangentInvert }; dynamicMesh.AddData(verts, uvs, tris, norms, tangents, useSubmesh); } } else//build a frame { Vector3 v0f = v0 + new Vector3(division.frame, -division.frame, 0); Vector3 v1f = v1 + new Vector3(-division.frame, -division.frame, 0); Vector3 v2f = v2 + new Vector3(division.frame, division.frame, 0); Vector3 v3f = v3 + new Vector3(-division.frame, division.frame, 0); Vector3 recessV = Vector3.forward * (division.recess); Vector3 v0r = v0f + recessV; Vector3 v1r = v1f + recessV; Vector3 v2r = v2f + recessV; Vector3 v3r = v3f + recessV; Vector2 uv0f = CalculateUV(usedSurface, v0f); Vector2 uv1f = CalculateUV(usedSurface, v1f); Vector2 uv2f = CalculateUV(usedSurface, v2f); Vector2 uv3f = CalculateUV(usedSurface, v3f); // Vector2 uv0r = CalculateUV(usedSurface, v0r); // Vector2 uv1r = CalculateUV(usedSurface, v1r); // Vector2 uv2r = CalculateUV(usedSurface, v2r); // Vector2 uv3r = CalculateUV(usedSurface, v3r); Vector3[] verts = { v0, v1, v2, v3, v0f, v1f, v2f, v3f }; Vector2[] uvs = { uv0, uv1, uv2, uv3, uv0f, uv1f, uv2f, uv3f }; Vector3[] norms = { norm, norm, norm, norm, norm, norm, norm, norm }; Vector4[] tangents = { tangent, tangent, tangent, tangent, tangent, tangent, tangent, tangent }; int[] tris = { 0, 4, 2, 4, 6, 2, //left 0, 1, 4, 1, 5, 4, //top 5, 1, 3, 5, 3, 7, //right 2, 6, 3, 3, 6, 7, //bottom }; dynamicMesh.AddData(verts, uvs, tris, norms, tangents, useSubmesh); Vector2 uvUp = CalculateUV(usedSurface, new Vector2(0, division.recess)); Vector2 uvRight = CalculateUV(usedSurface, new Vector2(division.recess, 0)); dynamicMesh.AddPlaneComplex(v1f, v0f, v1r, v0r, uv1f, uv0f, uv1f + uvUp, uv0f + uvUp, Vector3.down, tangent, useSubmesh, usedSurface); //top dynamicMesh.AddPlaneComplex(v2f, v3f, v2r, v3r, uv2f, uv3f, uv2f + uvUp, uv3f + uvUp, Vector3.up, tangent, useSubmesh, usedSurface); //bottom dynamicMesh.AddPlaneComplex(v0f, v2f, v0r, v2r, uv0f, uv2f, uv0f + uvRight, uv2f + uvRight, Vector3.right, tangentForward, useSubmesh, usedSurface); //left dynamicMesh.AddPlaneComplex(v3f, v1f, v3r, v1r, uv3f, uv1f, uv3f + uvRight, uv1f + uvRight, Vector3.left, tangentBack, useSubmesh, usedSurface); //right if (interior) { Vector3 interiorOffset = new Vector3(0, 0, (totalDepth - panel.recess) * 2); Vector3 interiorOffsetr = new Vector3(0, 0, (totalDepth - panel.recess - division.recess) * 2); verts = new[] { v0 + interiorOffset, v1 + interiorOffset, v2 + interiorOffset, v3 + interiorOffset, v0f + interiorOffset, v1f + interiorOffset, v2f + interiorOffset, v3f + interiorOffset }; uvs = new [] { uv1, uv0, uv3, uv2, uv1f, uv0f, uv3f, uv2f }; Array.Reverse(tris); norms = new[] { -norm, -norm, -norm, -norm, -norm, -norm, -norm, -norm }; tangents = new[] { tangentInvert, tangentInvert, tangentInvert, tangentInvert, tangentInvert, tangentInvert, tangentInvert, tangentInvert }; dynamicMesh.AddData(verts, uvs, tris, norms, tangents, useSubmesh); dynamicMesh.AddPlaneComplex(v0f + interiorOffset, v1f + interiorOffset, v0r + interiorOffsetr, v1r + interiorOffsetr, uv0f, uv1f, uv0f + uvUp, uv1f + uvUp, Vector3.down, tangentInvert, useSubmesh, usedSurface); //top dynamicMesh.AddPlaneComplex(v3f + interiorOffset, v2f + interiorOffset, v3r + interiorOffsetr, v2r + interiorOffsetr, uv3f, uv2f, uv3f + uvUp, uv2f + uvUp, Vector3.up, tangentInvert, useSubmesh, usedSurface); //bottom dynamicMesh.AddPlaneComplex(v2f + interiorOffset, v0f + interiorOffset, v2r + interiorOffsetr, v0r + interiorOffsetr, uv2f, uv0f, uv2f + uvRight, uv0f + uvRight, Vector3.right, tangentBack, useSubmesh, usedSurface); //left dynamicMesh.AddPlaneComplex(v3f + interiorOffset, v3f + interiorOffset, v3r + interiorOffsetr, v3r + interiorOffsetr, uv1f, uv3f, uv1f + uvRight, uv3f + uvRight, Vector3.left, tangentForward, useSubmesh, usedSurface); //right } List <Division> children = division.GetChildren; int childCount = children.Count; if (childCount > 1 && division.frame > 0) { for (int c = 0; c < childCount - 1; c++) { Panel childPanel = dataDic[panel][c]; if (division.divisionType == BuildR2.Portal.DivisionTypes.Horizontal) { Vector3 v0d = v0 + new Vector3(childPanel.rect.xMax - panelRect.xMin, -division.frame, 0); Vector3 v1d = v0d + new Vector3(division.frame, 0, 0); Vector3 v2d = v0d + new Vector3(0, -panelRect.height + division.frame * 2, 0); Vector3 v3d = v1d + new Vector3(0, -panelRect.height + division.frame * 2, 0); Vector2 uv0d = CalculateUV(usedSurface, v0d); Vector2 uv1d = CalculateUV(usedSurface, v1d); Vector2 uv2d = CalculateUV(usedSurface, v2d); Vector2 uv3d = CalculateUV(usedSurface, v3d); dynamicMesh.AddPlaneComplex(v1d, v0d, v3d, v2d, uv0d, uv1d, uv2d, uv3d, norm, tangent, useSubmesh, usedSurface); //divider face dynamicMesh.AddPlaneComplex(v2d, v0d, v2d + recessV, v0d + recessV, uv2d, uv0d, uv2d + uvRight, uv0d + uvRight, Vector3.left, tangentBack, useSubmesh, usedSurface); //divider left dynamicMesh.AddPlaneComplex(v1d, v3d, v1d + recessV, v3d + recessV, uv1d, uv3d, uv1d - uvRight, uv3d - uvRight, Vector3.right, tangentBack, useSubmesh, usedSurface); //divider right if (interior) { Vector3 interiorOffset = new Vector3(0, 0, (totalDepth - panel.recess) * 2); Vector3 interiorOffsetr = new Vector3(0, 0, (totalDepth - panel.recess - division.recess) * 2); dynamicMesh.AddPlaneComplex(v0d + interiorOffset, v1d + interiorOffset, v2d + interiorOffset, v3d + interiorOffset, uv1d, uv0d, uv3d, uv2d, -norm, tangentInvert, useSubmesh, usedSurface); //divider face dynamicMesh.AddPlaneComplex(v0d + interiorOffset, v2d + interiorOffset, v0d + recessV + interiorOffsetr, v2d + recessV + interiorOffsetr, uv0d, uv2d, uv0d + uvRight, uv2d + uvRight, Vector3.left, tangentForward, useSubmesh, usedSurface); //divider left dynamicMesh.AddPlaneComplex(v3d + interiorOffset, v1d + interiorOffset, v3d + recessV + interiorOffsetr, v1d + recessV + interiorOffsetr, uv3d, uv1d, uv3d - uvRight, uv1d - uvRight, Vector3.right, tangentForward, useSubmesh, usedSurface); //divider right } } else { Vector3 v0d = v0 + new Vector3(division.frame, -childPanel.rect.yMax + panelRect.yMin, 0); Vector3 v1d = v0d + new Vector3(0, -division.frame, 0); Vector3 v2d = v0d + new Vector3(panelRect.width - division.frame * 2, 0, 0); Vector3 v3d = v1d + new Vector3(panelRect.width - division.frame * 2, 0, 0); Vector2 uv0d = CalculateUV(usedSurface, v0d); Vector2 uv1d = CalculateUV(usedSurface, v1d); Vector2 uv2d = CalculateUV(usedSurface, v2d); Vector2 uv3d = CalculateUV(usedSurface, v3d); dynamicMesh.AddPlaneComplex(v0d, v1d, v2d, v3d, uv0d, uv1d, uv2d, uv3d, norm, tangent, useSubmesh, usedSurface); //divider face dynamicMesh.AddPlaneComplex(v0d, v2d, v0d + recessV, v2d + recessV, uv0d, uv2d, uv0d + uvUp, uv2d + uvUp, Vector3.up, tangent, useSubmesh, usedSurface); //divider top dynamicMesh.AddPlaneComplex(v3d, v1d, v3d + recessV, v1d + recessV, uv3d, uv1d, uv3d - uvUp, uv1d - uvUp, Vector3.down, tangent, useSubmesh, usedSurface); //divider bottom if (interior) { Vector3 interiorOffset = new Vector3(0, 0, (totalDepth - panel.recess) * 2); Vector3 interiorOffsetr = new Vector3(0, 0, (totalDepth - panel.recess - division.recess) * 2); dynamicMesh.AddPlaneComplex(v1d + interiorOffset, v0d + interiorOffset, v3d + interiorOffset, v2d + interiorOffset, uv1d, uv0d, uv3d, uv2d, -norm, tangentInvert, useSubmesh, usedSurface); //divider face dynamicMesh.AddPlaneComplex(v2d + interiorOffset, v0d + interiorOffset, v2d + recessV + interiorOffsetr, v0d + recessV + interiorOffsetr, uv2d, uv0d, uv2d + uvUp, uv0d + uvUp, Vector3.up, tangentInvert, useSubmesh, usedSurface); //divider top dynamicMesh.AddPlaneComplex(v1d + interiorOffset, v3d + interiorOffset, v1d + recessV + interiorOffsetr, v3d + recessV + interiorOffsetr, uv1d, uv3d, uv1d - uvUp, uv3d - uvUp, Vector3.down, tangentInvert, useSubmesh, usedSurface); //divider bottom } } } } } } }
public static void Generate(ref BuildRMesh mesh, Gable design, Vector3 p0, Vector3 p1, float height, float thickness, Vector2 baseUV) { int gableSectionCount = design.count; Vector2 designSize = new Vector2(); for (int g = 0; g < gableSectionCount; g++) { designSize += design[g].GetSize(); } Vector2 actualSize = new Vector2(Vector3.Distance(p0, p1), height); Vector2 designScale = new Vector2((actualSize.x / 2) / designSize.x, actualSize.y / designSize.y); Vector2 basePosition = Vector2.zero; Vector3 facadeVector = p1 - p0; Vector3 facadeDirection = facadeVector.normalized; float facadeWidth = facadeVector.magnitude; Vector3 facadeNormal = Vector3.Cross(Vector3.up, facadeDirection); Vector4 facadeTangentForward = BuildRMesh.CalculateTangent(facadeDirection); Vector4 facadeTangentLeft = BuildRMesh.CalculateTangent(facadeNormal); Vector4 facadeTangentRight = BuildRMesh.CalculateTangent(-facadeNormal); Vector4 facadeTangentBack = BuildRMesh.CalculateTangent(-facadeDirection); Surface surface = design.surface; int submesh = mesh.submeshLibrary.SubmeshAdd(surface);//surfaceMapping.IndexOf(surface); if (submesh == -1) { submesh = 0; } Vector3 back = -facadeNormal * thickness; for (int g = 0; g < gableSectionCount; g++) { float sectionWidth = design[g].size.x * designScale.x; float sectionHeight = design[g].size.y * designScale.y; Vector3 g0, g1, g2, g3; switch (design[g].type) { case GablePart.Types.Vertical: g0 = p0 + facadeDirection * basePosition.x + Vector3.up * basePosition.y; g1 = p1 - facadeDirection * basePosition.x + Vector3.up * basePosition.y; g2 = g0 + Vector3.up * sectionHeight; g3 = g1 + Vector3.up * sectionHeight; Vector2 uvMax = baseUV + basePosition + new Vector2(facadeWidth - basePosition.x * 2, sectionHeight); mesh.AddPlane(g0, g1, g2, g3, baseUV + basePosition, uvMax, facadeNormal, facadeTangentForward, submesh, surface); Vector2 uvB0 = baseUV + basePosition + new Vector2(0, 0); Vector2 uvB1 = baseUV + basePosition + new Vector2(facadeWidth - basePosition.x * 2, sectionHeight); mesh.AddPlane(g1 + back, g0 + back, g3 + back, g2 + back, uvB0, uvB1, -facadeNormal, facadeTangentBack, submesh, surface); var gb0 = g0 + back; var gb1 = g1 + back; var gb2 = g2 + back; var gb3 = g3 + back; Vector2 baseVUV = new Vector2(0, basePosition.y); mesh.AddPlane(gb0, g0, gb2, g2, baseVUV, new Vector2(thickness, basePosition.y + sectionHeight), -facadeDirection, facadeTangentLeft, submesh, surface); mesh.AddPlane(g1, gb1, g3, gb3, baseVUV, new Vector2(thickness, basePosition.y + sectionHeight), facadeDirection, facadeTangentRight, submesh, surface); basePosition.y += sectionHeight; break; case GablePart.Types.Horizonal: g0 = p0 + facadeDirection * basePosition.x + Vector3.up * basePosition.y; g1 = p1 - facadeDirection * basePosition.x + Vector3.up * basePosition.y; g2 = g0 + facadeDirection * sectionWidth; g3 = g1 - facadeDirection * sectionWidth; Vector4 tangent = BuildRMesh.CalculateTangent(facadeDirection); mesh.AddPlane(g0, g2, g0 + back, g2 + back, Vector3.zero, new Vector2(sectionWidth, thickness), Vector3.up, tangent, submesh, surface); mesh.AddPlane(g3, g1, g3 + back, g1 + back, Vector3.zero, new Vector2(sectionWidth, thickness), Vector3.up, tangent, submesh, surface); basePosition.x += sectionWidth; break; case GablePart.Types.Diagonal: Vector3 gd0 = p0 + facadeDirection * basePosition.x + Vector3.up * basePosition.y; Vector3 gd1 = p1 - facadeDirection * basePosition.x + Vector3.up * basePosition.y; Vector3 gd2 = gd0 + facadeDirection * sectionWidth + Vector3.up * sectionHeight; Vector3 gd3 = gd1 - facadeDirection * sectionWidth + Vector3.up * sectionHeight; Vector3 gdb0 = gd0 + back; Vector3 gdb1 = gd1 + back; Vector3 gdb2 = gd2 + back; Vector3 gdb3 = gd3 + back; Vector2 uv0 = baseUV + basePosition; Vector2 uv1 = baseUV + new Vector2(basePosition.x + facadeWidth - basePosition.x * 2, basePosition.y); Vector2 uv2 = baseUV + new Vector2(basePosition.x + sectionWidth, basePosition.y + sectionHeight); Vector2 uv3 = baseUV + new Vector2(basePosition.x + facadeWidth - basePosition.x * 2 - sectionWidth, basePosition.y + sectionHeight); mesh.AddPlaneComplex(gd0, gd1, gd2, gd3, uv0, uv1, uv2, uv3, facadeNormal, facadeTangentForward, submesh, surface); //face mesh.AddPlaneComplex(gdb1, gdb0, gdb3, gdb2, uv0, uv1, uv2, uv3, -facadeNormal, facadeTangentBack, submesh, surface); //face Vector3 leftNorm = Vector3.Cross(-facadeNormal, (gd2 - gd0).normalized); Vector3[] leftNorms = { leftNorm, leftNorm, leftNorm, leftNorm }; Vector4 leftTangent = facadeTangentLeft; Vector4[] leftTangents = { leftTangent, leftTangent, leftTangent, leftTangent }; Vector3[] leftFace = { gdb0, gd0, gdb2, gd2 }; float faceWidth = Vector3.Distance(gd0, gd2); Vector2 sideUV0 = Vector2.zero; Vector2 sideUV1 = surface != null?surface.CalculateUV(new Vector2(thickness, 0)) : new Vector2(1, 0); Vector2 sideUV2 = surface != null?surface.CalculateUV(new Vector2(0, faceWidth)) : new Vector2(0, 1); Vector2 sideUV3 = surface != null?surface.CalculateUV(new Vector2(thickness, faceWidth)) : new Vector2(1, 1); Vector2[] leftFaceUV = { sideUV0, sideUV1, sideUV2, sideUV3 }; mesh.AddData(leftFace, leftFaceUV, new[] { 0, 2, 1, 2, 3, 1 }, leftNorms, leftTangents, submesh); Vector3 rightNorm = Vector3.Cross(-facadeNormal, (gd1 - gd3).normalized); Vector3[] rightNorms = { rightNorm, rightNorm, rightNorm, rightNorm }; Vector4 rightTangent = facadeTangentRight; Vector4[] rightTangents = { rightTangent, rightTangent, rightTangent, rightTangent }; Vector3[] rightFace = { gd1, gdb1, gd3, gdb3 }; Vector2[] rightFaceUV = { sideUV0, sideUV1, sideUV2, sideUV3 }; //todo mesh.AddData(rightFace, rightFaceUV, new[] { 0, 2, 1, 2, 3, 1 }, rightNorms, rightTangents, submesh); basePosition.x += sectionWidth; basePosition.y += sectionHeight; break; case GablePart.Types.Concave: Arc(ref mesh, design, new Vector3(sectionWidth, sectionHeight, thickness), p0, p1, basePosition, submesh, surface, false, baseUV); basePosition.x += sectionWidth; basePosition.y += sectionHeight; break; case GablePart.Types.Convex: Arc(ref mesh, design, new Vector3(sectionWidth, sectionHeight, thickness), p0, p1, basePosition, submesh, surface, true, baseUV); basePosition.x += sectionWidth; basePosition.y += sectionHeight; break; } } }
public static void Generate(Chimney chimney, GenerationOutput output, SubmeshLibrary submeshLibrary = null) { RGEN.seed = chimney.seed; DYNAMIC_MESH.Clear(); if (submeshLibrary != null) { DYNAMIC_MESH.submeshLibrary.AddRange(submeshLibrary.SURFACES.ToArray()); //DYNAMIC_MESH.submeshLibrary.Inject(ref submeshLibrary); } else { DYNAMIC_MESH.submeshLibrary.Add(chimney); } submeshLibrary = DYNAMIC_MESH.submeshLibrary; //CASE Vector3 caseNoiseVector = new Vector3(chimney.noise.x * RGEN.OneRange(), chimney.noise.y * RGEN.OneRange(), chimney.noise.z * RGEN.OneRange()); Vector3 cs0 = new Vector3(-chimney.caseSize.x * 0.5f, 0, -chimney.caseSize.z * 0.5f); Vector3 cs1 = new Vector3(chimney.caseSize.x * 0.5f, 0, -chimney.caseSize.z * 0.5f); Vector3 cs2 = new Vector3(-chimney.caseSize.x * 0.5f, 0, chimney.caseSize.z * 0.5f); Vector3 cs3 = new Vector3(chimney.caseSize.x * 0.5f, 0, chimney.caseSize.z * 0.5f); Vector3 cs4 = new Vector3(-chimney.caseSize.x * 0.5f, chimney.caseSize.y, -chimney.caseSize.z * 0.5f) + caseNoiseVector; Vector3 cs5 = new Vector3(chimney.caseSize.x * 0.5f, chimney.caseSize.y, -chimney.caseSize.z * 0.5f) + caseNoiseVector; Vector3 cs6 = new Vector3(-chimney.caseSize.x * 0.5f, chimney.caseSize.y, chimney.caseSize.z * 0.5f) + caseNoiseVector; Vector3 cs7 = new Vector3(chimney.caseSize.x * 0.5f, chimney.caseSize.y, chimney.caseSize.z * 0.5f) + caseNoiseVector; Vector2 csuv0 = new Vector2(0, 0); Vector2 csuv1 = new Vector2(chimney.caseSize.x, chimney.caseSize.y); Vector2 csuv2 = new Vector2(csuv1.x, 0); Vector2 csuv3 = new Vector2(csuv1.x + chimney.caseSize.z, chimney.caseSize.y); Vector2 csuv4 = new Vector2(csuv3.x, 0); Vector2 csuv5 = new Vector2(csuv3.x + chimney.caseSize.x, chimney.caseSize.y); Vector2 csuv6 = new Vector2(csuv5.x, 0); Vector2 csuv7 = new Vector2(csuv5.x + chimney.caseSize.z, chimney.caseSize.y); Vector2 csuv8 = new Vector2(0, 0); Vector2 csuv9 = new Vector2(chimney.caseSize.x, chimney.caseSize.z); Vector4 cst0 = new Vector4(0, 0, 1, 0); Vector4 cst1 = new Vector4(1, 0, 1, 0); Vector4 cst2 = new Vector4(0, 0, -1, 0); Vector4 cst3 = new Vector4(-1, 0, 0, 0); Vector4 cst4 = new Vector4(0, 0, 1, 0); int caseSubmesh = submeshLibrary.SubmeshAdd(chimney.caseSurface); //sides DYNAMIC_MESH.AddPlane(cs0, cs1, cs4, cs5, csuv0, csuv1, Vector3.back, cst0, caseSubmesh, chimney.caseSurface); DYNAMIC_MESH.AddPlane(cs1, cs3, cs5, cs7, csuv2, csuv3, Vector3.right, cst1, caseSubmesh, chimney.caseSurface); DYNAMIC_MESH.AddPlane(cs3, cs2, cs7, cs6, csuv4, csuv5, Vector3.forward, cst2, caseSubmesh, chimney.caseSurface); DYNAMIC_MESH.AddPlane(cs2, cs0, cs6, cs4, csuv6, csuv7, Vector3.left, cst3, caseSubmesh, chimney.caseSurface); //top DYNAMIC_MESH.AddPlane(cs4, cs5, cs6, cs7, csuv8, csuv9, Vector3.up, cst4, caseSubmesh, chimney.caseSurface);//todo calculate the values for this - don't be lazy //CROWN Vector3 crownBase = caseNoiseVector + Vector3.up * chimney.caseSize.y; Vector3 crownNoiseVector = new Vector3(chimney.noise.x * RGEN.OneRange(), chimney.noise.y * RGEN.OneRange(), chimney.noise.z * RGEN.OneRange()); Vector3 cr0 = crownBase + new Vector3(-chimney.crownSize.x * 0.5f, 0, -chimney.crownSize.z * 0.5f); Vector3 cr1 = crownBase + new Vector3(chimney.crownSize.x * 0.5f, 0, -chimney.crownSize.z * 0.5f); Vector3 cr2 = crownBase + new Vector3(-chimney.crownSize.x * 0.5f, 0, chimney.crownSize.z * 0.5f); Vector3 cr3 = crownBase + new Vector3(chimney.crownSize.x * 0.5f, 0, chimney.crownSize.z * 0.5f); Vector3 cr4 = crownBase + new Vector3(-chimney.crownSize.x * 0.5f, chimney.crownSize.y, -chimney.crownSize.z * 0.5f) + crownNoiseVector; Vector3 cr5 = crownBase + new Vector3(chimney.crownSize.x * 0.5f, chimney.crownSize.y, -chimney.crownSize.z * 0.5f) + crownNoiseVector; Vector3 cr6 = crownBase + new Vector3(-chimney.crownSize.x * 0.5f, chimney.crownSize.y, chimney.crownSize.z * 0.5f) + crownNoiseVector; Vector3 cr7 = crownBase + new Vector3(chimney.crownSize.x * 0.5f, chimney.crownSize.y, chimney.crownSize.z * 0.5f) + crownNoiseVector; Vector2 cruv0 = new Vector2(0, 0); Vector2 cruv1 = new Vector2(chimney.crownSize.x, chimney.crownSize.y); Vector2 cruv2 = new Vector2(csuv1.x, 0); Vector2 cruv3 = new Vector2(csuv1.x + chimney.caseSize.z, chimney.crownSize.y); Vector2 cruv4 = new Vector2(csuv3.x, 0); Vector2 cruv5 = new Vector2(csuv3.x + chimney.crownSize.x, chimney.crownSize.y); Vector2 cruv6 = new Vector2(csuv5.x, chimney.crownSize.y); Vector2 cruv7 = new Vector2(csuv5.x + chimney.crownSize.z, chimney.crownSize.y); Vector2 cruv8 = new Vector2(0, 0); Vector2 cruv9 = new Vector2(chimney.crownSize.x, chimney.crownSize.z); Vector4 crt0 = new Vector4(0, 0, 1, 0); Vector4 crt1 = new Vector4(1, 0, 1, 0); Vector4 crt2 = new Vector4(0, 0, -1, 0); Vector4 crt3 = new Vector4(-1, 0, 0, 0); Vector4 crt4 = new Vector4(0, 0, 1, 0); int crownSubmesh = submeshLibrary.SubmeshAdd(chimney.crownSurface); DYNAMIC_MESH.AddPlane(cr0, cr1, cr4, cr5, cruv0, cruv1, Vector3.back, crt0, crownSubmesh, chimney.crownSurface); //todo calculate the values for this - don't be lazy DYNAMIC_MESH.AddPlane(cr1, cr3, cr5, cr7, cruv2, cruv3, Vector3.right, crt1, crownSubmesh, chimney.crownSurface); //todo calculate the values for this - don't be lazy DYNAMIC_MESH.AddPlane(cr3, cr2, cr7, cr6, cruv4, cruv5, Vector3.forward, crt2, crownSubmesh, chimney.crownSurface); //todo calculate the values for this - don't be lazy DYNAMIC_MESH.AddPlane(cr2, cr0, cr6, cr4, cruv6, cruv7, Vector3.left, crt3, crownSubmesh, chimney.crownSurface); //todo calculate the values for this - don't be lazy DYNAMIC_MESH.AddPlane(cr1, cr0, cr3, cr2, cruv8, cruv9, Vector3.down, crt4, crownSubmesh, chimney.crownSurface); //todo calculate the values for this - don't be lazy DYNAMIC_MESH.AddPlane(cr4, cr5, cr6, cr7, cruv8, cruv9, Vector3.up, crt4, crownSubmesh, chimney.crownSurface); //todo calculate the values for this - don't be lazy int xCount = 1; int zCount = 1; if (chimney.allowMultiple) { xCount = Mathf.FloorToInt((chimney.crownSize.x - chimney.flueSpacing) / (chimney.flueSize.x + chimney.flueSpacing)); if (xCount < 1) { xCount = 1; } if (chimney.allowMultipleRows) { zCount = Mathf.FloorToInt((chimney.crownSize.z - chimney.flueSpacing) / (chimney.flueSize.z + chimney.flueSpacing)); if (zCount < 1) { zCount = 1; } } } float xSpacing = (chimney.crownSize.x - chimney.flueSize.x * xCount) / (xCount + 1); float zSpacing = (chimney.crownSize.z - chimney.flueSize.z * zCount) / (zCount + 1); //FLUES for (int x = 0; x < xCount; x++) { for (int z = 0; z < zCount; z++) { Vector3 flueBase = cr4 + new Vector3(xSpacing + x * (chimney.flueSize.x + xSpacing) + chimney.flueSize.x * 0.5f, 0, zSpacing + z * (chimney.flueSize.z + zSpacing) + chimney.flueSize.z * 0.5f); float thickness = (chimney.flueSize.x + chimney.flueSize.z) * 0.05f;//10% float drop = chimney.flueSize.y * 0.9f; Vector4 topTangent = new Vector4(1, 0, 0, 0); Surface useFlueSurface = GenerationUtil.GetSurface(chimney.flueSurfaces, RGEN); int flueSubmesh = submeshLibrary.SubmeshAdd(useFlueSurface); int innerSubmesh = submeshLibrary.SubmeshAdd(chimney.innerSurface); Vector3 flueNoiseVector = new Vector3(chimney.noise.x * RGEN.OneRange(), chimney.noise.y * RGEN.OneRange(), chimney.noise.z * RGEN.OneRange()); if (chimney.square) { Vector3 f0 = flueBase + new Vector3(-chimney.flueSize.x * 0.5f, 0, -chimney.flueSize.z * 0.5f); Vector3 f1 = flueBase + new Vector3(chimney.flueSize.x * 0.5f, 0, -chimney.flueSize.z * 0.5f); Vector3 f2 = flueBase + new Vector3(-chimney.flueSize.x * 0.5f, 0, chimney.flueSize.z * 0.5f); Vector3 f3 = flueBase + new Vector3(chimney.flueSize.x * 0.5f, 0, chimney.flueSize.z * 0.5f); Vector3 f4 = flueBase + new Vector3(-chimney.flueSize.x * 0.5f, chimney.flueSize.y, -chimney.flueSize.z * 0.5f) + flueNoiseVector; Vector3 f5 = flueBase + new Vector3(chimney.flueSize.x * 0.5f, chimney.flueSize.y, -chimney.flueSize.z * 0.5f) + flueNoiseVector; Vector3 f6 = flueBase + new Vector3(-chimney.flueSize.x * 0.5f, chimney.flueSize.y, chimney.flueSize.z * 0.5f) + flueNoiseVector; Vector3 f7 = flueBase + new Vector3(chimney.flueSize.x * 0.5f, chimney.flueSize.y, chimney.flueSize.z * 0.5f) + flueNoiseVector; Vector3 f4i = f4 + new Vector3(thickness, 0, thickness) + flueNoiseVector; Vector3 f5i = f5 + new Vector3(-thickness, 0, thickness) + flueNoiseVector; Vector3 f6i = f6 + new Vector3(thickness, 0, -thickness) + flueNoiseVector; Vector3 f7i = f7 + new Vector3(-thickness, 0, -thickness) + flueNoiseVector; Vector3 f4id = f4i + new Vector3(0, -drop, 0); Vector3 f5id = f5i + new Vector3(0, -drop, 0); Vector3 f6id = f6i + new Vector3(0, -drop, 0); Vector3 f7id = f7i + new Vector3(0, -drop, 0); // Vector2 fuv0 = new Vector2(0, 0); // Vector2 fuv1 = new Vector2(chimney.flueSize.x, 0); // Vector2 fuv2 = new Vector2(fuv1.x + chimney.flueSize.z, 0); // Vector2 fuv3 = new Vector2(fuv2.x + chimney.flueSize.x, 0); // // Vector2 fuv4 = new Vector2(0, chimney.flueSize.y); // Vector2 fuv5 = new Vector2(chimney.flueSize.x, chimney.flueSize.y); // Vector2 fuv6 = new Vector2(fuv1.x + chimney.flueSize.z, chimney.flueSize.y); // Vector2 fuv7 = new Vector2(fuv2.x + chimney.flueSize.x, chimney.flueSize.y); //Flue Sides DYNAMIC_MESH.AddPlane(f0, f1, f4, f5, flueSubmesh); //todo calculate the values for this - don't be lazy DYNAMIC_MESH.AddPlane(f1, f3, f5, f7, flueSubmesh); //todo calculate the values for this - don't be lazy DYNAMIC_MESH.AddPlane(f3, f2, f7, f6, flueSubmesh); //todo calculate the values for this - don't be lazy DYNAMIC_MESH.AddPlane(f2, f0, f6, f4, flueSubmesh); //todo calculate the values for this - don't be lazy //Flue Top DYNAMIC_MESH.AddPlaneComplex(f4, f5, f4i, f5i, Vector3.up, topTangent, flueSubmesh, useFlueSurface); //todo calculate the values for this - don't be lazy DYNAMIC_MESH.AddPlaneComplex(f5, f7, f5i, f7i, Vector3.up, topTangent, flueSubmesh, useFlueSurface); //todo calculate the values for this - don't be lazy DYNAMIC_MESH.AddPlaneComplex(f7, f6, f7i, f6i, Vector3.up, topTangent, flueSubmesh, useFlueSurface); //todo calculate the values for this - don't be lazy DYNAMIC_MESH.AddPlaneComplex(f6, f4, f6i, f4i, Vector3.up, topTangent, flueSubmesh, useFlueSurface); //todo calculate the values for this - don't be lazy //Flue Drop DYNAMIC_MESH.AddPlane(f5id, f4id, f5i, f4i, innerSubmesh); //todo calculate the values for this - don't be lazy DYNAMIC_MESH.AddPlane(f7id, f5id, f7i, f5i, innerSubmesh); //todo calculate the values for this - don't be lazy DYNAMIC_MESH.AddPlane(f6id, f7id, f6i, f7i, innerSubmesh); //todo calculate the values for this - don't be lazy DYNAMIC_MESH.AddPlane(f4id, f6id, f4i, f6i, innerSubmesh); //todo calculate the values for this - don't be lazy DYNAMIC_MESH.AddPlane(f4id, f5id, f6id, f7id, innerSubmesh); //todo calculate the values for this - don't be lazy } else { int vertCount = (chimney.segments + 1) * 2;//add an additonal so we can wrap the UVs well RawMeshData flueOuter = new RawMeshData(vertCount, chimney.segments * 6); RawMeshData flueTop = new RawMeshData(vertCount, chimney.segments * 6); //add additional point for the middle, bottom of the inside of the flue RawMeshData flueInner = new RawMeshData(vertCount + 1, chimney.segments * 9); //the additonal point at the bottom of the flue - added to the end of the mesh data flueInner.vertices[vertCount] = flueBase; flueInner.normals[vertCount] = Vector3.up; flueInner.tangents[vertCount] = new Vector4(1, 0, 0, 0); int indexIm = flueInner.vertCount - 1; float circumference = Mathf.PI * (chimney.flueSize.x + chimney.flueSize.z); for (int s = 0; s < chimney.segments + 1; s++) { float percent = s / (float)(chimney.segments); percent = (percent + (chimney.angleOffset / 360)) % 1f; int indexV0 = s * 2; int indexV1 = s * 2 + 1; int indexV2 = s * 2 + 2; int indexV3 = s * 2 + 3; if (s == chimney.segments - 1) { indexV2 = 0; indexV3 = 1; } float xa = Mathf.Sin(percent * Mathf.PI * 2) * chimney.flueSize.x * 0.5f; float za = Mathf.Cos(percent * Mathf.PI * 2) * chimney.flueSize.z * 0.5f; // float innerHalf = thickness / (chimney.flueSize.x + chimney.flueSize.z) / 2; float xai = Mathf.Sin(percent * Mathf.PI * 2) * chimney.flueSize.x * 0.4f; float zai = Mathf.Cos(percent * Mathf.PI * 2) * chimney.flueSize.z * 0.4f; Vector3 v0 = flueBase + new Vector3(xa, 0, za); Vector3 v1 = flueBase + new Vector3(xa, chimney.flueSize.y, za) + flueNoiseVector; Vector3 v2 = flueBase + new Vector3(xai, chimney.flueSize.y, zai) + flueNoiseVector; Vector3 v3 = flueBase + new Vector3(xai, chimney.flueSize.y * 0.1f, zai); Vector2 uv0 = new Vector2(-circumference * percent, 0); Vector2 uv1 = new Vector2(-circumference * percent, chimney.flueSize.y); Vector2 uv2 = new Vector2(-circumference * percent, chimney.flueSize.y + 0.1f); Vector2 uv3 = new Vector2(-circumference * percent, 0); int rdnFlueSurfaceIndex = RGEN.Index(chimney.flueSurfaces.Count); Surface flueSurface = rdnFlueSurfaceIndex != -1 ? chimney.flueSurfaces[rdnFlueSurfaceIndex] : null; if (flueSurface != null) { uv0 = flueSurface.CalculateUV(uv0); uv1 = flueSurface.CalculateUV(uv1); uv2 = flueSurface.CalculateUV(uv2); uv3 = flueSurface.CalculateUV(uv3); } flueOuter.vertices[indexV0] = v0; flueOuter.vertices[indexV1] = v1; flueOuter.uvs[indexV0] = uv0; flueOuter.uvs[indexV1] = uv1; flueTop.vertices[indexV0] = v1; flueTop.vertices[indexV1] = v2; flueTop.uvs[indexV0] = uv1; flueTop.uvs[indexV1] = uv2; flueInner.vertices[indexV0] = v2; flueInner.vertices[indexV1] = v3; flueInner.uvs[indexV0] = uv2; flueInner.uvs[indexV1] = uv3; Vector3 outerNormal = new Vector3(Mathf.Sin(percent * Mathf.PI * 2), 0, Mathf.Cos(percent * Mathf.PI * 2)); flueOuter.normals[indexV0] = outerNormal; flueOuter.normals[indexV1] = outerNormal; flueTop.normals[indexV0] = Vector3.up; flueTop.normals[indexV1] = Vector3.up; flueInner.normals[indexV0] = -outerNormal; flueInner.normals[indexV1] = -outerNormal; if (s < chimney.segments) { int tidx0 = s * 6; flueOuter.triangles[tidx0 + 0] = indexV0; flueOuter.triangles[tidx0 + 2] = indexV1; flueOuter.triangles[tidx0 + 1] = indexV2; flueOuter.triangles[tidx0 + 3] = indexV1; flueOuter.triangles[tidx0 + 4] = indexV2; flueOuter.triangles[tidx0 + 5] = indexV3; flueTop.triangles[tidx0 + 0] = indexV0; flueTop.triangles[tidx0 + 2] = indexV1; flueTop.triangles[tidx0 + 1] = indexV2; flueTop.triangles[tidx0 + 3] = indexV1; flueTop.triangles[tidx0 + 4] = indexV2; flueTop.triangles[tidx0 + 5] = indexV3; int tidx0i = s * 9; flueInner.triangles[tidx0i + 0] = indexV0; flueInner.triangles[tidx0i + 2] = indexV1; flueInner.triangles[tidx0i + 1] = indexV2; flueInner.triangles[tidx0i + 3] = indexV1; flueInner.triangles[tidx0i + 4] = indexV2; flueInner.triangles[tidx0i + 5] = indexV3; flueInner.triangles[tidx0i + 6] = indexV1; flueInner.triangles[tidx0i + 7] = indexV3; flueInner.triangles[tidx0i + 8] = indexIm; } } DYNAMIC_MESH.AddData(flueOuter, flueSubmesh); DYNAMIC_MESH.AddData(flueTop, flueSubmesh); DYNAMIC_MESH.AddData(flueInner, innerSubmesh); } } } if (output.raw != null) { output.raw.Copy(DYNAMIC_MESH); } if (output.mesh != null) { output.mesh.Clear(false); DYNAMIC_MESH.Build(output.mesh); } }