public MeshVertex GetBent(MeshVertex vert) { var res = new MeshVertex(vert.position, vert.normal, vert.uv); // application of scale res.position = Vector3.Scale(res.position, new Vector3(0, scale.y, scale.x)); // application of roll res.position = Quaternion.AngleAxis(roll, Vector3.right) * res.position; res.normal = Quaternion.AngleAxis(roll, Vector3.right) * res.normal; // reset X value res.position.x = 0; // application of the rotation + location Quaternion q = Rotation * Quaternion.Euler(0, -90, 0); res.position = q * res.position + location; res.normal = q * res.normal; return(res); }
public void CreateMeshes() { if (null == spline || null == meshInfos || 0 == meshInfos.Length) { return; } UpdateSourceMeshes(); UpdateDecisionParts(); string generatedName = "generated by " + GetType().Name; var generatedTranform = transform.Find(generatedName); generated = generatedTranform != null ? generatedTranform.gameObject : UOUtility.Create(generatedName, gameObject); generated.isStatic = false == updateInPlayMode; generated.layer = gameObject.layer; var generatedChildren = generated.transform.Cast <Transform>().ToList(); foreach (var child in generatedChildren) { if (null == child) { continue; } var meshCollider = child.GetComponent <MeshCollider>(); if (meshCollider) { meshCollider.enabled = false; } } var meshChunkDict = new Dictionary <Material, List <MeshChunk> >(); var sampleCache = new Dictionary <float, CurveSample>(); float offset = 0; for (int i = 0; i < decisionParts.Count; ++i) { int index = decisionParts[i]; if (false == meshChunkDict.ContainsKey(meshInfos[index].material)) { meshChunkDict.Add(meshInfos[index].material, new List <MeshChunk>()); } var meshChunkList = meshChunkDict[meshInfos[index].material]; int vertexCount = meshInfos[index].mesh.vertices.Length; bool isReachedMaxVertices = 0 < meshChunkList.Count && PerChunkMaxVertices < (meshChunkList.Last().bentVertices.Count + vertexCount); bool isReachedMaxLength = 0 < meshChunkList.Count && PerChunkMaxLength < meshChunkList.Last().length; if (0 == meshChunkList.Count || isReachedMaxVertices || isReachedMaxLength) { meshChunkList.Add(new MeshChunk() { bentVertices = new List <MeshVertex>(vertexCount), triangles = new List <int>(vertexCount / 3), uv = new List <Vector2> [8], length = 0 }); } var meshChunk = meshChunkList.Last(); ref SourceMesh sourceMesh = ref sourceMeshes[index]; meshChunk.triangles.AddRange(sourceMesh.Triangles.Select(idx => idx + meshChunk.bentVertices.Count)); List <Vector2> UV = new List <Vector2>(); for (int channel = 0; channel < 8; ++channel) { UV.Clear(); sourceMesh.Mesh.GetUVs(channel, UV); if (0 < UV.Count) { if (null == meshChunk.uv[channel]) { meshChunk.uv[channel] = new List <Vector2>(); } int fillCount = Mathf.Max(0, (meshChunk.bentVertices.Count - UV.Count) - meshChunk.uv[channel].Count); if (0 < fillCount) { meshChunk.uv[channel].AddRange(Enumerable.Repeat(Vector2.zero, fillCount)); } meshChunk.uv[channel].AddRange(UV); } } foreach (var vertex in sourceMesh.Vertices) { var vert = new MeshVertex(vertex.position, vertex.normal, vertex.uv); vert.position.x *= partsScale; float distance = vert.position.x - sourceMesh.MinX * partsScale + offset; distance = Mathf.Clamp(distance, 0, spline.Length); CurveSample sample; if (false == sampleCache.TryGetValue(distance, out sample)) { sample = spline.GetSampleAtDistance(distance); if (heightSync) { var sampleLocationWS = spline.transform.TransformPoint(sample.location); RaycastHit hitInfo; if (Physics.Raycast(sampleLocationWS + Vector3.up * heightSyncTraceRange, -Vector3.up, out hitInfo, heightSyncTraceRange * 2, heightSyncLayerMask)) { var newSampleLocation = spline.transform.InverseTransformPoint(hitInfo.point); var newSampleUp = heightNormalSync ? spline.transform.InverseTransformDirection(hitInfo.normal) : sample.up; sample = new CurveSample(newSampleLocation, sample.tangent, newSampleUp, sample.scale, sample.roll, sample.distanceInCurve, sample.timeInCurve, sample.curve); } } sampleCache.Add(distance, sample); } MeshVertex bentVertex = sample.GetBent(vert); meshChunk.bentVertices.Add(bentVertex); } offset += sourceMeshes[index].Length * partsScale; meshChunk.length += sourceMeshes[index].Length * partsScale; }