예제 #1
0
        /// <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;
        }