public void Update(TrainSetionManager manager) { // Debug.Log("Vertex begin ======"); for (int i = 0; i < maxCount; i++) { TrailSection section = manager.GetMembers(i); meshVertices[i * 2] = section.vertex[0]; meshVertices[i * 2 + 1] = section.vertex[1]; // Debug.Log("section.vertex[0]==" + section.vertex[0]); // Debug.Log("section.vertex[1]==" + section.vertex[1]); meshColor[i * 2] = section.colors[0]; meshColor[i * 2 + 1] = section.colors[1]; meshUV[i * 2] = section.uv[0]; meshUV[i * 2 + 1] = section.uv[1]; } FreshMesh(); }
/// <summary> /// AutoDB Population Tool - Add json data to db /// Goes through a set of geoJSON features, looks for them in the database by trailname and adds geometry to db if found /// </summary> /// /// <remarks> Michael, 2/17/2019. </remarks> /// /// <param name="geoJsonSource">Receives location of geoJson string</param> public void ImportGeoJsonDataToDB() { //For Loggin string unfoundTrailNames = "Trail not found in db: "; JObject t = JObject.Parse(File.ReadAllText(geoJsonSource)) as JObject; //Allow the use of dynamic json targeting dynamic traildata = t; var wkid = traildata.spatialReference.wkid; foreach (dynamic trail in traildata.features) { //Check if a matching trail name in the database exists and if so add current trail section to trail string trailName = trail.attributes.TRLNAME; if (db.Trails.Where(x => x.TrailName.ToUpper() == trailName).Any()) { var ts = new TrailSection(trail, wkid); var currentTrail = db.Trails.Where(x => x.TrailName.ToUpper() == trailName).First(); if (currentTrail.TrailSections.Count < 1) { currentTrail.Status = ts.Status; } currentTrail.TrailSections.Add(ts); } else { unfoundTrailNames += (trailName + ": "); } } db.SaveChanges(); }
void IsAddPoint(Vector3 postion) { TrailSection tmpFirst = setionManager.GetFirst(); float tmpfloat = (tmpFirst.position - postion).sqrMagnitude; // Debug.Log("curCount===========" + curCount); if (tmpfloat > sqrMinDistance) { TrailSection tmpLast = setionManager.GetLast(); // Debug.Log("tmplast=========" + tmpLast.cellIndex); Initial(tmpLast, postion); setionManager.ReplaceLastToFirst(); } FollowFront(); }
public ActionResult ManuallyAddJsonToDb(string trailNameInDb, string[] trailFeatureNames) { try { var Trail = db.Trails.Where(x => x.TrailName == trailNameInDb.Trim()).First(); foreach (var trailFeatureName in trailFeatureNames) { var newTrailFeatures = GeoJSONTools.GetTrailFromGeoJson(trailFeatureName.ToUpper(), out string wkid); foreach (var feature in newTrailFeatures) { var ts = new TrailSection(feature, wkid); Trail.TrailSections.Add(ts); if (Trail.TrailSections.Count < 1) { Trail.Status = ts.Status; } } } db.SaveChanges(); return(Json(new { status = "ok" })); } catch (Exception e) { return(Json(new { status = "error", messages = new[] { e.Message } })); } }
public TrainSetionManager(int tmpCount, Transform tmpTrans, Color tmpStart, Color tmpEnd) { ower = tmpTrans; setionManager = new CycleQueue <TrailSection>(); startColor = tmpStart; endColor = tmpEnd; curCount = tmpCount; for (int i = 0; i < tmpCount; i++) { float tmpFloat = (float)i / tmpCount; TrailSection tmpSection = new TrailSection(); setionManager.AddMember(tmpSection); tmpSection.Initial(i, tmpCount, startColor, endColor); Initial(tmpSection, ower.position); } }
static void Main(string[] args) { List <TrailSection> Trails = new List <TrailSection>(); JObject t = JObject.Parse(File.ReadAllText(@"C:\Users\Michael\Desktop\Programming\Projects\OlympicTrailData.Json")) as JObject; dynamic traildata = t; var wkid = traildata.spatialReference.wkid; foreach (dynamic trail in traildata.features) { string LineType = GeometryType(trail.geometry.paths[0].Count); //Check if this should be a point or line TrailSection ts = new TrailSection(); string geometryString = LineType + " ("; foreach (dynamic point in trail.geometry.paths[0]) { geometryString += (string)point[0] + " " + (string)point[1] + ","; } geometryString = geometryString.Remove(geometryString.Length - 1); geometryString += ")"; ts.ShortDescription = trail.attributes.TRLNAME; ts.Geography = DbGeography.FromText(geometryString, (int)wkid); Trails.Add(ts); } Console.Read(); }
public void CopyFromSetion(TrailSection tmpFrom) { for (int i = 0; i < this.colors.Length; i++) { this.colors[i] = tmpFrom.colors[i]; } for (int i = 0; i < this.uv.Length; i++) { this.uv[i] = tmpFrom.uv[i]; } for (int i = 0; i < this.vertex.Length; i++) { this.vertex[i] = tmpFrom.vertex[i]; } this.upDir = tmpFrom.upDir; this.position = tmpFrom.position; this.timer = tmpFrom.timer; }
/// <summary> /// 用于将条带的Section转换为用于渲染的顶点、索引缓冲 /// 可以重载这个方法实现特定的填充策略,例如: /// 可断裂的条带 /// 更高性能的填充策略 /// 定向Billboard /// </summary> private void UpdateBuffers() { Vector3 cameraForward = RendererCamera.transform.forward; for (int iSection = 1; iSection < m_Sections.Count; iSection++) { TrailSection iterSection = m_Sections[iSection]; // Generate vertices Vector3 vHalfWidth = Vector3.Cross((iterSection.Position - m_Sections[iSection - 1].Position).normalized, cameraForward).normalized *iterSection.HalfWidth; m_PositionBuffer[iSection * 4 + 0] = iterSection.Position - vHalfWidth; m_PositionBuffer[iSection * 4 + 1] = iterSection.Position + vHalfWidth; // fade colors out over time m_ColorBuffer[iSection * 4 + 0] = iterSection.Color; m_ColorBuffer[iSection * 4 + 1] = iterSection.Color; m_UVBuffer[iSection * 4 + 0] = new Vector2(iterSection.TexcoordU, 0); m_UVBuffer[iSection * 4 + 1] = new Vector2(iterSection.TexcoordU, 1); } if (m_Sections.Count > 0) { int iSection = 0; TrailSection iterSection = m_Sections[iSection]; // Generate vertices Vector3 vHalfWidth = Vector3.Cross((iterSection.Position - m_Sections[iSection + 1].Position).normalized, RendererCamera.transform.forward).normalized *iterSection.HalfWidth; m_PositionBuffer[iSection * 4 + 0] = iterSection.Position - vHalfWidth; m_PositionBuffer[iSection * 4 + 1] = iterSection.Position + vHalfWidth; // fade colors out over time m_ColorBuffer[iSection * 4 + 0] = iterSection.Color; m_ColorBuffer[iSection * 4 + 1] = iterSection.Color; m_UVBuffer[iSection * 4 + 0] = new Vector2(iterSection.TexcoordU, 0); m_UVBuffer[iSection * 4 + 1] = new Vector2(iterSection.TexcoordU, 1); } for (int iSection = 0; iSection < m_Sections.Count - 1; iSection++) { TrailSection iterSection = m_Sections[iSection + 1]; m_PositionBuffer[iSection * 4 + 2] = m_PositionBuffer[iSection * 4 + Mathf.Min(iSection, 1) * 4]; m_PositionBuffer[iSection * 4 + 3] = m_PositionBuffer[iSection * 4 + Mathf.Min(iSection, 1) * 5]; // fade colors out over time m_ColorBuffer[iSection * 4 + 2] = m_ColorBuffer[iSection * 4 + 4]; m_ColorBuffer[iSection * 4 + 3] = m_ColorBuffer[iSection * 4 + 5]; m_UVBuffer[iSection * 4 + 2] = m_UVBuffer[iSection * 4 + 4]; m_UVBuffer[iSection * 4 + 3] = m_UVBuffer[iSection * 4 + 5]; } for (int iSection = (m_Sections.Count - 1) * 4; iSection < m_PositionBuffer.Length; ++iSection) { // 对于不需要渲染的Section,把坐标放在屏幕外 m_PositionBuffer[iSection] = new Vector3(0, -100000.0f, 0); } }
protected void OnDrawGizmosSelected() { if (!Application.isPlaying || !DEBUG_DrawGizmos) { return; } GUIStyle guiStyle = new GUIStyle(); guiStyle.fontSize = 15; guiStyle.normal.textColor = Color.green; for (int iSection = 0; iSection < m_Sections.Count; ++iSection) { TrailSection iterSection = m_Sections[iSection]; Gizmos.color = Color.red; } for (int iPosition = 0; iPosition < m_PositionBuffer.Length; iPosition++) { if (iPosition % 2 == 0) { Vector3 start = m_PositionBuffer[iPosition]; Vector3 end = m_PositionBuffer[iPosition + 1]; Gizmos.color = Color.yellow; Gizmos.DrawLine(start, end); if (iPosition % 4 == 0) { Gizmos.color = Color.green; guiStyle.normal.textColor = Color.green; Gizmos.DrawSphere(start, 0.05f); UnityEditor.Handles.Label(start + Vector3.right * .2f, iPosition.ToString(), guiStyle); Gizmos.color = Color.red; guiStyle.normal.textColor = Color.red; Gizmos.DrawSphere(end, 0.05f); UnityEditor.Handles.Label(end - Vector3.right * .2f, (iPosition + 1).ToString(), guiStyle); } else { Gizmos.color = Color.green; guiStyle.normal.textColor = Color.green; Gizmos.DrawSphere(start, 0.05f); UnityEditor.Handles.Label(start + Vector3.right * .2f + Vector3.forward * .2f, iPosition.ToString(), guiStyle); Gizmos.color = Color.red; guiStyle.normal.textColor = Color.red; Gizmos.DrawSphere(end, 0.05f); UnityEditor.Handles.Label(end - Vector3.right * .2f + Vector3.forward * .2f, (iPosition + 1).ToString(), guiStyle); } } } Bounds bounds = m_TrailRenderer._MeshRenderer.bounds; Gizmos.color = Color.white; Gizmos.DrawWireSphere(bounds.center, bounds.extents.magnitude); }
public void Initial(TrailSection tmpsetioin, Vector3 postion) { tmpsetioin.position = postion; tmpsetioin.timer = lastTimer; tmpsetioin.Initial(0, curCount, startColor, endColor); }
/// <summary> /// 如果希望在发射新的条带段时,能够对这个新产生的段上的数据做一些特殊处理(例如随机颜色),或者对自己扩展的变量进行初始化赋值时,重载本方法 /// </summary> private void SetupSection(TrailSection section, Vector3 position, Quaternion rotation, int previousSectionIndex) { bool isHeadSection = previousSectionIndex < 0; section.LengthToPreviousSection = isHeadSection ? 0 : (position - m_Sections[previousSectionIndex].Position).magnitude; section.Position = position; section.HalfWidth = StartHalfWidth; }
public void UpdateSetionVertex(TrailSection tmpsetioin) { tmpsetioin.upDir = ower.TransformDirection(Vector3.up); Vector3 first = ower.worldToLocalMatrix.MultiplyPoint(tmpsetioin.position); Vector3 two = ower.worldToLocalMatrix.MultiplyPoint(tmpsetioin.position + tmpsetioin.upDir * height); tmpsetioin.InitialVertex(first, two); }
public void FollowFront(TrailSection front, float total, Color start, Color end) { if (front.timer < 0.00001f) { CopyFromSetion(front); } else { Initial(this.cellIndex, total, start, end); } this.cellIndex = front.cellIndex + 1; }
/// <summary> /// 计算Trail世界空间的包围球 /// 如果当前没有Section,则返回中心为发射器的位置,大小为0的Bounds /// TODO 优化计算方式,降低计算频率 /// 这种计算方式更适合处理一直朝某方向飞的条带 /// 遍历所有的Section计算Bounds太废了,又不可能实现通用且高效的算法 /// 考虑让子类重载,根据不同情况去优化计算 /// </summary> private Bounds CaculateBounds() { Bounds bounds = new Bounds(transform.position, Vector3.zero); if (m_Sections.Count > 0) { TrailSection centerSection = m_Sections[m_Sections.Count / 2]; TrailSection lastSection = m_Sections[m_Sections.Count - 1]; bounds.Encapsulate(centerSection.Position); bounds.Encapsulate(lastSection.Position); } return(bounds); }
/// <summary> /// 用于更新条带段的属性。自定制的特殊动画、过渡等逻辑请写在这个方法的重载中。(见osPlaneTrail范例中如何实现的“自定制曲线的条带颜色变化”) /// </summary> private void UpdateSections() { float totalLength = 0; for (int iSection = m_Sections.Count - 1; iSection >= 0; iSection--) { TrailSection iterSection = m_Sections[iSection]; totalLength += iterSection.LengthToPreviousSection; if (totalLength > m_TargetLength) { /* 断裂效果说明:例 * 下图第一行是Section Index 第二行中"*"是Section "----"是画出来的Trail * 0 1 2 3 4 *----*----*----*----* * 当有2个Section过期时,如果移除两个Section,结果如下图 * 2 3 4 * ----*----*----* * ↑这里断裂 * 为了避免断裂效果,我们只移除1个Section(iLastOutdateSection = 1) * 1 2 3 4 *----*----*----* */ m_Sections.RemoveRange(0, iSection + 1 == m_Sections.Count ? m_Sections.Count // 所有的都过期了,我们可以彻底移除了 : iSection); // 只要不是全部过期了就保留一个过期的Section,避免断裂效果 break; } float progress = Mathf.Clamp01(totalLength / m_TargetLength); iterSection.Color = ColorCurve.Evaluate(progress); iterSection.HalfWidth = Mathf.Lerp(StartHalfWidth, EndHalfWidth, progress); iterSection.TexcoordU = progress; } float emmiter2currentSectionLength = 0; if (totalLength > m_TargetLength) { totalLength = m_TargetLength; } for (int iSection = m_Sections.Count - 1; iSection >= 0; iSection--) { TrailSection iterSection = m_Sections[iSection]; emmiter2currentSectionLength += iterSection.LengthToPreviousSection; float progress = Mathf.Clamp01(emmiter2currentSectionLength / totalLength); iterSection.Color = ColorCurve.Evaluate(progress); iterSection.HalfWidth = Mathf.Lerp(StartHalfWidth, EndHalfWidth, progress); iterSection.TexcoordU = progress; } }
/// <summary> /// 当前Section数量超过<see cref="MaxSectionCount"/>时不会添加Section /// </summary> private TrailSection TryAddSection(Vector3 position, Quaternion rotation) { // TODO 不能添加Section会导致条带发射器终止发射,暂时的解决方法是把MaxSectionCount配的很大。预计以后顶点数可以动态改变 if (m_Sections.Count == MaxSectionCount - 1) { return(null); } TrailSection newSection = new TrailSection(); m_Sections.Add(newSection); SetupSection(newSection, position, rotation, m_Sections.Count - 2); return(newSection); }
private void UpdateAutoEmitting() { if (!(m_IsEmitting && (EnableAutoEmittingWhenMeOutOfCamera || IsInRendererCamera(transform.position)))) { return; } Vector3 emitterPosition_RendererSpace = Quaternion.Inverse(m_TrailRenderer.transform.rotation) * (transform.position - m_TrailRenderer.transform.position); Quaternion emitterRotation_RendererSpace = transform.rotation * Quaternion.Inverse(m_TrailRenderer.transform.rotation); if (m_Sections.Count == 0) { // 在发射器上一帧的位置添加一个Section TryAddSection(emitterPosition_RendererSpace, emitterRotation_RendererSpace); // 在发射器当前位置添加一个Section作为HeadSection, TryAddSection(emitterPosition_RendererSpace, emitterRotation_RendererSpace); } else { #region 判断是否需要新的Section // TDOO 如果FOV不经常变动,可以把这个结果Cache下来。或者把这个值放在相机的管理中每帧计算 float cameraHalfTanFOV = Mathf.Tan(RendererCamera.fieldOfView * 0.5f * Mathf.Deg2Rad); // 把需要发射新Section的发射器在屏幕上移动的距离换算成世界空间的距离 float minMeMoveDistanceSqr = cameraHalfTanFOV * AutoEmittingAddSectionWhenMeMoveDistanceInScreenSpaceGreaterThen; minMeMoveDistanceSqr *= minMeMoveDistanceSqr; minMeMoveDistanceSqr *= m_Me2CameraDistanceSqr; // 需要同时满足世界空间距离和屏幕空间距离 minMeMoveDistanceSqr = Mathf.Max(AutoEmittingAddSectionWhenMeMoveDistanceSqrInWorldSpcaeGreaterThen, minMeMoveDistanceSqr); bool needAddSection = (transform.position - m_Sections[m_Sections.Count - 2].Position).sqrMagnitude > minMeMoveDistanceSqr; #endregion if (needAddSection) { TryAddSection(emitterPosition_RendererSpace, emitterRotation_RendererSpace); } else { // 将HeadSection挪到发射器的位置 TrailSection headSection = m_Sections[m_Sections.Count - 1]; SetupSection(headSection, emitterPosition_RendererSpace, emitterRotation_RendererSpace, m_Sections.Count - 2); } } }
private void Iterate(float iterateTime) { _position = transform.position; if (_sections.Count == 0 || (_sections[0].Point - _position).sqrMagnitude > _minDistance * _minDistance) { TrailSection section = new TrailSection(); section.Point = _position; if (_alwaysUp) { section.UpDir = Vector3.up; } else { section.UpDir = transform.TransformDirection(Vector3.up); } section.Time = iterateTime; _sections.Insert(0, section); } }
public void ResetTrail() { TrailSection tmpFirst = setionManager.GetFirst(); Initial(tmpFirst, ower.position); UpdateSetionVertex(tmpFirst); List <TrailSection> tmpSections = setionManager.GetMembers(); for (int i = 1; i < tmpSections.Count; i++) { tmpSections[i].CopyFromSetion(tmpFirst); } }
public void Iterate(float iterateTime) { Vector3 currentPosition = transform.position; Vector3 upDirection = Cross(Vector3.forward, (currentPosition - mLastPosition)); upDirection = Vector3.Normalize(upDirection); if (mTrailSectionList.Count > 0 && (mTrailSectionList[0].startPoint - currentPosition).sqrMagnitude > (minDistance * minDistance)) { TrailSection trailSection = new TrailSection(); trailSection.startPoint = currentPosition; trailSection.upDirection = upDirection; trailSection.spawnTime = iterateTime; trailSection.lifeTime = trailLifetime; mTrailSectionList.Insert(0, trailSection); mLastPosition = currentPosition; } else if (mTrailSectionList.Count == 0) { if ((currentPosition - mLastPosition).sqrMagnitude > (minDistance * minDistance)) { TrailSection trailSection = new TrailSection(); trailSection.startPoint = currentPosition; trailSection.upDirection = upDirection; trailSection.spawnTime = iterateTime; trailSection.lifeTime = trailLifetime; mTrailSectionList.Insert(0, trailSection); mLastPosition = currentPosition; } else { mMesh.Clear(); } } }
public void Itterate(float itterateTime) { // ** call everytime you sample animation ** position = transform.position; now = itterateTime; // Add a new trail section if (sections.Count == 0 || (sections[0].point - position).sqrMagnitude > minDistance * minDistance) { TrailSection section = new TrailSection(); section.point = position; if (alwaysUp) { section.upDir = Vector3.up; } else { section.upDir = transform.TransformDirection(Vector3.up); } section.time = now; sections.Insert(0, section); } }
void LateUpdate() { if (emit) { Vector3 position = this.transform.position; float timeElapsed = Time.time - this.timeStarted; // Use matrix instead of transform.TransformPoint for performance reasons Matrix4x4 localSpaceTransform = transform.worldToLocalMatrix; // Remove old sectionList // if (sectionList.Count > 0 && now > sectionList[sectionList.Count - 1].time + time) { // sectionList.RemoveAt(sectionList.Count - 1); // } // Add a new trail section // if (sectionList.Count == 0 || (sectionList[0].point - position).sqrMagnitude > minDistance * minDistance) if (sectionList.Count == 0 || (sectionList[0].point - position).magnitude > minDistance)// || timeElapsed > minTime) { TrailSection section = new TrailSection(); section.point = position; if (alwaysUp) { section.upDir = Vector3.up; } else { section.upDir = transform.TransformDirection(Vector3.up); } float distance = 0f; if (sectionList.Count > 0) { int i = sectionList.Count - 1; distance += sectionList[i].distance; Vector3 p1 = localSpaceTransform.MultiplyPoint(section.point); // - upDir * height * 0.5f); Vector3 p2 = localSpaceTransform.MultiplyPoint(sectionList[i].point); // - upDir * height * 0.5f); distance += Vector3.Distance(p1, p2); } section.distance = distance; section.time = Time.time; sectionList.Insert(0, section); // this.timeStarted = Time.time; } // Rebuild the mesh mesh.Clear(); // We need at least 2 sectionList to create the line if (sectionList.Count < 2) { return; } Vector3[] vertices = new Vector3[sectionList.Count * 2]; Color[] colors = new Color[sectionList.Count * 2]; Vector2[] uv = new Vector2[sectionList.Count * 2]; TrailSection previousSection = sectionList[0]; TrailSection currentSection = sectionList[0]; // Generate vertex, uv and colors for (int i = 0; i < sectionList.Count; i++) { previousSection = currentSection; currentSection = sectionList[i]; // Calculate u for texture uv and color interpolation // float u = 0.0f; // if (i != 0) { // u = (Time.time - currentSection.time) / time; // u = (i % 2f); // } // Calculate upwards direction Vector3 upDir = currentSection.upDir; // Generate vertices vertices[i * 2 + 0] = localSpaceTransform.MultiplyPoint(currentSection.point - upDir * height * 0.5f); vertices[i * 2 + 1] = localSpaceTransform.MultiplyPoint(currentSection.point + upDir * height * 0.5f); uv[i * 2 + 0] = new Vector2(currentSection.distance, 0f); uv[i * 2 + 1] = new Vector2(currentSection.distance, 1f); // fade colors out over time Color interpolatedColor = Color.Lerp(startColor, endColor, i / (float)sectionList.Count); colors[i * 2 + 0] = interpolatedColor; colors[i * 2 + 1] = interpolatedColor; } // Generate triangles indices int[] triangles = new int[(sectionList.Count - 1) * 2 * 3]; for (int i = 0; i < triangles.Length / 6; i++) { triangles[i * 6 + 0] = i * 2; triangles[i * 6 + 1] = i * 2 + 1; triangles[i * 6 + 2] = i * 2 + 2; triangles[i * 6 + 3] = i * 2 + 2; triangles[i * 6 + 4] = i * 2 + 1; triangles[i * 6 + 5] = i * 2 + 3; } // Assign to mesh mesh.vertices = vertices; mesh.colors = colors; mesh.uv = uv; mesh.triangles = triangles; } }
public void UpdateTrail(float currentTime) { while (mTrailSectionList.Count > 0 && !mTrailSectionList[mTrailSectionList.Count - 1].IsAlive(currentTime)) { mTrailSectionList.RemoveAt(mTrailSectionList.Count - 1); } if (mTrailSectionList.Count < 2) { mMesh.Clear(); return; } mVertexBuffer = new Vector3[mTrailSectionList.Count * 2]; mColorBuffer = new Color[mTrailSectionList.Count * 2]; mUVColor = new Vector2[mTrailSectionList.Count * 2]; mCurrentTrailSection = mTrailSectionList[0]; mWorldToLocalMatrix = transform.worldToLocalMatrix; for (var i = 0; i < mTrailSectionList.Count; i++) { mCurrentTrailSection = mTrailSectionList[i]; float u = 0.0f; if (i != 0) { u = Mathf.Clamp01((currentTime - mCurrentTrailSection.spawnTime) / trailLifetime); } Vector3 upDirection = mCurrentTrailSection.upDirection; mVertexBuffer[i * 2 + 0] = mWorldToLocalMatrix.MultiplyPoint(mCurrentTrailSection.startPoint - upDirection * trailLength * 0.5f); mVertexBuffer[i * 2 + 1] = mWorldToLocalMatrix.MultiplyPoint(mCurrentTrailSection.startPoint + upDirection * trailLength * 0.5f); mUVColor[i * 2 + 0] = new Vector2(u, 0); mUVColor[i * 2 + 1] = new Vector2(u, 1); Color interpolatedColor = Color.Lerp(startColor, endColor, u); mColorBuffer[i * 2 + 0] = interpolatedColor; mColorBuffer[i * 2 + 1] = interpolatedColor; } int[] triangles = new int[(mTrailSectionList.Count - 1) * 6]; for (int i = 0; i < triangles.Length / 6; i++) { triangles[i * 6 + 0] = i * 2; triangles[i * 6 + 1] = i * 2 + 1; triangles[i * 6 + 2] = i * 2 + 2; triangles[i * 6 + 3] = i * 2 + 2; triangles[i * 6 + 4] = i * 2 + 1; triangles[i * 6 + 5] = i * 2 + 3; } mMesh.Clear(); mMesh.vertices = mVertexBuffer; mMesh.colors = mColorBuffer; mMesh.uv = mUVColor; mMesh.triangles = triangles; if (trailLifetime > desiredTrailLifetime) { trailLifetime -= mDeltaTime * timeTransitionSpeed; if (trailLifetime <= desiredTrailLifetime) { trailLifetime = desiredTrailLifetime; } } else if (trailLifetime < desiredTrailLifetime) { trailLifetime += mDeltaTime * timeTransitionSpeed; if (trailLifetime >= desiredTrailLifetime) { trailLifetime = desiredTrailLifetime; } } }
void LateUpdate() { if (atkState != "None" && hMotion.mainState == HeroAnim.MainState.Combat) { Vector3 startPosition = startPoint.position; Vector3 endPosition = endPoint.position; float now = Time.time; // Remove old Sections while (sections.Count > 0 && now > sections[sections.Count - 1].time + time) { sections.RemoveAt(sections.Count - 1); isClean = false; } // Add a new trail section if (sections.Count == 0 || (sections [0].startP - startPosition).sqrMagnitude > minDistance * minDistance) { TrailSection section = new TrailSection(); section.startP = startPosition; section.endP = endPosition; section.time = now; sections.Insert(0, section); } // Rebuild the mesh Mesh mesh = GetComponent <MeshFilter> ().mesh as Mesh; mesh.Clear(); if (sections.Count < 2) { return; } Vector3[] vertices = new Vector3[sections.Count * 2]; Color[] colors = new Color[sections.Count * 2]; Vector2[] uv = new Vector2[sections.Count * 2]; //TrailSection previousSection = sections [0]; TrailSection currentSection = sections [0]; // Use matrix instead of transform.TransformPoint for performance reasons Matrix4x4 localSpaceTransform = transform.worldToLocalMatrix; // Generate vertex, uv and colors for (int i = 0; i < sections.Count; i++) { //previousSection = currentSection; currentSection = sections [i]; // Calculate u for texture uv and color interpolation float u = 0.0f; if (i != 0) { u = Mathf.Clamp01((Time.time - currentSection.time) / time); } // Calculate upwards direction //Vector3 endPos = currentSection.endP; // Generate vertices vertices [i * 2 + 0] = localSpaceTransform.MultiplyPoint(currentSection.startP); vertices [i * 2 + 1] = localSpaceTransform.MultiplyPoint(currentSection.endP); uv [i * 2 + 0] = new Vector2(u, 0); uv [i * 2 + 1] = new Vector2(u, 1); // fade colors out over time Color interpolatedColor = Color.Lerp(startColor, endColor, u); colors [i * 2 + 0] = interpolatedColor; colors [i * 2 + 1] = interpolatedColor; } // Generate triangles indices int[] triangles = new int[(sections.Count - 1) * 2 * 3]; for (int i = 0; i < triangles.Length / 6; i++) { triangles [i * 6 + 0] = i * 2; triangles [i * 6 + 1] = i * 2 + 1; triangles [i * 6 + 2] = i * 2 + 2; triangles [i * 6 + 3] = i * 2 + 2; triangles [i * 6 + 4] = i * 2 + 1; triangles [i * 6 + 5] = i * 2 + 3; } // Assign to mesh mesh.vertices = vertices; mesh.colors = colors; mesh.uv = uv; mesh.triangles = triangles; } else { if (!isClean) { sections.Clear(); if (mf.mesh) { mf.mesh.Clear(); } isClean = true; } } }
public TrailSection GetMembers(int index) { TrailSection tmpSection = (TrailSection)setionManager.GetMember(index); return(tmpSection); }
public virtual void update(float elapsedTime) { if (!mObject.activeSelf) { return; } // 先将模型数据清空 mMesh.Clear(); // 更新所有片段的生命周期 for (int i = 0; i < mSectionList.Count;) { TrailSection section = mSectionList[mSectionList.Count - 1 - i]; section.update(elapsedTime); if (section.isDead()) { mSectionList.RemoveAt(mSectionList.Count - 1 - i); } else { ++i; } } int sectionCount = mSectionList.Count; if (sectionCount < 2) { return; } // 计算顶点,纹理坐标,颜色 Vector3[] vertices = new Vector3[sectionCount * 2 + sectionCount * 2]; Vector2[] uv = new Vector2[sectionCount * 2 + sectionCount * 2]; Color[] colors = new Color[sectionCount * 2 + sectionCount * 2]; // 每个点到前一个点的距离 float[] disList = new float[sectionCount]; // 计算光带总长度 float totalDis = 0.0f; for (int i = 0; i < sectionCount; ++i) { int preIndex = i - 1; MathUtility.clamp(ref preIndex, 0, sectionCount - 1); disList[i] = (mSectionList[i].mStart - mSectionList[preIndex].mStart).magnitude; totalDis += disList[i]; } float curDis = 0.0f; for (int i = 0; i < sectionCount; ++i) { curDis += disList[i]; // 竖直的光带 vertices[2 * i + 0] = mTransform.worldToLocalMatrix.MultiplyPoint(mSectionList[i].mStart); vertices[2 * i + 1] = mTransform.worldToLocalMatrix.MultiplyPoint(mSectionList[i].mEnd); float u = 1.0f - curDis / totalDis; uv[2 * i + 0] = new Vector2(u, 0.0f); uv[2 * i + 1] = new Vector2(u, 0.45f); colors[2 * i + 0] = MathUtility.lerp(mStartColor, mEndColor, u); colors[2 * i + 1] = colors[2 * i + 0]; // 顶部横向光带 // 横向的点坐标 Vector3 v0, v1, v2; v0 = mSectionList[i].mEnd - mSectionList[i].mStart; if (i == 0) { v1 = mSectionList[i].mEnd - mSectionList[i + 1].mEnd; } else { v1 = mSectionList[i - 1].mEnd - mSectionList[i].mEnd; } v0.Normalize(); v1.Normalize(); if (MathUtility.isFloatZero(MathUtility.getLength(v1 - v0))) { v2 = v0; } else { v2 = Vector3.Cross(v0, v1); v2.Normalize(); } int startIndex = sectionCount * 2 + 2 * i; vertices[startIndex + 0] = mTransform.worldToLocalMatrix.MultiplyPoint(mSectionList[i].mEnd - v2 * mTopWidth * 0.5f - new Vector3(0.0f, 0.03f, 0.0f)); vertices[startIndex + 1] = mTransform.worldToLocalMatrix.MultiplyPoint(mSectionList[i].mEnd + v2 * mTopWidth * 0.5f - new Vector3(0.0f, 0.03f, 0.0f)); uv[startIndex + 0] = new Vector2(u, 0.5f); uv[startIndex + 1] = new Vector2(u, 1.0f); colors[startIndex + 0] = MathUtility.lerp(mStartColor, mEndColor, u); colors[startIndex + 1] = MathUtility.lerp(mStartColor, mEndColor, u); } // 计算顶点索引,每两个点之间两个三角面,每个三角面三个顶点,顶部横向的片是每段有4个三角形 int[] triangles = new int[(sectionCount - 1) * 6 + (sectionCount - 1) * 6]; for (int i = 0; i < sectionCount - 1; ++i) { int startIndex = i * 6; int indexValue = i * 2; triangles[startIndex + 0] = indexValue + 0; triangles[startIndex + 1] = indexValue + 1; triangles[startIndex + 2] = indexValue + 2; triangles[startIndex + 3] = indexValue + 2; triangles[startIndex + 4] = indexValue + 1; triangles[startIndex + 5] = indexValue + 3; } for (int i = 0; i < sectionCount - 1; ++i) { int startIndex = (sectionCount - 1) * 6 + i * 6; int indexValue = sectionCount * 2 + i * 2; triangles[startIndex + 0] = indexValue + 0; triangles[startIndex + 1] = indexValue + 1; triangles[startIndex + 2] = indexValue + 2; triangles[startIndex + 3] = indexValue + 2; triangles[startIndex + 4] = indexValue + 1; triangles[startIndex + 5] = indexValue + 3; } // 将顶点数据设置到模型中 mMesh.vertices = vertices; mMesh.colors = colors; mMesh.uv = uv; mMesh.triangles = triangles; }
public void UpdateTrail(float currentTime, float deltaTime) { // ** call once a frame ** // Rebuild the mesh mesh.Clear(); // // Remove old sections while (sections.Count > 0 && currentTime > sections[sections.Count - 1].time + time) { sections.RemoveAt(sections.Count - 1); } // We need at least 2 sections to create the line if (sections.Count < 2) { return; } // vertices = new Vector3[sections.Count * 2]; colors = new Color[sections.Count * 2]; uv = new Vector2[sections.Count * 2]; // currentSection = sections[0]; // // Use matrix instead of transform.TransformPoint for performance reasons localSpaceTransform = transform.worldToLocalMatrix; // Generate vertex, uv and colors for (var i = 0; i < sections.Count; i++) { // currentSection = sections[i]; // Calculate u for texture uv and color interpolation float u = 0.0f; if (i != 0) { u = Mathf.Clamp01((currentTime - currentSection.time) / time); } // // Calculate upwards direction Vector3 upDir = currentSection.upDir; // Generate vertices vertices[i * 2 + 0] = localSpaceTransform.MultiplyPoint(currentSection.point); vertices[i * 2 + 1] = localSpaceTransform.MultiplyPoint(currentSection.point + upDir * height); uv[i * 2 + 0] = new Vector2(u, 0); uv[i * 2 + 1] = new Vector2(u, 1); // fade colors out over time Color interpolatedColor = Color.Lerp(startColor, endColor, u); colors[i * 2 + 0] = interpolatedColor; colors[i * 2 + 1] = interpolatedColor; } // Generate triangles indices int[] triangles = new int[(sections.Count - 1) * 2 * 3]; for (int i = 0; i < triangles.Length / 6; i++) { triangles[i * 6 + 0] = i * 2; triangles[i * 6 + 1] = i * 2 + 1; triangles[i * 6 + 2] = i * 2 + 2; triangles[i * 6 + 3] = i * 2 + 2; triangles[i * 6 + 4] = i * 2 + 1; triangles[i * 6 + 5] = i * 2 + 3; } // Assign to mesh mesh.vertices = vertices; mesh.colors = colors; mesh.uv = uv; mesh.triangles = triangles; // // Tween to the desired time // if (time > desiredTime) { time -= deltaTime * timeTransitionSpeed; if (time <= desiredTime) { time = desiredTime; } } else if (time < desiredTime) { time += deltaTime * timeTransitionSpeed; if (time >= desiredTime) { time = desiredTime; } } }
void LateUpdate() { position = transform.position; bitangent = transform.right; int lastIndex = sections.Count - 1; if (!pause) { while (sections.Count > 0 && Time.time > sections[0].Time + time) { sections.RemoveAt(0); } lastIndex = sections.Count - 1; if (sections.Count == 0 || (position - sections[lastIndex].Position).sqrMagnitude > minDistance * minDistance) { TrailSection section = new TrailSection(); section.Bitangent = transform.right; section.Position = position; section.Time = Time.time; sections.Add(section); } lastIndex = sections.Count - 1; } mesh = GetComponent <MeshFilter>().mesh; if (sections.Count > 2) { vertices = new Vector3[sections.Count * 2 + 2]; colors = new Color[sections.Count * 2 + 2]; uv = new Vector2[sections.Count * 2 + 2]; currentSection = sections[0]; Color interpolatedColor; float u; Vector2 smoothPosition = sections[lastIndex].Position; Vector2 smoothBitangent = sections[lastIndex].Bitangent; float smoothingLerp = 0.9f; Matrix4x4 localSpaceTransform = transform.worldToLocalMatrix; for (int i = 0; i < window.Length; i++) { window[i] = sections[lastIndex]; } TrailSection smoothedSection = new TrailSection(); float inverseLength = 1.0f / window.Length; for (int i = sections.Count - 1; i >= 0; i--) { currentSection = sections[i]; for (int j = 1; j < window.Length; j++) { TrailSection nextSection = window[j]; window[j - 1] = window[j]; smoothedSection.Position += nextSection.Position; smoothedSection.Bitangent += nextSection.Bitangent; } smoothedSection.Position += currentSection.Position; smoothedSection.Bitangent += currentSection.Bitangent; window[window.Length - 1] = currentSection; smoothedSection.Position *= inverseLength; smoothedSection.Bitangent *= inverseLength; smoothPosition = Vector2.Lerp(currentSection.Position, smoothPosition, smoothingLerp); smoothBitangent = Vector2.Lerp(currentSection.Bitangent, smoothBitangent, smoothingLerp).normalized; vertices[i * 2 + 0] = localSpaceTransform.MultiplyPoint(smoothPosition + smoothBitangent * (height / 2f)); vertices[i * 2 + 1] = localSpaceTransform.MultiplyPoint(smoothPosition - smoothBitangent * (height / 2f)); u = i > 0 ? (sections.Count - i) / (float)sections.Count : 1.0f; uv[i * 2 + 0] = new Vector2(u, 0); uv[i * 2 + 1] = new Vector2(u, 1); interpolatedColor = Color.Lerp(Color.white, new Color(1, 1, 1, 0), u); colors[i * 2 + 0] = interpolatedColor; colors[i * 2 + 1] = interpolatedColor; } vertices[vertices.Length - 2] = localSpaceTransform.MultiplyPoint(position + bitangent * (height / 2f)); vertices[vertices.Length - 1] = localSpaceTransform.MultiplyPoint(position - bitangent * (height / 2f)); uv[uv.Length - 2] = new Vector2(0, 0); uv[uv.Length - 1] = new Vector2(0, 1); colors[colors.Length - 2] = Color.white; colors[colors.Length - 1] = Color.white; triangles = new int[sections.Count * 2 * 3]; for (int i = 0; i < triangles.Length / 6; i++) { triangles[i * 6 + 0] = i * 2; triangles[i * 6 + 1] = i * 2 + 1; triangles[i * 6 + 2] = i * 2 + 2; triangles[i * 6 + 3] = i * 2 + 2; triangles[i * 6 + 4] = i * 2 + 1; triangles[i * 6 + 5] = i * 2 + 3; } mesh.Clear(); mesh.vertices = vertices; mesh.colors = colors; mesh.uv = uv; mesh.triangles = triangles; } }
public void UpdateTrail() { Vector3 position = transform.position; float now = UnityEngine.Time.time; if ((position - LastPositionVelocity).sqrMagnitude < InternalVelocityThreshold) { Time = StartTime; LastTrailSection = new TrailSection { Position = position, Up = transform.TransformDirection(Vector3.up), Time = now }; LastTrailUsed = false; if (OneTrailMore && (LastPosition - position).sqrMagnitude > MinDistance * MinDistance) { // New Section TrailSection section = new TrailSection { Position = position, Up = transform.TransformDirection(Vector3.up), Time = now }; Sections.Enqueue(section); LastPosition = section.Position; OneTrailMore = false; } if (!OneTrailMore) { InternalVelocityThreshold = VelocityThreshold; } return; } if (Sections.Count == 0 || (LastPosition - position).sqrMagnitude > MinDistance * MinDistance) { InternalVelocityThreshold = EndVelocityThreshold; if (Sections.Count == 0) { AudioSource.PlayOneShot(Random.Range(0.0f, 1.0f) < 0.5f ? Swing1 : Swing2); } if (!LastTrailUsed) { Sections.Enqueue(LastTrailSection); } LastTrailUsed = true; OneTrailMore = true; // New Section TrailSection section = new TrailSection { Position = position, Up = transform.TransformDirection(Vector3.up), Time = now }; Sections.Enqueue(section); LastPosition = section.Position; } }
void LateUpdate() { if (atkState != "None" && hMotion.mainState == HeroAnim.MainState.Combat) { Vector3 startPosition = startPoint.position; Vector3 endPosition = endPoint.position; float now = Time.time; // Remove old Sections while (sections.Count > 0 && now > sections[sections.Count - 1].time + time) { sections.RemoveAt (sections.Count - 1); isClean = false; } // Add a new trail section if (sections.Count == 0 || (sections [0].startP - startPosition).sqrMagnitude > minDistance * minDistance) { TrailSection section = new TrailSection (); section.startP = startPosition; section.endP = endPosition; section.time = now; sections.Insert (0, section); } // Rebuild the mesh Mesh mesh = GetComponent <MeshFilter> ().mesh as Mesh; mesh.Clear (); if (sections.Count < 2) return; Vector3[] vertices = new Vector3[sections.Count * 2]; Color[] colors = new Color[sections.Count * 2]; Vector2[] uv = new Vector2[sections.Count * 2]; //TrailSection previousSection = sections [0]; TrailSection currentSection = sections [0]; // Use matrix instead of transform.TransformPoint for performance reasons Matrix4x4 localSpaceTransform = transform.worldToLocalMatrix; // Generate vertex, uv and colors for (int i = 0; i < sections.Count; i++) { //previousSection = currentSection; currentSection = sections [i]; // Calculate u for texture uv and color interpolation float u = 0.0f; if (i != 0) u = Mathf.Clamp01 ((Time.time - currentSection.time) / time); // Calculate upwards direction //Vector3 endPos = currentSection.endP; // Generate vertices vertices [i * 2 + 0] = localSpaceTransform.MultiplyPoint (currentSection.startP); vertices [i * 2 + 1] = localSpaceTransform.MultiplyPoint (currentSection.endP); uv [i * 2 + 0] = new Vector2 (u, 0); uv [i * 2 + 1] = new Vector2 (u, 1); // fade colors out over time Color interpolatedColor = Color.Lerp (startColor, endColor, u); colors [i * 2 + 0] = interpolatedColor; colors [i * 2 + 1] = interpolatedColor; } // Generate triangles indices int[] triangles = new int[(sections.Count - 1) * 2 * 3]; for (int i = 0; i < triangles.Length / 6; i++) { triangles [i * 6 + 0] = i * 2; triangles [i * 6 + 1] = i * 2 + 1; triangles [i * 6 + 2] = i * 2 + 2; triangles [i * 6 + 3] = i * 2 + 2; triangles [i * 6 + 4] = i * 2 + 1; triangles [i * 6 + 5] = i * 2 + 3; } // Assign to mesh mesh.vertices = vertices; mesh.colors = colors; mesh.uv = uv; mesh.triangles = triangles; } else { if (!isClean) { sections.Clear (); if (mf.mesh) { mf.mesh.Clear (); } isClean = true; } } }
public void FixVertex() { if (IsCommonError()) { return; } #if UNITY_EDITOR if (Application.isPlaying) { meshF.mesh.Clear(); } else { meshF.sharedMesh.Clear(); } #else meshF.mesh.Clear(); #endif long size = sectionAllocator.DataCount; if (size < 2) { return; } long verCount = size * 2; Vector3[] vertices = vertexAllocator.AllocMem(verCount); Color[] colors = colorAllocator.AllocMem(verCount); Vector2[] uv = uvAllocator.AllocMem(verCount); int[] triangles = triangleAllocator.AllocMem((size - 1) * 2 * 3); Color startColor = m_Colors[0]; Color endColor = m_Colors[1]; float mod = (float)1 / (float)(size - 1); float traiDis = GetTrailDis(); for (long index = 0; index < size; index++) { TrailSection indexSection = sectionAllocator.GetData(index); float sectionWidth = GetTrailWidth(index, traiDis); pointDir = GetTrailDir(index); float colorSection = (colorNum - 1) * index * mod; if ( (colorSection >= 0) && (colorSection < 1) ) { startColor = m_Colors[0]; endColor = m_Colors[1]; } else if ( (colorSection >= 1) && (colorSection < 2) ) { startColor = m_Colors[1]; endColor = m_Colors[2]; } else if ( (colorSection >= 2) && (colorSection < 3) ) { startColor = m_Colors[2]; endColor = m_Colors[3]; } else { startColor = m_Colors[3]; endColor = m_Colors[4]; } float colorMod = colorSection - (int)(colorSection); if (colorSection >= 4f) { colorMod = 1; } vertices[index * 2] = indexSection.Pos + (pointDir * sectionWidth); vertices[index * 2 + 1] = indexSection.Pos + (-pointDir * sectionWidth); //vertices[index * 2] = indexSection.Pos + (pointDir * sectionWidth) - gameObject.transform.position; //vertices[index * 2 + 1] = indexSection.Pos + (-pointDir * sectionWidth) - gameObject.transform.position; uv[index * 2].x = index * mod; uv[index * 2].y = 1; uv[index * 2 + 1].x = uv[index * 2].x; uv[index * 2 + 1].y = 0; //colors[index * 2] = Color.Lerp(startColor, endColor, colorMod); //colors[index * 2 + 1] = colors[index * 2]; colors[index * 2] = startColor * (1 - colorMod) + endColor * (colorMod); colors[index * 2 + 1] = colors[index * 2]; } for (int i = 0; i < triangles.Length / 6; i++) { if (i < size - 1) { triangles[i * 6 + 0] = i * 2; triangles[i * 6 + 1] = i * 2 + 1; triangles[i * 6 + 2] = i * 2 + 2; triangles[i * 6 + 3] = i * 2 + 2; triangles[i * 6 + 4] = i * 2 + 1; triangles[i * 6 + 5] = i * 2 + 3; } else { triangles[i * 6 + 0] = triangles[((size - 1) * 2) * 3 - 1]; triangles[i * 6 + 1] = triangles[((size - 1) * 2) * 3 - 1]; triangles[i * 6 + 2] = triangles[((size - 1) * 2) * 3 - 1]; triangles[i * 6 + 3] = triangles[((size - 1) * 2) * 3 - 1]; triangles[i * 6 + 4] = triangles[((size - 1) * 2) * 3 - 1]; triangles[i * 6 + 5] = triangles[((size - 1) * 2) * 3 - 1]; } } //尽量不要Set,先看内部缓冲区是否有空间 #if UNITY_EDITOR if (Application.isPlaying) { meshF.mesh.MarkDynamic(); meshF.mesh.vertices = vertices; meshF.mesh.colors = colors; meshF.mesh.uv = uv; meshF.mesh.triangles = triangles; } else { meshF.sharedMesh.MarkDynamic(); meshF.sharedMesh.vertices = vertices; meshF.sharedMesh.colors = colors; meshF.sharedMesh.uv = uv; meshF.sharedMesh.triangles = triangles; } #else meshF.mesh.MarkDynamic(); meshF.mesh.vertices = vertices; meshF.mesh.colors = colors; meshF.mesh.uv = uv; meshF.mesh.triangles = triangles; #endif }