/// <summary> /// Draws the animated model. /// </summary> /// <param name="gameTime">The elapsed game time.</param> /// <remarks> /// This method will only be called if all the following points are true: /// <list type="bullet"> /// <item> /// <description>The entity passes a frustrum culling test.</description> /// </item> /// <item> /// <description>The parent of the owner <see cref="Entity" /> of the <see cref="Drawable" /> cascades its visibility to its children and it is visible.</description> /// </item> /// <item> /// <description>The <see cref="Drawable" /> is active.</description> /// </item> /// <item> /// <description>The owner <see cref="Entity" /> of the <see cref="Drawable" /> is active and visible.</description> /// </item> /// </list> /// </remarks> public override void Draw(TimeSpan gameTime) { if (this.lastModelId != this.skinnedModel.GetHashCode()) { this.meshMaterials = new Material[this.skinnedModel.Meshes.Count]; this.updateVertexBuffer = new bool[this.skinnedModel.Meshes.Count]; this.lastModelId = this.skinnedModel.GetHashCode(); } if (this.LODEnabled) { this.passUpdate--; if (this.passUpdate <= 0) { float distanceToCamera = Vector3.Distance(this.Transform.Position, this.RenderManager.CurrentDrawingCamera3D.Position); float amount = (distanceToCamera - this.lodMinDistance) / this.lodDiffDistance; if (amount > 1) { amount = 1; } if (amount < 0) { amount = 0; } this.passUpdate = (int)(amount * Quality); this.updateLod = true; } } float zOrder = Vector3.DistanceSquared(this.RenderManager.CurrentDrawingCamera3D.Position, this.Transform.Position); bool needsUpdate = (!LowPerformance && this.lastKeyFrame != this.Animation.Frame && this.updateLod) && this.lastAnimTime != this.Animation.TotalAnimTime; this.lastAnimTime = this.Animation.TotalAnimTime; if (needsUpdate) { this.UpdateTransforms(); } for (int i = 0; i < this.skinnedModel.Meshes.Count; i++) { Material currentMaterial; SkinnedMesh currentMesh = this.skinnedModel.Meshes[i]; this.updateVertexBuffer[i] |= needsUpdate; if (this.MaterialMap.Materials.ContainsKey(currentMesh.Name)) { currentMaterial = this.MaterialMap.Materials[currentMesh.Name]; } else { currentMaterial = this.MaterialMap.DefaultMaterial; } this.meshMaterials[i] = currentMaterial; if (currentMaterial != null) { if (this.updateVertexBuffer[i]) { currentMesh.SetBones(this.skinTransforms, true); this.GraphicsDevice.BindVertexBuffer(currentMesh.VertexBuffer); this.updateVertexBuffer[i] = false; } currentMesh.ZOrder = zOrder; this.GraphicsDevice.UnsetBuffers(); Matrix transform = this.Transform.WorldTransform; this.RenderManager.DrawMesh(currentMesh, currentMaterial, ref transform, false); this.GraphicsDevice.UnsetBuffers(); } } if (this.LODEnabled) { this.updateLod = false; } this.lastKeyFrame = this.Animation.Frame; }