/** * This function updates the spline mesh. It is called automatically once in a while, if updateMode isn't set to DontUpdate. */ public void UpdateMesh( ) { Setup( ); //Reset the generated meshes if (BentMesh) { BentMesh.Clear( ); } if (baseMesh == null || spline == null || segmentCount <= 0) { return; } //Gather model data Vector3[] verticesBase = baseMesh.vertices; Vector3[] normalsBase = baseMesh.normals; Vector4[] tangentsBase = baseMesh.tangents; Vector2[] uvBase = baseMesh.uv; int[] trianglesBase = baseMesh.triangles; //Allocate some memory for new mesh data Vector3[] verticesNew = new Vector3[verticesBase.Length * segmentCount]; Vector3[] normalsNew = new Vector3[normalsBase.Length * segmentCount]; Vector4[] tangentsNew = new Vector4[tangentsBase.Length * segmentCount]; Vector2[] uvNew = new Vector2[uvBase.Length * segmentCount]; int[] trianglesNew = new int[trianglesBase.Length * segmentCount]; //Group front/rear vertices together List <int> verticesFront = new List <int>( ); List <int> verticesBack = new List <int>( ); Vector3 centerFront = Vector3.zero; Vector3 centerBack = Vector3.zero; for (int i = 0; i < verticesBase.Length; i++) { if (verticesBase[i].z > 0f) { verticesFront.Add(i); centerFront += verticesBase[i]; } else if (verticesBase[i].z < 0f) { verticesBack.Add(i); centerBack += verticesBase[i]; } } centerFront /= verticesFront.Count; centerBack /= verticesBack.Count; if (splineSegment >= 0 && splineSegment < spline.SegmentCount) { SplineSegment currentSegment = spline.SplineSegments[splineSegment]; int vIndex = 0; for (int segment = 0; segment < segmentCount; segment++) { float param0 = (float)segment / segmentCount; float param1 = (float)(segment + 1) / segmentCount; if (param1 == 1f) { param1 -= 0.00001f; } param0 = currentSegment.ConvertSegmentToSplineParamter(param0); param1 = currentSegment.ConvertSegmentToSplineParamter(param1); CalculateBentMesh(ref vIndex, verticesFront, verticesBack, ref centerFront, ref centerBack, param0, param1, verticesBase, normalsBase, tangentsBase, uvBase, verticesNew, normalsNew, tangentsNew, uvNew); for (int i = 0; i < trianglesBase.Length; i++) { trianglesNew[i + (segment * trianglesBase.Length)] = trianglesBase[i] + (verticesBase.Length * segment); } } BentMesh.vertices = verticesNew; BentMesh.uv = uvNew; if (normalsBase.Length > 0) { BentMesh.normals = normalsNew; } if (tangentsBase.Length > 0) { BentMesh.tangents = tangentsNew; } BentMesh.triangles = trianglesNew; } else { int vIndex = 0; for (int segment = 0; segment < segmentCount; segment++) { float param0 = (float)segment / segmentCount; float param1 = (float)(segment + 1) / segmentCount; if (param1 == 1f) { param1 -= 0.00001f; } CalculateBentMesh(ref vIndex, verticesFront, verticesBack, ref centerFront, ref centerBack, param0, param1, verticesBase, normalsBase, tangentsBase, uvBase, verticesNew, normalsNew, tangentsNew, uvNew); for (int i = 0; i < trianglesBase.Length; i++) { trianglesNew[i + (segment * trianglesBase.Length)] = trianglesBase[i] + (verticesBase.Length * segment); } } BentMesh.vertices = verticesNew; BentMesh.uv = uvNew; if (normalsBase.Length > 0) { BentMesh.normals = normalsNew; } if (tangentsBase.Length > 0) { BentMesh.tangents = tangentsNew; } BentMesh.triangles = trianglesNew; } }
private void UpdateMesh(Mesh dstMesh, int splineSegment, ref List <Vector3> lightProbePositions) { Vector2 probeExtents = new Vector2(baseMesh.bounds.extents.x + lightProbeExtrude.x, lightProbeExtrude.y); Vector3[] segmentProbePositions = { new Vector3(0, probeExtents.y + lightProbeHeight * 0.5f, 0), new Vector3(probeExtents.x, probeExtents.y, 0), new Vector3(probeExtents.x, probeExtents.y + lightProbeHeight, 0), new Vector3(-probeExtents.x, probeExtents.y, 0), new Vector3(-probeExtents.x, probeExtents.y + lightProbeHeight, 0) }; //Gather model data Vector3[] verticesBase = baseMesh.vertices; Vector3[] normalsBase = baseMesh.normals; Vector4[] tangentsBase = baseMesh.tangents; Vector2[] uvBase = baseMesh.uv; Vector2[] uvLightmap = baseMesh.uv2; ArrayList allTrianglesBase = new ArrayList(); for (int q = 0; q < baseMesh.subMeshCount; ++q) { allTrianglesBase.Add(baseMesh.GetTriangles(q)); } var localSegmentCount = segmentCount / splineSegmentCount; //Allocate some memory for new mesh data Vector3[] verticesNew = new Vector3[verticesBase.Length * localSegmentCount]; Vector3[] normalsNew = new Vector3[normalsBase.Length * localSegmentCount]; Vector4[] tangentsNew = new Vector4[tangentsBase.Length * localSegmentCount]; Vector2[] uvNew = new Vector2[uvBase.Length * localSegmentCount]; Vector2[] lightmapUvNew = new Vector2[uvBase.Length * localSegmentCount]; ArrayList allTrianglesNew = new ArrayList(); for (int q = 0; q < baseMesh.subMeshCount; ++q) { allTrianglesNew.Add(new int[baseMesh.GetTriangles(q).Length *localSegmentCount]); } //Group front/rear vertices together List <int> verticesFront = new List <int>( ); List <int> verticesBack = new List <int>( ); Vector3 centerFront = Vector3.zero; Vector3 centerBack = Vector3.zero; Vector3 minCorner = new Vector3(Mathf.Infinity, Mathf.Infinity, Mathf.Infinity); for (int i = 0; i < verticesBase.Length; i++) { if (verticesBase[i].z > 0f) { verticesFront.Add(i); centerFront += verticesBase[i]; } else if (verticesBase[i].z < 0f) { verticesBack.Add(i); centerBack += verticesBase[i]; } minCorner = Vector3.Min(minCorner, verticesBase[i]); verticesBase[i].x = verticesBase[i].x + xyOffset.x; verticesBase[i].y = verticesBase[i].y + xyOffset.y; } centerFront /= verticesFront.Count; centerBack /= verticesBack.Count; // float meshAspect = (xyScale.x * baseMesh.bounds.size.x) / baseMesh.bounds.size.z; // Vector2 lightmapScale = new Vector2( // (baseMesh.bounds.size.x * xyScale.x), // spline.Length/(float)splineSegmentCount); //;;Debug.Log ("lightmapScale " + lightmapScale.x + "," + lightmapScale.y + " " + splineSegmentCount + " " + localSegmentCount + " " + baseMesh.bounds.size); int vIndex = 0; int boxDimension = (int)Mathf.Round(Mathf.Sqrt(localSegmentCount) + 0.5f); //;;Debug.Log ("boxDimension " + boxDimension); for (int segment = 0; segment < localSegmentCount; segment++) { float localParam0 = (float)segment / localSegmentCount; float localParam1 = (float)(segment + 1) / localSegmentCount; if (localParam1 == 1f) { localParam1 -= 0.00001f; } float splineParam0 = localParam0; float splineParam1 = localParam1; if (splitMesh && splineSegment < spline.SegmentCount) { SplineSegment currentSegment = spline.SplineSegments[splineSegment]; splineParam0 = currentSegment.ConvertSegmentToSplineParamter(localParam0); splineParam1 = currentSegment.ConvertSegmentToSplineParamter(localParam1); } int onX = segment / boxDimension; //int onY = segment % boxDimension; //;;Debug.Log(onX + " " + onY); var columnStartingSegment = onX * boxDimension; var lightmapOffset = new Vector2( onX, -Mathf.Max(0f, (float)columnStartingSegment / (float)localSegmentCount)); CalculateBentMesh(ref vIndex, verticesFront, verticesBack, ref centerFront, ref centerBack, splineParam0, splineParam1, localParam0, localParam1, new Vector2(1.0f / ((float)boxDimension), (float)(boxDimension - 1)), lightmapOffset, verticesBase, normalsBase, tangentsBase, uvBase, uvLightmap, verticesNew, normalsNew, tangentsNew, uvNew, lightmapUvNew); for (int q = 0; q < allTrianglesNew.Count; ++q) { int[] trianglesNew = allTrianglesNew[q] as int[]; int[] trianglesBase = allTrianglesBase[q] as int[]; for (int i = 0; i < trianglesBase.Length; i++) { trianglesNew[i + (segment * trianglesBase.Length)] = trianglesBase[i] + (verticesBase.Length * segment); } } } var localLightProbeSegmentCount = lightProbeSegmentCount / splineSegmentCount; for (int segment = 0; segment < localLightProbeSegmentCount + 1; segment++) { float param0 = (float)segment / localLightProbeSegmentCount; float paramC = ((float)segment + 0.5f) / localLightProbeSegmentCount; if (splitMesh && splineSegment < spline.SegmentCount) { SplineSegment currentSegment = spline.SplineSegments[splineSegment]; param0 = currentSegment.ConvertSegmentToSplineParamter(param0); paramC = currentSegment.ConvertSegmentToSplineParamter(paramC); } Vector3 pos0 = spline.transform.InverseTransformPoint(spline.GetPositionOnSpline(param0)); Quaternion rot0 = spline.GetOrientationOnSpline(param0) * Quaternion.Inverse(spline.transform.localRotation); Vector3 posC = spline.transform.InverseTransformPoint(spline.GetPositionOnSpline(paramC)); Quaternion rotC = spline.GetOrientationOnSpline(paramC) * Quaternion.Inverse(spline.transform.localRotation); foreach (var probePos in segmentProbePositions) { lightProbePositions.Add(pos0 + rot0 * probePos); } if (segment != localLightProbeSegmentCount) { lightProbePositions.Add(posC + rotC * segmentProbePositions[0]); } } dstMesh.vertices = verticesNew; dstMesh.uv = uvNew; dstMesh.uv2 = lightmapUvNew; if (normalsBase.Length > 0) { dstMesh.normals = normalsNew; } if (tangentsBase.Length > 0) { dstMesh.tangents = tangentsNew; } dstMesh.subMeshCount = allTrianglesNew.Count; for (int q = 0; q < allTrianglesNew.Count; ++q) { int[] trianglesNew = allTrianglesNew[q] as int[]; dstMesh.SetTriangles(trianglesNew, q); } }