/// <summary> /// Update the trail manager /// </summary> /// <param name="gameTime">The current game time.</param> protected override void Update(TimeSpan gameTime) { for (int i = this.BusyTrails.Count - 1; i >= 0; i--) { TrailSetting trail = this.BusyTrails[i]; trail.CurrentTime += gameTime.TotalSeconds; if (!trail.Finished && trail.NextPointTime <= trail.CurrentTime) { trail.Points.Add(new TrailPoint() { Position = trail.Transform.Position, Time = trail.CurrentTime }); trail.NextPointTime = trail.CurrentTime + trail.TimeStep; this.TrailPointsCount++; } if (trail.CurrentTime - trail.Points[0].Time > trail.ExpirationTime) { trail.Points.RemoveAt(0); this.TrailPointsCount--; } if (trail.Finished && trail.Points.Count == 0) { this.RemoveTrail(trail); } } }
/// <summary> /// Process a trail point /// </summary> /// <param name="trail">The trail setting</param> /// <param name="start">start position</param> /// <param name="end">end position</param> /// <param name="lerp">Lerp factor</param> private void ProcessTrailPoint(TrailSetting trail, ref Vector3 start, ref Vector3 end, float lerp) { Vector3 diff = end - start; Vector3 eyeDir = start - this.RenderManager.ActiveCamera3D.Position; float halfThickness = trail.Thickness; Vector3 perpendicular; Vector3.Cross(ref eyeDir, ref diff, out perpendicular); perpendicular.Normalize(); this.vertices[this.currentVertexId].Position = end + (perpendicular * halfThickness); this.vertices[this.currentVertexId].TexCoord = new Vector2(lerp, 0); this.vertices[this.currentVertexId].Color = Color.White * lerp; this.indices[this.currentIndexId] = (ushort)this.currentVertexId; this.currentVertexId++; this.currentIndexId++; this.vertices[this.currentVertexId].Position = end - (perpendicular * halfThickness); this.vertices[this.currentVertexId].TexCoord = new Vector2(lerp, 1); this.vertices[this.currentVertexId].Color = Color.White * lerp; this.indices[this.currentIndexId] = (ushort)this.currentVertexId; this.currentVertexId++; this.currentIndexId++; }
/// <summary> /// Process a middle trail point /// </summary> /// <param name="trail">The current trail</param> private void ProcessTrailPoint(TrailSetting trail, int pointId) { Vector3 start = trail.Points[pointId - 1].Position; Vector3 end = trail.Points[pointId].Position; double pointTime = trail.Points[pointId].Time; float lerp = (float)((trail.CurrentTime - pointTime) / trail.ExpirationTime); ProcessTrailPoint(trail, ref start, ref end, lerp); }
/// <summary> /// Instantiate the trails /// </summary> /// <param name="numTrails">The number of trails to instantiate</param> private void InstantiateTrails(int numTrails) { for (int i = 0; i < numTrails; i++) { TrailSetting trail = new TrailSetting(); this.FreeTrails.Add(trail); } this.Capacity += numTrails; }
/// <summary> /// Draw the trail mesh /// </summary> /// <param name="gameTime">The current game time</param> public override void Draw(TimeSpan gameTime) { if (this.manager.NumTrails == 0) { return; } Vector3 cameraPos = this.RenderManager.CurrentDrawingCamera3D.Position; int vertexPrediction = this.manager.TrailPointsCount * VerticesPerTrailPoint; int indexPrediction = vertexPrediction + (this.manager.NumTrails * 4); if (indexPrediction >= this.nIndices || vertexPrediction >= this.nVertices) { this.nIndices = indexPrediction + VerticesStep; this.nVertices = vertexPrediction + VerticesStep; this.BuildMesh(); } this.currentVertexId = 0; this.currentIndexId = 0; int trailCount = this.manager.NumTrails; for (int i = 0; i < trailCount; i++) { TrailSetting trail = this.manager.BusyTrails[i]; int numPoints = trail.Points.Count; if (numPoints < 2) { continue; } this.ProcessStartPoint(trail); for (int j = 1; j < trail.Points.Count; j++) { this.ProcessTrailPoint(trail, j); } this.ProcessEndPoint(trail); } this.mesh.VertexBuffer.SetData(this.vertices, this.currentVertexId); this.mesh.IndexBuffer.SetData(this.indices, this.currentIndexId); this.GraphicsDevice.BindVertexBuffer(this.mesh.VertexBuffer); this.GraphicsDevice.BindIndexBuffer(this.mesh.IndexBuffer); this.mesh.NumPrimitives = this.currentIndexId - 2; this.RenderManager.DrawMesh(this.mesh, this.material, ref identity); }
/// <summary> /// Remove the trail /// </summary> /// <param name="trail"></param> private void RemoveTrail(TrailSetting trail) { if (this.BusyTrails.Remove(trail)) { this.TrailPointsCount -= trail.Points.Count; this.NumTrails--; this.FreeTrails.Add(trail); if (this.BusyTrails.Count == 0) { this.IsActive = false; } } }
/// <summary> /// Process the end point of a trail /// </summary> /// <param name="trail">The current trail</param> private void ProcessEndPoint(TrailSetting trail) { Vector3 start = trail.Points.Last().Position; Vector3 end = trail.Transform.Position; Color c = Color.White; float lerp = 0; if (trail.Finished) { double pointTime = trail.Points.Last().Time; lerp = (float)((trail.CurrentTime - pointTime) / trail.ExpirationTime); } ProcessTrailPoint(trail, ref start, ref end, lerp); }
/// <summary> /// Process a start point of a trail /// </summary> /// <param name="trail">The current trail</param> private void ProcessStartPoint(TrailSetting trail) { if (this.currentIndexId != 0) { // Concatenate two triangle strips... this.indices[this.currentIndexId + 0] = (ushort)(this.currentVertexId - 1); this.indices[this.currentIndexId + 1] = (ushort)(this.currentVertexId); this.indices[this.currentIndexId + 2] = (ushort)(this.currentVertexId); this.indices[this.currentIndexId + 3] = (ushort)(this.currentVertexId + 1); this.currentIndexId += 4; } Vector3 start = trail.Points[0].Position; Vector3 end = trail.Points[1].Position; double pointTime = trail.Points[1].Time; float lerp = (float)((trail.CurrentTime - pointTime) / trail.ExpirationTime); ProcessTrailPoint(trail, ref start, ref end, 0); }
/// <summary> /// Get a free trail /// </summary> /// <param name="transform">The transform to follow the trail</param> /// <returns></returns> public TrailSetting GetFreeTrail(Transform3D transform) { if (this.FreeTrails.Count == 0) { this.InstantiateTrails(TrailCountIncrement); } TrailSetting trail = this.FreeTrails[0]; this.FreeTrails.RemoveAt(0); this.BusyTrails.Add(trail); this.NumTrails++; trail.Transform = transform; trail.Reset(); if (!this.IsActive) { this.IsActive = true; } return(trail); }
/// <summary> /// Draw debug lines /// </summary> protected override void DrawDebugLines() { base.DrawDebugLines(); return; if (this.manager.NumTrails == 0) { return; } int trailCount = this.manager.NumTrails; for (int i = 0; i < trailCount; i++) { TrailSetting trail = this.manager.BusyTrails[i]; int numPoints = trail.Points.Count; for (int j = 0; j < trail.Points.Count; j++) { this.RenderManager.LineBatch3D.DrawPoint(trail.Points[j].Position, 4, Color.Yellow); } } }
/// <summary> /// Release a trail /// </summary> /// <param name="trail">The trail instance to release</param> public void FreeTrail(TrailSetting trail) { trail.Finished = true; }
/// <summary> /// Initializes the fighter controller /// </summary> protected override void Initialize() { base.Initialize(); // Init engine trails this.trails = new List <TrailSetting>(); foreach (var trailEntity in this.Owner.FindChildrenByTag("Trail")) { Transform3D trailTransform = trailEntity.FindComponent <Transform3D>(); TrailSetting trail = this.trailManager.GetFreeTrail(trailTransform); trail.Thickness = 1; trail.ExpirationTime = 1f; trail.TimeStep = 0.02; } // Register fighter in screenplay manager var screenplay = this.EntityManager.Find("ScreenplayManager").FindComponent <ScreenplayManager>(); screenplay.RegisterFighter(new FighterSetting() { State = this.State, Transform = transform3D }); this.soundManager = this.EntityManager.Find("SoundManager").FindComponent <SoundManager>(); // Gets all fighter guns this.guns = new List <ProjectileEmitter>(); var gunEntities = this.Owner.ChildEntities.Where(e => e.Tag == "Gun"); foreach (var gunEntity in gunEntities) { var projectileEmitter = gunEntity.FindComponent <ProjectileEmitter>(); this.guns.Add(projectileEmitter); projectileEmitter.OnShoot += projectileEmitter_OnShoot; } this.laserTrigger.OnActionChange += laserTrigger_OnActionChange; // Load sound emitters var engineSoundEntity = this.Owner.FindChild("engineSoundEmitter"); if (engineSoundEntity == null) { engineSoundEntity = this.Owner; } this.engineSoundEmitter = engineSoundEntity.FindComponent <SoundEmitter3D>(); var gunsSoundEntity = this.Owner.FindChild("gunsSoundEmitter"); if (gunsSoundEntity == null) { gunsSoundEntity = this.Owner; } this.gunsSoundEmitter = gunsSoundEntity.FindComponent <SoundEmitter3D>(); }