private void Generate() { random = new System.Random(_randomSeed); useLastResult = false; iterations = 0; if (_hasStartMesh) { iterations++; } if (_hasEndMesh) { iterations++; } iterations += (extrudableMeshes.Count - 2) * _repeat; double num = 1.0 / (double)iterations; double num2 = num * _spacing * 0.5; if (combineMeshes.Count < iterations) { combineMeshes.AddRange(new TS_Mesh[iterations - combineMeshes.Count]); } else if (combineMeshes.Count > iterations) { combineMeshes.RemoveRange(combineMeshes.Count - 1 - (combineMeshes.Count - iterations), combineMeshes.Count - iterations); } for (int i = 0; i < iterations; i++) { double from = (double)i * num + num2; double to = (double)i * num + num - num2; if (combineMeshes[i] == null) { combineMeshes[i] = new TS_Mesh(); } Stretch(extrudableMeshes[GetMeshIndex(i)], combineMeshes[i], from, to); if (_spacing == 0.0) { useLastResult = true; } } if (_dontStretchCaps) { if (_hasStartMesh) { TS_Mesh tS_Mesh = new TS_Mesh(); TRS(extrudableMeshes[0], tS_Mesh, 0.0); combineMeshes.Add(tS_Mesh); } if (_hasEndMesh) { TS_Mesh tS_Mesh2 = new TS_Mesh(); TRS(extrudableMeshes[1], tS_Mesh2, 1.0); combineMeshes.Add(tS_Mesh2); } } if (tsMesh == null) { tsMesh = new TS_Mesh(); } tsMesh.Combine(combineMeshes, overwrite: true); }
/// <summary> /// Called by the extrusion sequence prior to extruding /// </summary> public void RuntimeInitialize() { if (transform == null) { _error = true; return; } localToWorldMatrix = transform.localToWorldMatrix; localScale = transform.localScale; #if DREAMTECK_SPLINES if (extrusionSettings.bendSpline && splineComputer != null) { splineComputer.ResampleTransform(); } else { extrusionSettings.bendSpline = false; } #endif if (meshFilter != null) { _originalMesh = meshFilter.sharedMesh; if (extrusionSettings.bendMesh) { extrusionMesh = new TS_Mesh(_originalMesh); } } else { extrusionSettings.bendMesh = false; } if (spriteRenderer != null) { if (spriteRenderer.sprite != null) { extrusionSpriteVertices = spriteRenderer.sprite.vertices; extrusionSpriteUVs = spriteRenderer.sprite.uv; } } else { extrusionSettings.bendSprite = false; } if (meshCollider != null) { _originalCollisionMesh = meshCollider.sharedMesh; if (extrusionSettings.meshColliderHandling == ExtrusionSettings.MeshColliderHandling.Extrude) { extrusionCollisionMesh = new TS_Mesh(_originalCollisionMesh); } } else if (extrusionSettings.meshColliderHandling == ExtrusionSettings.MeshColliderHandling.Extrude) { extrusionSettings.meshColliderHandling = ExtrusionSettings.MeshColliderHandling.Bypass; } }
void Generate() { double step = span / _repeat; double space = step * _spacing * 0.5; useLastResult = false; if (combineMeshes.Length != _repeat) { combineMeshes = new TS_Mesh[_repeat]; } for (int i = 0; i < _repeat; i++) { if (combineMeshes[i] == null) { combineMeshes[i] = new TS_Mesh(); } double from = clipFrom + i * step + space; double to = clipFrom + i * step + step - space; if (middleMesh != null && space == 0f) { if (computer.isClosed && span >= 1f) { combineMeshes[i].Absorb(middleMesh); } else if (i > 0 && i < _repeat - 1) { combineMeshes[i].Absorb(middleMesh); } else if (i == 0) { combineMeshes[i].Absorb(startMesh); } else if (i == _repeat - 1) { combineMeshes[i].Absorb(endMesh); } else { combineMeshes[i].Absorb(inputMesh); } } else { combineMeshes[i].Absorb(inputMesh); } combineMeshes[i] = Stretch(combineMeshes[i], from, to); if (_spacing == 0f) { useLastResult = true; } } tsMesh = new TS_Mesh(); tsMesh.Combine(combineMeshes); }
private void StripFaces(TS_Mesh input, List <int> toStrip) { int[] newTris = new int[input.triangles.Length - toStrip.Count * 3]; int removed = 0; toStrip.Sort(); for (int i = 0; i < input.triangles.Length; i += 3) { if (removed < toStrip.Count) { if (i == toStrip[removed]) { removed++; continue; } } if (i - removed * 3 >= newTris.Length - 2) { break; } // Debug.Log("Face: " + (i - removed * 3) + ", " + (i - removed * 3 + 1) + ", " + (i - removed * 3 + 2) + " total faces: " + newTris.Length + " total removed so far: " + removed * 3 + " out of " + toStrip.Count*3); newTris[i - removed * 3] = input.triangles[i]; newTris[i + 1 - removed * 3] = input.triangles[i + 1]; newTris[i + 2 - removed * 3] = input.triangles[i + 2]; } removed = 0; for (int i = 0; i < input.subMeshes.Count; i++) { List <int> submesh = new List <int>(); for (int n = 0; n < input.subMeshes[i].Length; n += 3) { if (removed < toStrip.Count) { if (input.subMeshes[i][n] == input.triangles[toStrip[removed]]) { if (input.subMeshes[i][n + 1] == input.triangles[toStrip[removed] + 1]) { if (input.subMeshes[i][n + 2] == input.triangles[toStrip[removed] + 2]) { removed++; continue; } } } } submesh.Add(input.subMeshes[i][n]); submesh.Add(input.subMeshes[i][n + 1]); submesh.Add(input.subMeshes[i][n + 2]); } input.subMeshes[i] = submesh.ToArray(); } input.triangles = newTris; }
void SetMesh() { inputMesh = new TS_Mesh(sourceMesh); GroupVertices(); if (_removeInnerFaces) { GenerateInnerMesh(); } else { middleMesh = startMesh = endMesh = null; } }
private void TRS(ExtrudableMesh source, TS_Mesh target, double percent) { CreateTSFromExtrudableMesh(source, ref target); SplineResult splineResult = Evaluate(percent); Quaternion rhs = Quaternion.identity; switch (axis) { case Axis.X: rhs = Quaternion.LookRotation(Vector3.right); break; case Axis.Y: rhs = Quaternion.LookRotation(Vector3.up, Vector3.back); break; } ref Matrix4x4 reference = ref vertexMatrix;
private void CreateTSFromExtrudableMesh(ExtrudableMesh source, ref TS_Mesh target) { if (target.vertices.Length != source.vertices.Length) { target.vertices = new Vector3[source.vertices.Length]; } if (target.normals.Length != source.normals.Length) { target.normals = new Vector3[source.normals.Length]; } if (target.tangents.Length != source.tangents.Length) { target.tangents = new Vector4[source.tangents.Length]; } if (target.colors.Length != source.colors.Length) { target.colors = new Color[source.colors.Length]; } if (target.uv.Length != source.uv.Length) { target.uv = new Vector2[source.uv.Length]; } source.uv.CopyTo(target.uv, 0); if (target.uv.Length != target.vertices.Length) { Vector2[] newUv = new Vector2[target.vertices.Length]; for (int i = 0; i < target.vertices.Length; i++) { if (i < target.uv.Length) { newUv[i] = target.uv[i]; } else { newUv[i] = Vector2.zero; } } target.uv = newUv; } source.colors.CopyTo(target.colors, 0); target.subMeshes.Clear(); for (int n = 0; n < source.subMeshes.Count; n++) { target.subMeshes.Add(source.subMeshes[n].triangles); } }
public void CloneMesh() { if (tsMesh != null) { tsMesh = TS_Mesh.Copy(tsMesh); } else { tsMesh = new TS_Mesh(); } if (mesh != null) { mesh = (Mesh)Instantiate(mesh); } else { mesh = new Mesh(); } }
void BendMesh(Vector3[] vertexPercents, Vector3[] originalNormals, TS_Mesh mesh, Matrix4x4 worldToLocalMatrix) { if (mesh.vertexCount != vertexPercents.Length) { Debug.LogError("Vertex count mismatch"); return; } for (int i = 0; i < mesh.vertexCount; i++) { Vector3 percent = vertexPercents[i]; if (axis == Axis.Y) { percent.z = 1f - percent.z; } GetevalResult(percent); mesh.vertices[i] = worldToLocalMatrix.MultiplyPoint3x4(evalResult.position); mesh.normals[i] = worldToLocalMatrix.MultiplyVector(normalMatrix.MultiplyVector(originalNormals[i])); } }
private void TRS(ExtrudableMesh source, TS_Mesh target, double percent) { CreateTSFromExtrudableMesh(source, ref target); SplineResult result = Evaluate(percent); Matrix4x4 trsMatrix = new Matrix4x4(); Quaternion axisRotation = Quaternion.identity; switch (axis) { case Axis.X: axisRotation = Quaternion.LookRotation(Vector3.right); break; case Axis.Y: axisRotation = Quaternion.LookRotation(Vector3.up, Vector3.back); break; } trsMatrix.SetTRS(result.position + result.right * offset.x + result.normal * offset.y + result.direction * offset.z, result.rotation * Quaternion.AngleAxis(rotation, Vector3.forward) * axisRotation, new Vector3(_scale.x, _scale.y, 1f) * result.size); for (int i = 0; i < target.vertexCount; i++) { target.vertices[i] = trsMatrix.MultiplyPoint3x4(source.vertices[i]); target.normals[i] = trsMatrix.MultiplyVector(source.normals[i]); } }
public override void EditorAwake() { base.EditorAwake(); if (inputMesh != null) { inputMesh = TS_Mesh.Copy(inputMesh); } if (middleMesh != null) { middleMesh = TS_Mesh.Copy(middleMesh); } if (startMesh != null) { startMesh = TS_Mesh.Copy(startMesh); } if (endMesh != null) { endMesh = TS_Mesh.Copy(endMesh); } }
public override void EditorAwake() { base.EditorAwake(); //Make copies of the meshes. if (tsMesh != null) { tsMesh = TS_Mesh.Copy(tsMesh); } else { tsMesh = new TS_Mesh(); } if (mesh != null) { mesh = (Mesh)Instantiate(mesh); } else { mesh = new Mesh(); } Awake(); }
private void Stretch(ExtrudableMesh source, TS_Mesh target, double from, double to) { CreateTSFromExtrudableMesh(source, ref target); SplineResult result = new SplineResult(); Vector2 uv = Vector2.zero; Vector3 trsVector = Vector3.zero; Matrix4x4 trsMatrix = new Matrix4x4(); Quaternion axisRotation = Quaternion.identity; switch (axis) { case Axis.X: axisRotation = Quaternion.LookRotation(Vector3.left); break; case Axis.Y: axisRotation = Quaternion.LookRotation(Vector3.up, Vector3.forward); break; } for (int i = 0; i < source.vertexGroups.Count; i++) { double evalPercent = 0.0; switch (axis) { case Axis.X: evalPercent = DMath.Clamp01(Mathf.InverseLerp(source.bounds.min.x, source.bounds.max.x, source.vertexGroups[i].value)); break; case Axis.Y: evalPercent = DMath.Clamp01(Mathf.InverseLerp(source.bounds.min.y, source.bounds.max.y, source.vertexGroups[i].value)); break; case Axis.Z: evalPercent = DMath.Clamp01(Mathf.InverseLerp(source.bounds.min.z, source.bounds.max.z, source.vertexGroups[i].value)); break; } if (useLastResult && i == source.vertexGroups.Count) { result = lastResult; } else { Evaluate(result, UnclipPercent(DMath.Lerp(from, to, evalPercent))); } trsMatrix.SetTRS(result.position + result.right * offset.x + result.normal * offset.y + result.direction * offset.z, result.rotation * Quaternion.AngleAxis(rotation, Vector3.forward), new Vector3(_scale.x, _scale.y, 1f) * result.size); if (i == 0) { lastResult.CopyFrom(result); } for (int n = 0; n < source.vertexGroups[i].ids.Length; n++) { int index = source.vertexGroups[i].ids[n]; trsVector = axisRotation * source.vertices[index]; trsVector.z = 0f; target.vertices[index] = trsMatrix.MultiplyPoint3x4(trsVector); trsVector = axisRotation * source.normals[index]; target.normals[index] = trsMatrix.MultiplyVector(trsVector); target.colors[index] = target.colors[index] * result.color; uv = target.uv[index]; switch (_tileUVs) { case TileUVs.U: uv.x = (float)result.percent; break; case TileUVs.V: uv.y = (float)result.percent; break; case TileUVs.UniformU: uv.x = CalculateLength(0.0, result.percent); break; case TileUVs.UniformV: uv.y = CalculateLength(0.0, result.percent); break; } target.uv[index] = new Vector2(uv.x * uvScale.x, uv.y * uvScale.y); target.uv[index] += uvOffset; } } }
public void RemoveInnerMesh() { middleMesh = null; startMesh = null; endMesh = null; }
void Generate() { random = new System.Random(_randomSeed); useLastResult = false; iterations = 0; if (_hasStartMesh) { iterations++; } if (_hasEndMesh) { iterations++; } iterations += (extrudableMeshes.Count - 2) * _repeat; double step = 1.0 / iterations; double space = step * _spacing * 0.5; if (combineMeshes.Count < iterations) { combineMeshes.AddRange(new TS_Mesh[iterations - combineMeshes.Count]); } else if (combineMeshes.Count > iterations) { combineMeshes.RemoveRange((combineMeshes.Count - 1) - (combineMeshes.Count - iterations), combineMeshes.Count - iterations); } for (int i = 0; i < iterations; i++) { double from = i * step + space; double to = i * step + step - space; if (combineMeshes[i] == null) { combineMeshes[i] = new TS_Mesh(); } Stretch(extrudableMeshes[GetMeshIndex(i)], combineMeshes[i], from, to); if (_spacing == 0f) { useLastResult = true; } } if (_dontStretchCaps) { if (_hasStartMesh) { TS_Mesh addMesh = new TS_Mesh(); TRS(extrudableMeshes[0], addMesh, 0.0); combineMeshes.Add(addMesh); } if (_hasEndMesh) { TS_Mesh addMesh = new TS_Mesh(); TRS(extrudableMeshes[1], addMesh, 1.0); combineMeshes.Add(addMesh); } } if (tsMesh == null) { tsMesh = new TS_Mesh(); } tsMesh.Combine(combineMeshes, true); }
public void GenerateInnerMesh() { int[] beginIndices = new int[vertexGroups[0].ids.Length]; int[] endIndices = new int[vertexGroups[vertexGroups.Count - 1].ids.Length]; vertexGroups[0].ids.CopyTo(beginIndices, 0); vertexGroups[vertexGroups.Count - 1].ids.CopyTo(endIndices, 0); //First run through the faces and find the ones that belong only to the end vertices and begin vertices List <int> startTriangles = new List <int>(); List <int> endTriangles = new List <int>(); for (int i = 0; i < inputMesh.triangles.Length; i += 3) { bool removeTriangle = false; int found = 0; for (int n = 0; n < beginIndices.Length; n++) { if (inputMesh.triangles[i] == beginIndices[n] || inputMesh.triangles[i + 1] == beginIndices[n] || inputMesh.triangles[i + 2] == beginIndices[n]) { found++; } if (found == 3) { removeTriangle = true; break; } } if (removeTriangle) { startTriangles.Add(i); continue; } removeTriangle = false; found = 0; for (int n = 0; n < endIndices.Length; n++) { if (inputMesh.triangles[i] == endIndices[n] || inputMesh.triangles[i + 1] == endIndices[n] || inputMesh.triangles[i + 2] == endIndices[n]) { found++; } if (found == 3) { removeTriangle = true; break; } } if (removeTriangle) { endTriangles.Add(i); } } middleMesh = TS_Mesh.Copy(inputMesh); startMesh = TS_Mesh.Copy(inputMesh); endMesh = TS_Mesh.Copy(inputMesh); List <int> all = new List <int>(); all.AddRange(startTriangles); all.AddRange(endTriangles); StripFaces(startMesh, startTriangles); StripFaces(middleMesh, all); StripFaces(endMesh, endTriangles); }
private TS_Mesh Stretch(TS_Mesh mesh, double from, double to) { SplineResult result = new SplineResult(); if (_axis == Axis.X) { for (int i = 0; i < vertexGroups.Count; i++) { //Get the group's percent in the bounding box double xPercent = DMath.Clamp01(Mathf.InverseLerp(mesh.bounds.min.x, mesh.bounds.max.x, vertexGroups[i].value)); if (useLastResult && i == vertexGroups.Count) { result = lastResult; } else { Evaluate(DMath.Lerp(from, to, xPercent), ref result); } if (i == 0) { lastResult.Absorb(result); } for (int n = 0; n < vertexGroups[i].ids.Length; n++) { int index = vertexGroups[i].ids[n]; float yPercent = Mathf.Clamp01(Mathf.InverseLerp(mesh.bounds.min.y, mesh.bounds.max.y, mesh.vertices[index].y)); float zPercent = Mathf.Clamp01(Mathf.InverseLerp(mesh.bounds.min.z, mesh.bounds.max.z, mesh.vertices[index].z)); Quaternion rot = Quaternion.AngleAxis(rotation, result.direction); Vector3 right = Vector3.Cross(result.direction, result.normal); mesh.vertices[index] = result.position + rot * right * Mathf.Lerp(mesh.bounds.min.z, mesh.bounds.max.z, zPercent) * result.size * _scale.x - right * offset.x; mesh.vertices[index] += rot * result.normal * Mathf.Lerp(mesh.bounds.min.y, mesh.bounds.max.y, yPercent) * result.size * _scale.y + result.normal * offset.y; mesh.vertices[index] += result.direction * offset.z; //Apply all rotations to the normal mesh.normals[index] = rot * result.rotation * Quaternion.AngleAxis(-90f, Vector3.up) * Quaternion.FromToRotation(Vector3.up, result.normal) * mesh.normals[index]; } } } if (_axis == Axis.Y) { for (int i = 0; i < vertexGroups.Count; i++) { double yPercent = DMath.Clamp01(Mathf.InverseLerp(mesh.bounds.min.y, mesh.bounds.max.y, vertexGroups[i].value)); if (useLastResult && i == vertexGroups.Count) { result = lastResult; } else { Evaluate(DMath.Lerp(from, to, yPercent), ref result); } if (i == 0) { lastResult.Absorb(result); } for (int n = 0; n < vertexGroups[i].ids.Length; n++) { int index = vertexGroups[i].ids[n]; float xPercent = Mathf.Clamp01(Mathf.InverseLerp(mesh.bounds.min.x, mesh.bounds.max.x, mesh.vertices[index].x)); float zPercent = Mathf.Clamp01(Mathf.InverseLerp(mesh.bounds.min.z, mesh.bounds.max.z, mesh.vertices[index].z)); Quaternion rot = Quaternion.AngleAxis(rotation, result.direction); Vector3 right = Vector3.Cross(result.direction, result.normal); mesh.vertices[index] = result.position - rot * right * Mathf.Lerp(mesh.bounds.min.x, mesh.bounds.max.x, xPercent) * result.size * _scale.x - right * offset.x; mesh.vertices[index] -= rot * result.normal * Mathf.Lerp(mesh.bounds.min.z, mesh.bounds.max.z, zPercent) * result.size * _scale.y - result.normal * offset.y; mesh.vertices[index] += result.direction * offset.z; mesh.normals[index] = rot * result.rotation * Quaternion.AngleAxis(90f, Vector3.right) * Quaternion.FromToRotation(Vector3.up, result.normal) * mesh.normals[index]; } } } if (_axis == Axis.Z) { for (int i = 0; i < vertexGroups.Count; i++) { double zPercent = DMath.Clamp01(Mathf.InverseLerp(mesh.bounds.min.z, mesh.bounds.max.z, vertexGroups[i].value)); if (useLastResult && i == vertexGroups.Count) { result = lastResult; } else { Evaluate(DMath.Lerp(from, to, zPercent), ref result); } if (i == 0) { lastResult.Absorb(result); } for (int n = 0; n < vertexGroups[i].ids.Length; n++) { int index = vertexGroups[i].ids[n]; float xPercent = Mathf.Clamp01(Mathf.InverseLerp(mesh.bounds.min.x, mesh.bounds.max.x, mesh.vertices[index].x)); float yPercent = Mathf.Clamp01(Mathf.InverseLerp(mesh.bounds.min.y, mesh.bounds.max.y, mesh.vertices[index].y)); Quaternion rot = Quaternion.AngleAxis(rotation, result.direction); Vector3 right = Vector3.Cross(result.direction, result.normal); mesh.vertices[index] = result.position - rot * right * Mathf.Lerp(mesh.bounds.min.x, mesh.bounds.max.x, xPercent) * result.size * _scale.x - right * offset.x; mesh.vertices[index] += rot * result.normal * Mathf.Lerp(mesh.bounds.min.y, mesh.bounds.max.y, yPercent) * result.size * _scale.y + result.normal * offset.y; mesh.vertices[index] += result.direction * offset.z; mesh.normals[index] = rot * result.rotation * mesh.normals[index]; } } } return(mesh); }