| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167 |
- #region File Description
- //-----------------------------------------------------------------------------
- // ModelViewerControl.cs
- //
- // Microsoft XNA Community Game Platform
- // Copyright (C) Microsoft Corporation. All rights reserved.
- //-----------------------------------------------------------------------------
- #endregion
- #region Using Statements
- using System;
- using System.Diagnostics;
- using System.Windows.Forms;
- using Microsoft.Xna.Framework;
- using Microsoft.Xna.Framework.Graphics;
- #endregion
- namespace WinFormsContentLoading
- {
- /// <summary>
- /// Example control inherits from GraphicsDeviceControl, and displays
- /// a spinning 3D model. The main form class is responsible for loading
- /// the model: this control just displays it.
- /// </summary>
- class ModelViewerControl : GraphicsDeviceControl
- {
- /// <summary>
- /// Gets or sets the current model.
- /// </summary>
- public Model Model
- {
- get { return model; }
- set
- {
- model = value;
- if (model != null)
- {
- MeasureModel();
- }
- }
- }
- Model model;
- // Cache information about the model size and position.
- Matrix[] boneTransforms;
- Vector3 modelCenter;
- float modelRadius;
- // Timer controls the rotation speed.
- Stopwatch timer;
- /// <summary>
- /// Initializes the control.
- /// </summary>
- protected override void Initialize()
- {
- // Start the animation timer.
- timer = Stopwatch.StartNew();
- // Hook the idle event to constantly redraw our animation.
- Application.Idle += delegate { Invalidate(); };
- }
- /// <summary>
- /// Draws the control.
- /// </summary>
- protected override void Draw()
- {
- // Clear to the default control background color.
- Color backColor = new Color(BackColor.R, BackColor.G, BackColor.B);
- GraphicsDevice.Clear(backColor);
- if (model != null)
- {
- // Compute camera matrices.
- float rotation = (float)timer.Elapsed.TotalSeconds;
- Vector3 eyePosition = modelCenter;
- eyePosition.Z += modelRadius * 2;
- eyePosition.Y += modelRadius;
- float aspectRatio = GraphicsDevice.Viewport.AspectRatio;
-
- float nearClip = modelRadius / 100;
- float farClip = modelRadius * 100;
- Matrix world = Matrix.CreateRotationY(rotation);
- Matrix view = Matrix.CreateLookAt(eyePosition, modelCenter, Vector3.Up);
- Matrix projection = Matrix.CreatePerspectiveFieldOfView(1, aspectRatio,
- nearClip, farClip);
- // Draw the model.
- foreach (ModelMesh mesh in model.Meshes)
- {
- foreach (BasicEffect effect in mesh.Effects)
- {
- effect.World = boneTransforms[mesh.ParentBone.Index] * world;
- effect.View = view;
- effect.Projection = projection;
- effect.EnableDefaultLighting();
- effect.PreferPerPixelLighting = true;
- effect.SpecularPower = 16;
- }
- mesh.Draw();
- }
- }
- }
- /// <summary>
- /// Whenever a new model is selected, we examine it to see how big
- /// it is and where it is centered. This lets us automatically zoom
- /// the display, so we can correctly handle models of any scale.
- /// </summary>
- void MeasureModel()
- {
- // Look up the absolute bone transforms for this model.
- boneTransforms = new Matrix[model.Bones.Count];
-
- model.CopyAbsoluteBoneTransformsTo(boneTransforms);
- // Compute an (approximate) model center position by
- // averaging the center of each mesh bounding sphere.
- modelCenter = Vector3.Zero;
- foreach (ModelMesh mesh in model.Meshes)
- {
- BoundingSphere meshBounds = mesh.BoundingSphere;
- Matrix transform = boneTransforms[mesh.ParentBone.Index];
- Vector3 meshCenter = Vector3.Transform(meshBounds.Center, transform);
- modelCenter += meshCenter;
- }
- modelCenter /= model.Meshes.Count;
- // Now we know the center point, we can compute the model radius
- // by examining the radius of each mesh bounding sphere.
- modelRadius = 0;
- foreach (ModelMesh mesh in model.Meshes)
- {
- BoundingSphere meshBounds = mesh.BoundingSphere;
- Matrix transform = boneTransforms[mesh.ParentBone.Index];
- Vector3 meshCenter = Vector3.Transform(meshBounds.Center, transform);
- float transformScale = transform.Forward.Length();
-
- float meshRadius = (meshCenter - modelCenter).Length() +
- (meshBounds.Radius * transformScale);
- modelRadius = Math.Max(modelRadius, meshRadius);
- }
- }
- }
- }
|