private void GenerateSymmetrical() { tsMesh.vertices = new Vector3[clippedSamples.Length * _slices * 2]; tsMesh.normals = new Vector3[tsMesh.vertices.Length]; tsMesh.uv = new Vector2[tsMesh.vertices.Length]; tsMesh.colors = new Color[tsMesh.vertices.Length]; int vertIndex = 0; float avgTop = 0f; float avgBottom = 0f; for (int i = 0; i < clippedSamples.Length; i++) { Vector3 top = clippedSamples[i].position; Vector3 bottom = top; Vector3 normal = Vector3.right; float heightPercent = 1f; switch (_axis) { case Axis.X: bottom.x = computer.position.x + (computer.position.x - top.x); heightPercent = uvScale.y * Mathf.Abs(top.x - bottom.x); avgTop += top.x; avgBottom = computer.position.x; break; case Axis.Y: bottom.y = computer.position.y + (computer.position.y - top.y); heightPercent = uvScale.y * Mathf.Abs(top.y - bottom.y); normal = Vector3.up; avgTop += top.y; avgBottom = computer.position.y; break; case Axis.Z: bottom.z = computer.position.z + (computer.position.z - top.z); heightPercent = uvScale.y * Mathf.Abs(top.z - bottom.z); normal = Vector3.forward; avgTop += top.z; avgBottom = computer.position.z; break; } Vector3 right = Vector3.Cross(normal, clippedSamples[i].direction).normalized; Vector3 offsetRight = Vector3.Cross(clippedSamples[i].normal, clippedSamples[i].direction); for (int n = 0; n < _slices * 2; n++) { float slicePercent = ((float)n / _slices); tsMesh.vertices[vertIndex] = Vector3.Lerp(bottom, top, slicePercent) + normal * offset.y + offsetRight * offset.x; tsMesh.normals[vertIndex] = right; if (flipFaces) { tsMesh.normals[vertIndex] *= -1; } if (_uvWrapMode == UVWrapMode.Clamp) { tsMesh.uv[vertIndex] = new Vector2((float)clippedSamples[i].percent * uvScale.x + uvOffset.x, slicePercent * uvScale.y + uvOffset.y); } else { tsMesh.uv[vertIndex] = new Vector2((float)clippedSamples[i].percent * uvScale.x + uvOffset.x, (0.5f - 0.5f * heightPercent + heightPercent * slicePercent) * uvScale.y + uvOffset.y); } tsMesh.colors[vertIndex] = clippedSamples[i].color * color; vertIndex++; } } if (clippedSamples.Length > 0) { avgTop /= clippedSamples.Length; } bool flip = flipFaces; if (avgTop * 2f < avgBottom) { flip = !flip; } tsMesh.triangles = MeshUtility.GeneratePlaneTriangles(_slices * 2 - 1, clippedSamples.Length, flip); }
void Generate() { int vertexIndex = 0; ResetUVDistance(); bool hasOffset = offset != Vector3.zero; for (int i = 0; i < sampleCount; i++) { GetSample(i, evalResult); Vector3 center = evalResult.position; Vector3 right = evalResult.right; if (hasOffset) { center += offset.x * right + offset.y * evalResult.up + offset.z * evalResult.forward; } if (uvMode == UVMode.UniformClamp || uvMode == UVMode.UniformClip) { AddUVDistance(i); } Color vertexColor = evalResult.color * color; for (int n = 0; n < _sides + 1; n++) { float anglePercent = (float)(n) / _sides; Quaternion rot = Quaternion.AngleAxis(_revolve * anglePercent + rotation + 180f, evalResult.forward); tsMesh.vertices[vertexIndex] = center + rot * right * size * evalResult.size * 0.5f; CalculateUVs(evalResult.percent, anglePercent); tsMesh.uv[vertexIndex] = Vector2.one * 0.5f + (Vector2)(Quaternion.AngleAxis(uvRotation + 180f, Vector3.forward) * (Vector2.one * 0.5f - (uvs + Vector2.right * (float)evalResult.percent * _uvTwist))); tsMesh.normals[vertexIndex] = Vector3.Normalize(tsMesh.vertices[vertexIndex] - center); tsMesh.colors[vertexIndex] = vertexColor; vertexIndex++; } } MeshUtility.GeneratePlaneTriangles(ref tsMesh.triangles, _sides, sampleCount, false); }
void Generate() { int vertexIndex = 0; ResetUVDistance(); for (int i = 0; i < clippedSamples.Length; i++) { Vector3 center = clippedSamples[i].position; Vector3 right = clippedSamples[i].right; if (offset != Vector3.zero) { center += offset.x * right + offset.y * clippedSamples[i].normal + offset.z * clippedSamples[i].direction; } if (uvMode == UVMode.UniformClamp || uvMode == UVMode.UniformClip) { AddUVDistance(i); } for (int n = 0; n < _sides + 1; n++) { float anglePercent = (float)(n) / _sides; Quaternion rot = Quaternion.AngleAxis(_integrity * anglePercent + rotation + 180f, clippedSamples[i].direction); tsMesh.vertices[vertexIndex] = center + rot * right * size * clippedSamples[i].size * 0.5f; CalculateUVs(clippedSamples[i].percent, anglePercent); tsMesh.uv[vertexIndex] = Vector2.one * 0.5f + (Vector2)(Quaternion.AngleAxis(uvRotation, Vector3.forward) * (Vector2.one * 0.5f - uvs)); tsMesh.normals[vertexIndex] = Vector3.Normalize(tsMesh.vertices[vertexIndex] - center); tsMesh.colors[vertexIndex] = clippedSamples[i].color * color; vertexIndex++; } } MeshUtility.GeneratePlaneTriangles(ref tsMesh.triangles, _sides, clippedSamples.Length, false); }
private void GenerateDefault() { int vertexCount = clippedSamples.Length * (_slices + 1); AllocateMesh(vertexCount, _slices * (clippedSamples.Length - 1) * 6); int vertIndex = 0; float avgTop = 0f; float avgBottom = 0f; float totalLength = 0f; for (int i = 0; i < clippedSamples.Length; i++) { Vector3 top = clippedSamples[i].position; Vector3 bottom = top; Vector3 normal = Vector3.right; float heightPercent = 1f; if (_uvWrapMode == UVWrapMode.UniformX || _uvWrapMode == UVWrapMode.Uniform) { if (i > 0) { totalLength += Vector3.Distance(clippedSamples[i].position, clippedSamples[i - 1].position); } } switch (_axis) { case Axis.X: avgBottom = bottom.x = computer.position.x; heightPercent = uvScale.y * Mathf.Abs(top.x - bottom.x); avgTop += top.x; break; case Axis.Y: avgBottom = bottom.y = computer.position.y; heightPercent = uvScale.y * Mathf.Abs(top.y - bottom.y); normal = Vector3.up; avgTop += top.y; break; case Axis.Z: avgBottom = bottom.z = computer.position.z; heightPercent = uvScale.y * Mathf.Abs(top.z - bottom.z); normal = Vector3.forward; avgTop += top.z; break; } Vector3 right = Vector3.Cross(normal, clippedSamples[i].direction).normalized; Vector3 offsetRight = Vector3.Cross(clippedSamples[i].normal, clippedSamples[i].direction); for (int n = 0; n < _slices + 1; n++) { float slicePercent = ((float)n / _slices); tsMesh.vertices[vertIndex] = Vector3.Lerp(bottom, top, slicePercent) + normal * offset.y + offsetRight * offset.x; tsMesh.normals[vertIndex] = right; switch (_uvWrapMode) { case UVWrapMode.Clamp: tsMesh.uv[vertIndex] = new Vector2((float)clippedSamples[i].percent * uvScale.x + uvOffset.x, slicePercent * uvScale.y + uvOffset.y); break; case UVWrapMode.UniformX: tsMesh.uv[vertIndex] = new Vector2(totalLength * uvScale.x + uvOffset.x, slicePercent * uvScale.y + uvOffset.y); break; case UVWrapMode.UniformY: tsMesh.uv[vertIndex] = new Vector2((float)clippedSamples[i].percent * uvScale.x + uvOffset.x, heightPercent * slicePercent * uvScale.y + uvOffset.y); break; case UVWrapMode.Uniform: tsMesh.uv[vertIndex] = new Vector2(totalLength * uvScale.x + uvOffset.x, heightPercent * slicePercent * uvScale.y + uvOffset.y); break; } tsMesh.colors[vertIndex] = clippedSamples[i].color * color; vertIndex++; } } if (clippedSamples.Length > 0) { avgTop /= clippedSamples.Length; } MeshUtility.GeneratePlaneTriangles(ref tsMesh.triangles, _slices, clippedSamples.Length, avgTop < avgBottom); }
protected override void BuildMesh() { if (base.clippedSamples.Length != 0) { base.BuildMesh(); GenerateVertices(); MeshUtility.GeneratePlaneTriangles(ref tsMesh.triangles, _slices, base.clippedSamples.Length, flip: false, 0, 0, reallocateArray: true); } }
protected override void BuildMesh() { if (sampleCount == 0) { return; } base.BuildMesh(); GenerateVertices(); MeshUtility.GeneratePlaneTriangles(ref tsMesh.triangles, _slices, sampleCount, false); }
protected override void BuildMesh() { if (clippedSamples.Length == 0) { return; } base.BuildMesh(); GenerateVertices(); MeshUtility.GeneratePlaneTriangles(ref tsMesh.triangles, _slices, clippedSamples.Length, false); }
void GenerateTriangles() { bool closed = _integrity == 360f; int faces = _sides * (clippedSamples.Length - 1); int indexCount = faces * 2 * 3; int t = indexCount; if (useCap) { indexCount += (_sides - 1) * 3 * 2; } tsMesh.triangles = new int[indexCount]; MeshUtility.GeneratePlaneTriangles(_sides, clippedSamples.Length, flipFaces && !doubleSided).CopyTo(tsMesh.triangles, 0); if (useCap) { int finalSides = closed ? _sides - 1 : _sides; int vertexCount = (_sides + 1) * clippedSamples.Length; //Start cap for (int i = 0; i < finalSides - 1; i++) { if (flipFaces && !doubleSided) { tsMesh.triangles[t++] = vertexCount; tsMesh.triangles[t++] = i + vertexCount + 1; tsMesh.triangles[t++] = i + vertexCount + 2; } else { tsMesh.triangles[t++] = i + vertexCount + 2; tsMesh.triangles[t++] = i + +vertexCount + 1; tsMesh.triangles[t++] = vertexCount; } } //End cap for (int i = 0; i < finalSides - 1; i++) { if (flipFaces && !doubleSided) { tsMesh.triangles[t++] = i + 2 + vertexCount + (_sides + 1); tsMesh.triangles[t++] = i + 1 + vertexCount + (_sides + 1); tsMesh.triangles[t++] = vertexCount + (_sides + 1); } else { tsMesh.triangles[t++] = vertexCount + (_sides + 1); tsMesh.triangles[t++] = i + 1 + vertexCount + (_sides + 1); tsMesh.triangles[t++] = i + 2 + vertexCount + (_sides + 1); } } } }
protected override void BuildMesh() { if (clippedSamples.Length == 0) { return; } base.BuildMesh(); GenerateVertices(); tsMesh.triangles = MeshUtility.GeneratePlaneTriangles(_slices, clippedSamples.Length, false); if (doubleSided) { MeshUtility.MakeDoublesided(tsMesh); } if (calculateTangents) { MeshUtility.CalculateTangents(tsMesh); } }
private void Generate() { int num = 0; ResetUVDistance(); for (int i = 0; i < base.clippedSamples.Length; i++) { Vector3 vector = base.clippedSamples[i].position; Vector3 right = base.clippedSamples[i].right; if (base.offset != Vector3.zero) { Vector3 a = vector; Vector3 offset = base.offset; Vector3 a2 = offset.x * right; Vector3 offset2 = base.offset; Vector3 a3 = a2 + offset2.y * base.clippedSamples[i].normal; Vector3 offset3 = base.offset; vector = a + (a3 + offset3.z * base.clippedSamples[i].direction); } if (base.uvMode == UVMode.UniformClamp || base.uvMode == UVMode.UniformClip) { AddUVDistance(i); } for (int j = 0; j < _sides + 1; j++) { float num2 = (float)j / (float)_sides; Quaternion rotation = Quaternion.AngleAxis(_integrity * num2 + base.rotation + 180f, base.clippedSamples[i].direction); tsMesh.vertices[num] = vector + rotation * right * base.size * base.clippedSamples[i].size * 0.5f; CalculateUVs(base.clippedSamples[i].percent, num2); tsMesh.uv[num] = Vector2.one * 0.5f + (Vector2)(Quaternion.AngleAxis(base.uvRotation, Vector3.forward) * (Vector2.one * 0.5f - MeshGenerator.uvs)); tsMesh.normals[num] = Vector3.Normalize(tsMesh.vertices[num] - vector); tsMesh.colors[num] = base.clippedSamples[i].color * base.color; num++; } } MeshUtility.GeneratePlaneTriangles(ref tsMesh.triangles, _sides, base.clippedSamples.Length, flip: false); }
public void Generate() { if (_extrudeComputer != null) { _extrudeComputer.Evaluate(ref extrudeResults, _extrudeFrom, _extrudeTo); } int capVertexCount = clippedSamples.Length; int wallVertexCount = 0; int totalVertexCount = 0; if (computer.isClosed) { capVertexCount--; } bool pathExtrude = _extrudeComputer != null && extrudeResults.Length > 0; bool simpleExtrude = !pathExtrude && _extrude != 0f; totalVertexCount = capVertexCount; if (pathExtrude) { wallVertexCount = clippedSamples.Length * extrudeResults.Length; totalVertexCount = capVertexCount * 2 + wallVertexCount; } else if (simpleExtrude) { wallVertexCount = clippedSamples.Length * 2; totalVertexCount = capVertexCount * 2 + wallVertexCount; } if (tsMesh.vertexCount != totalVertexCount) { tsMesh.vertices = new Vector3[totalVertexCount]; tsMesh.normals = new Vector3[totalVertexCount]; tsMesh.colors = new Color[totalVertexCount]; tsMesh.uv = new Vector2[totalVertexCount]; } Vector3 avgPos = Vector3.zero; Vector3 avgNormal = Vector3.zero; for (int i = 0; i < capVertexCount; i++) { tsMesh.vertices[i] = clippedSamples[i].position; tsMesh.normals[i] = clippedSamples[i].normal; tsMesh.colors[i] = clippedSamples[i].color; tsMesh.colors[i] *= color; avgPos += tsMesh.vertices[i]; avgNormal += tsMesh.normals[i]; } avgNormal.Normalize(); avgPos /= capVertexCount; GetProjectedVertices(tsMesh.vertices, avgNormal, avgPos, capVertexCount); Vector2 min = projectedVerts[0]; Vector2 max = projectedVerts[0]; for (int i = 1; i < projectedVerts.Length; i++) { if (min.x < projectedVerts[i].x) { min.x = projectedVerts[i].x; } if (min.y < projectedVerts[i].y) { min.y = projectedVerts[i].y; } if (max.x > projectedVerts[i].x) { max.x = projectedVerts[i].x; } if (max.y > projectedVerts[i].y) { max.y = projectedVerts[i].y; } } for (int i = 0; i < projectedVerts.Length; i++) { tsMesh.uv[i].x = Mathf.InverseLerp(max.x, min.x, projectedVerts[i].x) * uvScale.x - uvScale.x * 0.5f + uvOffset.x + 0.5f; tsMesh.uv[i].y = Mathf.InverseLerp(min.y, max.y, projectedVerts[i].y) * uvScale.y - uvScale.y * 0.5f + uvOffset.y + 0.5f; } bool clockwise = IsClockwise(projectedVerts); bool flipCap = flipFaces; bool flipSide = flipFaces; if (!clockwise) { flipSide = !flipSide; } if (simpleExtrude && _extrude < 0f) { flipCap = !flipCap; flipSide = !flipSide; } GenerateCapTris(flipCap); if (flipCap) { for (int i = 0; i < capVertexCount; i++) { tsMesh.normals[i] *= -1f; } } if (pathExtrude) { GetIdentityVerts(avgPos, avgNormal, clockwise); //Generate cap vertices with flipped normals for (int i = 0; i < capVertexCount; i++) { tsMesh.vertices[i + capVertexCount] = extrudeResults[0].position + extrudeResults[0].rotation * identityVertices[i]; tsMesh.normals[i + capVertexCount] = -extrudeResults[0].direction; tsMesh.colors[i + capVertexCount] = tsMesh.colors[i] * extrudeResults[0].color; tsMesh.uv[i + capVertexCount] = new Vector2(1f - tsMesh.uv[i].x, tsMesh.uv[i].y); tsMesh.vertices[i] = extrudeResults[extrudeResults.Length - 1].position + extrudeResults[extrudeResults.Length - 1].rotation * identityVertices[i]; tsMesh.normals[i] = extrudeResults[extrudeResults.Length - 1].direction; tsMesh.colors[i] *= extrudeResults[extrudeResults.Length - 1].color; } //Add wall vertices float totalLength = 0f; for (int i = 0; i < extrudeResults.Length; i++) { if (_uniformUvs && i > 0) { totalLength += Vector3.Distance(extrudeResults[i].position, extrudeResults[i - 1].position); } int startIndex = capVertexCount * 2 + i * clippedSamples.Length; for (int n = 0; n < identityVertices.Length; n++) { tsMesh.vertices[startIndex + n] = extrudeResults[i].position + extrudeResults[i].rotation * identityVertices[n]; tsMesh.normals[startIndex + n] = extrudeResults[i].rotation * identityNormals[n]; if (_uniformUvs) { tsMesh.uv[startIndex + n] = new Vector2((float)n / (identityVertices.Length - 1) * _sideUvScale.x + _sideUvOffset.x, totalLength * _sideUvScale.y + _sideUvOffset.y); } else { tsMesh.uv[startIndex + n] = new Vector2((float)n / (identityVertices.Length - 1) * _sideUvScale.x + _sideUvOffset.x, (float)i / (extrudeResults.Length - 1) * _sideUvScale.y + _sideUvOffset.y); } if (clockwise) { tsMesh.uv[startIndex + n].x = 1f - tsMesh.uv[startIndex + n].x; } } } wallTris = MeshUtility.GeneratePlaneTriangles(clippedSamples.Length - 1, extrudeResults.Length, flipSide); tsMesh.triangles = new int[capTris.Length * 2 + wallTris.Length]; int written = WriteTris(ref capTris, ref tsMesh.triangles, 0, 0, false); written = WriteTris(ref capTris, ref tsMesh.triangles, capVertexCount, written, true); written = WriteTris(ref wallTris, ref tsMesh.triangles, capVertexCount * 2, written, false); } else if (simpleExtrude) { //Duplicate cap vertices with flipped normals for (int i = 0; i < capVertexCount; i++) { tsMesh.vertices[i + capVertexCount] = tsMesh.vertices[i]; if (_expand != 0f) { tsMesh.vertices[i + capVertexCount] += (clockwise ? -clippedSamples[i].right : clippedSamples[i].right) * _expand; } tsMesh.normals[i + capVertexCount] = -tsMesh.normals[i]; tsMesh.colors[i + capVertexCount] = tsMesh.colors[i]; tsMesh.uv[i + capVertexCount] = new Vector2(1f - tsMesh.uv[i].x, tsMesh.uv[i].y); tsMesh.vertices[i] += avgNormal * _extrude; if (_expand != 0f) { tsMesh.vertices[i] += (clockwise ? -clippedSamples[i].right : clippedSamples[i].right) * _expand; } } //Add wall vertices for (int i = 0; i < clippedSamples.Length; i++) { tsMesh.vertices[i + capVertexCount * 2] = clippedSamples[i].position; if (_expand != 0f) { tsMesh.vertices[i + capVertexCount * 2] += (clockwise ? -clippedSamples[i].right : clippedSamples[i].right) * _expand; } tsMesh.normals[i + capVertexCount * 2] = clockwise ? -clippedSamples[i].right : clippedSamples[i].right; tsMesh.colors[i + capVertexCount * 2] = clippedSamples[i].color; tsMesh.uv[i + capVertexCount * 2] = new Vector2((float)i / (capVertexCount - 1) * _sideUvScale.x + _sideUvOffset.x, 0f + _sideUvOffset.y); if (clockwise) { tsMesh.uv[i + capVertexCount * 2].x = 1f - tsMesh.uv[i + capVertexCount * 2].x; } tsMesh.vertices[i + capVertexCount * 2 + clippedSamples.Length] = tsMesh.vertices[i + capVertexCount * 2] + avgNormal * _extrude; tsMesh.normals[i + capVertexCount * 2 + clippedSamples.Length] = clockwise ? -clippedSamples[i].right : clippedSamples[i].right; tsMesh.colors[i + capVertexCount * 2 + clippedSamples.Length] = clippedSamples[i].color; if (_uniformUvs) { tsMesh.uv[i + capVertexCount * 2 + clippedSamples.Length] = new Vector2((float)i / (capVertexCount - 1) * _sideUvScale.x + _sideUvOffset.x, _extrude * _sideUvScale.y + _sideUvOffset.y); } else { tsMesh.uv[i + capVertexCount * 2 + clippedSamples.Length] = new Vector2((float)i / (capVertexCount - 1) * _sideUvScale.x + _sideUvOffset.x, 1f * _sideUvScale.y + _sideUvOffset.y); } if (clockwise) { tsMesh.uv[i + capVertexCount * 2 + clippedSamples.Length].x = 1f - tsMesh.uv[i + capVertexCount * 2 + clippedSamples.Length].x; } } wallTris = MeshUtility.GeneratePlaneTriangles(clippedSamples.Length - 1, 2, flipSide); tsMesh.triangles = new int[capTris.Length * 2 + wallTris.Length]; int written = WriteTris(ref capTris, ref tsMesh.triangles, 0, 0, false); written = WriteTris(ref capTris, ref tsMesh.triangles, capVertexCount, written, true); written = WriteTris(ref wallTris, ref tsMesh.triangles, capVertexCount * 2, written, false); } else { //for (int i = 0; i < tsMesh.vertices.Length; i++) tsMesh.vertices[i] += clockwise ? -clippedSamples[i].right : clippedSamples[i].right; tsMesh.triangles = new int[capTris.Length]; WriteTris(ref capTris, ref tsMesh.triangles, 0, 0, false); } }
public void Generate() { int surfaceVertexCount = sampleCount; if (spline.isClosed) { surfaceVertexCount--; } int vertexCount = surfaceVertexCount; if (_extrudeSpline != null) { _extrudeSpline.Evaluate(ref extrudeResults, _extrudeFrom, _extrudeTo); } else if (extrudeResults.Length > 0) { extrudeResults = new SplineSample[0]; } bool pathExtrude = _extrudeSpline && extrudeResults.Length > 0; bool simpleExtrude = !pathExtrude && _extrude != 0f; if (pathExtrude) { vertexCount *= 2; vertexCount += sampleCount * extrudeResults.Length; } else if (simpleExtrude) { vertexCount *= 4; vertexCount += 2; } Vector3 center, normal; GetProjectedVertices(surfaceVertexCount, out center, out normal); bool clockwise = IsClockwise(projectedVerts); bool flipCap = false; bool flipSide = false; if (!clockwise) { flipSide = !flipSide; } if (simpleExtrude && _extrude < 0f) { flipCap = !flipCap; flipSide = !flipSide; } GenerateSurfaceTris(flipCap); int totalTrisCount = surfaceTris.Length; if (simpleExtrude) { totalTrisCount *= 2; totalTrisCount += 2 * sampleCount * 2 * 3; } else { totalTrisCount *= 2; totalTrisCount += extrudeResults.Length * sampleCount * 2 * 3; } AllocateMesh(vertexCount, totalTrisCount); Vector3 off = trs.right * offset.x + trs.up * offset.y + trs.forward * offset.z; for (int i = 0; i < surfaceVertexCount; i++) { GetSample(i, evalResult); tsMesh.vertices[i] = evalResult.position + off; tsMesh.normals[i] = evalResult.up; tsMesh.colors[i] = evalResult.color * color; } #region UVs Vector2 min = projectedVerts[0]; Vector2 max = projectedVerts[0]; for (int i = 1; i < projectedVerts.Length; i++) { if (min.x < projectedVerts[i].x) { min.x = projectedVerts[i].x; } if (min.y < projectedVerts[i].y) { min.y = projectedVerts[i].y; } if (max.x > projectedVerts[i].x) { max.x = projectedVerts[i].x; } if (max.y > projectedVerts[i].y) { max.y = projectedVerts[i].y; } } for (int i = 0; i < projectedVerts.Length; i++) { tsMesh.uv[i].x = Mathf.InverseLerp(max.x, min.x, projectedVerts[i].x) * uvScale.x - uvScale.x * 0.5f + uvOffset.x + 0.5f; tsMesh.uv[i].y = Mathf.InverseLerp(min.y, max.y, projectedVerts[i].y) * uvScale.y - uvScale.y * 0.5f + uvOffset.y + 0.5f; } #endregion if (flipCap) { for (int i = 0; i < surfaceVertexCount; i++) { tsMesh.normals[i] *= -1f; } } if (_expand != 0f) { for (int i = 0; i < surfaceVertexCount; i++) { GetSample(i, evalResult); tsMesh.vertices[i] += (clockwise ? -evalResult.right : evalResult.right) * _expand; } } if (pathExtrude) { GetIdentityVerts(center, normal, clockwise); //Generate cap vertices with flipped normals for (int i = 0; i < surfaceVertexCount; i++) { tsMesh.vertices[i + surfaceVertexCount] = extrudeResults[0].position + extrudeResults[0].rotation * identityVertices[i] + off; tsMesh.normals[i + surfaceVertexCount] = -extrudeResults[0].forward; tsMesh.colors[i + surfaceVertexCount] = tsMesh.colors[i] * extrudeResults[0].color; tsMesh.uv[i + surfaceVertexCount] = new Vector2(1f - tsMesh.uv[i].x, tsMesh.uv[i].y); tsMesh.vertices[i] = extrudeResults[extrudeResults.Length - 1].position + extrudeResults[extrudeResults.Length - 1].rotation * identityVertices[i] + off; tsMesh.normals[i] = extrudeResults[extrudeResults.Length - 1].forward; tsMesh.colors[i] *= extrudeResults[extrudeResults.Length - 1].color; } //Add wall vertices float totalLength = 0f; for (int i = 0; i < extrudeResults.Length; i++) { if (_uniformUvs && i > 0) { totalLength += Vector3.Distance(extrudeResults[i].position, extrudeResults[i - 1].position); } int startIndex = surfaceVertexCount * 2 + i * sampleCount; for (int n = 0; n < identityVertices.Length; n++) { tsMesh.vertices[startIndex + n] = extrudeResults[i].position + extrudeResults[i].rotation * identityVertices[n] + off; tsMesh.normals[startIndex + n] = extrudeResults[i].rotation * identityNormals[n]; if (_uniformUvs) { tsMesh.uv[startIndex + n] = new Vector2((float)n / (identityVertices.Length - 1) * _sideUvScale.x + _sideUvOffset.x, totalLength * _sideUvScale.y + _sideUvOffset.y); } else { tsMesh.uv[startIndex + n] = new Vector2((float)n / (identityVertices.Length - 1) * _sideUvScale.x + _sideUvOffset.x, (float)i / (extrudeResults.Length - 1) * _sideUvScale.y + _sideUvOffset.y); } if (clockwise) { tsMesh.uv[startIndex + n].x = 1f - tsMesh.uv[startIndex + n].x; } } } int written = WriteTris(ref surfaceTris, ref tsMesh.triangles, 0, 0, false); written = WriteTris(ref surfaceTris, ref tsMesh.triangles, surfaceVertexCount, written, true); MeshUtility.GeneratePlaneTriangles(ref wallTris, sampleCount - 1, extrudeResults.Length, flipSide, 0, 0, true); WriteTris(ref wallTris, ref tsMesh.triangles, surfaceVertexCount * 2, written, false); } else if (simpleExtrude) { //Duplicate cap vertices with flipped normals for (int i = 0; i < surfaceVertexCount; i++) { tsMesh.vertices[i + surfaceVertexCount] = tsMesh.vertices[i]; tsMesh.normals[i + surfaceVertexCount] = -tsMesh.normals[i]; tsMesh.colors[i + surfaceVertexCount] = tsMesh.colors[i]; tsMesh.uv[i + surfaceVertexCount] = new Vector2(1f - tsMesh.uv[i].x, tsMesh.uv[i].y); tsMesh.vertices[i] += normal * _extrude; } //Add wall vertices for (int i = 0; i < surfaceVertexCount + 1; i++) { int index = i; if (i >= surfaceVertexCount) { index = i - surfaceVertexCount; } GetSample(index, evalResult); tsMesh.vertices[i + surfaceVertexCount * 2] = tsMesh.vertices[index] - normal * _extrude; tsMesh.normals[i + surfaceVertexCount * 2] = clockwise ? -evalResult.right : evalResult.right; tsMesh.colors[i + surfaceVertexCount * 2] = tsMesh.colors[index]; tsMesh.uv[i + surfaceVertexCount * 2] = new Vector2((float)i / (surfaceVertexCount - 1) * _sideUvScale.x + _sideUvOffset.x, 0f + _sideUvOffset.y); if (clockwise) { tsMesh.uv[i + surfaceVertexCount * 2].x = 1f - tsMesh.uv[i + surfaceVertexCount * 2].x; } int offsetIndex = i + surfaceVertexCount * 3 + 1; tsMesh.vertices[offsetIndex] = tsMesh.vertices[index]; tsMesh.normals[offsetIndex] = tsMesh.normals[i + surfaceVertexCount * 2]; tsMesh.colors[offsetIndex] = tsMesh.colors[index]; if (_uniformUvs) { tsMesh.uv[offsetIndex] = new Vector2((float)i / surfaceVertexCount * _sideUvScale.x + _sideUvOffset.x, _extrude * _sideUvScale.y + _sideUvOffset.y); } else { tsMesh.uv[offsetIndex] = new Vector2((float)i / surfaceVertexCount * _sideUvScale.x + _sideUvOffset.x, 1f * _sideUvScale.y + _sideUvOffset.y); } if (clockwise) { tsMesh.uv[offsetIndex].x = 1f - tsMesh.uv[offsetIndex].x; } } int written = WriteTris(ref surfaceTris, ref tsMesh.triangles, 0, 0, false); written = WriteTris(ref surfaceTris, ref tsMesh.triangles, surfaceVertexCount, written, true); MeshUtility.GeneratePlaneTriangles(ref wallTris, sampleCount - 1, 2, flipSide, 0, 0, true); WriteTris(ref wallTris, ref tsMesh.triangles, surfaceVertexCount * 2, written, false); } else { WriteTris(ref surfaceTris, ref tsMesh.triangles, 0, 0, false); } }
private void Generate() { int vertexCount = clippedSamples.Length * (_slices + 1); AllocateMesh(vertexCount, _slices * (clippedSamples.Length - 1) * 6); int vertIndex = 0; float avgTop = 0f; float totalLength = 0f; SplineComputer rootComputer = rootUser.computer; Vector3 computerPosition = rootComputer.position; Vector3 normal = rootComputer.TransformDirection(Vector3.right); switch (_axis) { case Axis.Y: normal = rootComputer.TransformDirection(Vector3.up); break; case Axis.Z: normal = rootComputer.TransformDirection(Vector3.forward); break; } for (int i = 0; i < clippedSamples.Length; i++) { Vector3 samplePosition = clippedSamples[i].position; Vector3 localSamplePosition = rootComputer.InverseTransformPoint(samplePosition); Vector3 bottomPosition = localSamplePosition; Vector3 sampleDirection = clippedSamples[i].direction; Vector3 sampleNormal = clippedSamples[i].normal; float heightPercent = 1f; if (_uvWrapMode == UVWrapMode.UniformX || _uvWrapMode == UVWrapMode.Uniform) { if (i > 0) { totalLength += Vector3.Distance(clippedSamples[i].position, clippedSamples[i - 1].position); } } switch (_axis) { case Axis.X: bottomPosition.x = _symmetry ? -localSamplePosition.x : 0f; heightPercent = uvScale.y * Mathf.Abs(localSamplePosition.x); avgTop += localSamplePosition.x; break; case Axis.Y: bottomPosition.y = _symmetry ? -localSamplePosition.y : 0f; heightPercent = uvScale.y * Mathf.Abs(localSamplePosition.y); avgTop += localSamplePosition.y; break; case Axis.Z: bottomPosition.z = _symmetry ? -localSamplePosition.z : 0f; heightPercent = uvScale.y * Mathf.Abs(localSamplePosition.z); avgTop += localSamplePosition.z; break; } bottomPosition = rootComputer.TransformPoint(bottomPosition); Vector3 right = Vector3.Cross(normal, sampleDirection).normalized; Vector3 offsetRight = Vector3.Cross(sampleNormal, sampleDirection); for (int n = 0; n < _slices + 1; n++) { float slicePercent = ((float)n / _slices); tsMesh.vertices[vertIndex] = Vector3.Lerp(bottomPosition, samplePosition, slicePercent) + normal * offset.y + offsetRight * offset.x; tsMesh.normals[vertIndex] = right; switch (_uvWrapMode) { case UVWrapMode.Clamp: tsMesh.uv[vertIndex] = new Vector2((float)clippedSamples[i].percent * uvScale.x + uvOffset.x, slicePercent * uvScale.y + uvOffset.y); break; case UVWrapMode.UniformX: tsMesh.uv[vertIndex] = new Vector2(totalLength * uvScale.x + uvOffset.x, slicePercent * uvScale.y + uvOffset.y); break; case UVWrapMode.UniformY: tsMesh.uv[vertIndex] = new Vector2((float)clippedSamples[i].percent * uvScale.x + uvOffset.x, heightPercent * slicePercent * uvScale.y + uvOffset.y); break; case UVWrapMode.Uniform: tsMesh.uv[vertIndex] = new Vector2(totalLength * uvScale.x + uvOffset.x, heightPercent * slicePercent * uvScale.y + uvOffset.y); break; } tsMesh.colors[vertIndex] = clippedSamples[i].color * color; vertIndex++; } } if (clippedSamples.Length > 0) { avgTop /= clippedSamples.Length; } MeshUtility.GeneratePlaneTriangles(ref tsMesh.triangles, _slices, clippedSamples.Length, avgTop < 0f); }
protected override void BuildMesh() { base.BuildMesh(); GenerateVertices(vertexDirection, orthographic); MeshUtility.GeneratePlaneTriangles(ref tsMesh.triangles, _slices, sampleCount, false, 0, 0); }
protected override void BuildMesh() { base.BuildMesh(); GenerateVertices(vertexDirection, orthographic); tsMesh.triangles = MeshUtility.GeneratePlaneTriangles(_slices, clippedSamples.Length, false); }
private void Generate() { int vertexCount = sampleCount * (_slices + 1); AllocateMesh(vertexCount, _slices * (sampleCount - 1) * 6); int vertIndex = 0; float avgTop = 0f; float totalLength = 0f; Vector3 computerPosition = spline.position; Vector3 normal = spline.TransformDirection(Vector3.right); switch (_axis) { case Axis.Y: normal = spline.TransformDirection(Vector3.up); break; case Axis.Z: normal = spline.TransformDirection(Vector3.forward); break; } for (int i = 0; i < sampleCount; i++) { evalResult = GetSampleRaw(i); float resultSize = GetBaseSize(evalResult); Vector3 samplePosition = evalResult.position; Vector3 localSamplePosition = spline.InverseTransformPoint(samplePosition); Vector3 bottomPosition = localSamplePosition; Vector3 sampleDirection = evalResult.forward; Vector3 sampleNormal = evalResult.up; float heightPercent = 1f; if (_uvWrapMode == UVWrapMode.UniformX || _uvWrapMode == UVWrapMode.Uniform) { if (i > 0) { totalLength += Vector3.Distance(evalResult.position, GetSampleRaw(i - 1).position); } } switch (_axis) { case Axis.X: bottomPosition.x = _symmetry ? -localSamplePosition.x : 0f; heightPercent = uvScale.y * Mathf.Abs(localSamplePosition.x); avgTop += localSamplePosition.x; break; case Axis.Y: bottomPosition.y = _symmetry ? -localSamplePosition.y : 0f; heightPercent = uvScale.y * Mathf.Abs(localSamplePosition.y); avgTop += localSamplePosition.y; break; case Axis.Z: bottomPosition.z = _symmetry ? -localSamplePosition.z : 0f; heightPercent = uvScale.y * Mathf.Abs(localSamplePosition.z); avgTop += localSamplePosition.z; break; } bottomPosition = spline.TransformPoint(bottomPosition); Vector3 right = Vector3.Cross(normal, sampleDirection).normalized; Vector3 offsetRight = Vector3.Cross(sampleNormal, sampleDirection); for (int n = 0; n < _slices + 1; n++) { float slicePercent = ((float)n / _slices); tsMesh.vertices[vertIndex] = Vector3.Lerp(bottomPosition, samplePosition, slicePercent) + normal * (offset.y * resultSize) + offsetRight * (offset.x * resultSize); tsMesh.normals[vertIndex] = right; switch (_uvWrapMode) { case UVWrapMode.Clamp: tsMesh.uv[vertIndex] = new Vector2((float)evalResult.percent * uvScale.x + uvOffset.x, slicePercent * uvScale.y + uvOffset.y); break; case UVWrapMode.UniformX: tsMesh.uv[vertIndex] = new Vector2(totalLength * uvScale.x + uvOffset.x, slicePercent * uvScale.y + uvOffset.y); break; case UVWrapMode.UniformY: tsMesh.uv[vertIndex] = new Vector2((float)evalResult.percent * uvScale.x + uvOffset.x, heightPercent * slicePercent * uvScale.y + uvOffset.y); break; case UVWrapMode.Uniform: tsMesh.uv[vertIndex] = new Vector2(totalLength * uvScale.x + uvOffset.x, heightPercent * slicePercent * uvScale.y + uvOffset.y); break; } tsMesh.colors[vertIndex] = GetBaseColor(evalResult) * color; vertIndex++; } } if (sampleCount > 0) { avgTop /= sampleCount; } MeshUtility.GeneratePlaneTriangles(ref tsMesh.triangles, _slices, sampleCount, avgTop < 0f); }