/* * Copyright (c) 2007, John Hurliman * All rights reserved. * * - Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * - Redistributions of source code must retain the above copyright notice, this * list of conditions and the following disclaimer. * - Neither the name of the Second Life Reverse Engineering Team nor the names * of its contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ using System; using System.Text; using System.Collections.Generic; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using libsecondlife; using libsecondlife.Rendering; namespace sceneviewer.Prims { public class PrimVisual { // Constants public const int MaxCut = 200; public Matrix Matrix; public PrimMesh Mesh; public VertexPositionColor[] VertexArray; public int[] IndexArray; public Primitive Prim; public BoundingBox BoundBox; protected Color color; protected List Vertices; public PrimVisual(Primitive prim) { Prim = prim; BuildVertices(); VertexArray = Vertices.ToArray(); BuildMatrix(); } public void Select() { BuildVertices(); } public void Deselect() { ; } public void Update(ObjectUpdate primUpdate) { Prim.Position = primUpdate.Position; Prim.Rotation = primUpdate.Rotation; Prim.Acceleration = primUpdate.Acceleration; Prim.Velocity = primUpdate.Velocity; Prim.AngularVelocity = primUpdate.AngularVelocity; BuildMatrix(); } private void BuildVertices() { Mesh = Render.GenerateMesh(Prim.Data, Render.DETAIL_LEVELS[Render.DETAIL_LEVELS.Length - 1]); Vertices = new List(Mesh.Vertices.Count); // TODO: This is temporary, for debugging and entertainment purposes Random rand = new Random((int)Prim.LocalID + Environment.TickCount); byte r = (byte)rand.Next(256); byte g = (byte)rand.Next(256); byte b = (byte)rand.Next(256); color = new Color(r, g, b); //color = Color.Red; for (int i = 0; i < Mesh.Vertices.Count; i++) { LLVector3 point = Mesh.Vertices[i]; Vertices.Add(new VertexPositionColor(new Vector3(point.X, point.Y, point.Z), color)); } IndexArray = Mesh.Indices.ToArray(); } private void BuildMatrix() { Matrix offset = Matrix.CreateTranslation(new Vector3(Prim.Position.X, Prim.Position.Y, Prim.Position.Z)); Matrix rotation = Matrix.CreateFromQuaternion(new Quaternion(Prim.Rotation.X, Prim.Rotation.Y, Prim.Rotation.Z, Prim.Rotation.W)); Matrix scaling = Matrix.CreateScale(Prim.Scale.X, Prim.Scale.Y, Prim.Scale.Z); Matrix = scaling * rotation * offset; // Now that we have the final transformation matrix we can create a proper bounding box // TODO: This code has only been tested with linear extrusion prims if (Prim.ParentID != 0) { float minX = -0.5f, minY = -0.5f, minZ = -0.5f; if (Prim.Data.PathShearX < 0) minX *= Prim.Data.PathShearX; if (Prim.Data.PathShearY < 0) minY *= Prim.Data.PathShearY; float maxX = 0.5f, maxY = 0.5f, maxZ = 0.5f; if (Prim.Data.PathShearX > 0) maxX *= Prim.Data.PathShearX; if (Prim.Data.PathShearY > 0) maxY *= Prim.Data.PathShearY; Vector3 min = Vector3.Transform(new Vector3(minX, minY, minZ), Matrix); Vector3 max = Vector3.Transform(new Vector3(maxX, maxY, maxZ), Matrix); BoundBox = new BoundingBox(min, max); } else { BoundBox = new BoundingBox(); } } } }