/* * CubeComponent.cs * Copyright (c) 2007 David Astle * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ using System; using System.Collections.Generic; using System.Text; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; namespace Xclna.Xna.Animation.Visualization { /// /// A cube component to assist in visualization of drawable objects. /// public sealed class CubeComponent : DrawableGameComponent, IAttachable { private int[] indices; private VertexDeclaration vertexDeclaration; private BasicEffect effect; private IGraphicsDeviceService graphics; private Color color; private float sideLength; private VertexPositionColor[] verts; private Vector3[] buffer; private BonePose pose = null; private Matrix localTransform = Matrix.Identity; /// /// Gets or sets the world matrix. /// public Matrix World { get { return effect.World; } set { effect.World = value; } } /// /// Gets or sets the view matrix. /// public Matrix View { get { return effect.View; } set { effect.View = value; } } /// /// Gets or sets the projection matrix. /// public Matrix Projection { get { return effect.Projection; } set { effect.Projection = value; } } /// /// Gets or sets the color of the cube. /// public Color Color { get { return color; } set { for (int i = 0; i < verts.Length; i++) { verts[i].Color = value; } color = value; } } /// /// Creats a new CubeComponent. /// /// The game to which this component will be attached. /// The color of the cube. /// The length of one side of the cube. public CubeComponent(Game game, Color color, float sideLength) : base(game) { this.sideLength = sideLength; this.graphics = (IGraphicsDeviceService)game.Services.GetService( typeof(IGraphicsDeviceService)); effect = new BasicEffect(graphics.GraphicsDevice, null); indices = new int[] { 0,1,2, // left face 2,3,0, 3,2,6, // top face 6,7,3, 7,6,5, // right face 5,4,7, 4,5,1, // bottom face 1,0,4, 5,6,2, // back face 2,1,5, 7,4,0, // front face 0,3,7 }; Vector3[] originalVerts = new Vector3[] { new Vector3(-1, -1, 1), // 0 - front bottom left new Vector3(-1, -1, -1), // 1 - back bottom left new Vector3(-1,1,-1), // 2 - back top left new Vector3(-1,1,1), // 3 - front top left new Vector3(1,-1,1), // 4 - front bottom right new Vector3(1,-1,-1), // 5 - back bottom right new Vector3(1,1,-1), // 6 - back top right new Vector3(1,1,1) // 7 - front top right }; for (int i = 0; i < originalVerts.Length; i++) { originalVerts[i].X *= sideLength / 2; originalVerts[i].Y *= sideLength / 2; originalVerts[i].Z *= sideLength / 2; } vertexDeclaration = new VertexDeclaration( graphics.GraphicsDevice, VertexPositionColor.VertexElements); verts = new VertexPositionColor[8]; buffer = new Vector3[8]; for (int i = 0; i < verts.Length; i++) { verts[i].Position = originalVerts[i]; verts[i].Color = color; } effect.VertexColorEnabled = true; game.Components.Add(this); } /// /// Gets the bounding box of the cube in world space. /// public BoundingBox BoundingBox { get { Matrix world = effect.World; for (int i = 0; i < buffer.Length; i++) { Vector3.Transform(ref verts[i].Position, ref world, out buffer[i]); } return BoundingBox.CreateFromPoints(buffer); } } /// /// Immediately releases unmanaged resources. /// /// False if managed resources should not be disposed. protected override void Dispose(bool disposing) { vertexDeclaration.Dispose(); effect.Dispose(); base.Dispose(disposing); } /// /// Draws the cube. /// /// The game time. public override void Draw(GameTime gameTime) { effect.Begin(); foreach (EffectPass pass in effect.CurrentTechnique.Passes) { pass.Begin(); graphics.GraphicsDevice.VertexDeclaration = vertexDeclaration; graphics.GraphicsDevice.DrawUserIndexedPrimitives( PrimitiveType.TriangleList, verts, 0, verts.Length, indices, 0, 12); pass.End(); } effect.End(); } #region IAttachable Members /// /// Gets or sets the local transform of the cube, before it as affected by the attached bone. /// public Matrix LocalTransform { get { return localTransform; } set { localTransform = value; } } /// /// Gets or sets the combined transform in world coordinates. /// Matrix IAttachable.CombinedTransform { get { return World; } set { World = value; } } /// /// Gets or sets the bone to which this cube is attached. /// public BonePose AttachedBone { get { return pose; } set { pose = value; } } #endregion } }