using System; using System.Collections.Generic; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using Jitter.LinearMath; using Jitter.Collision; namespace KinPortal { public class Geometry { public List Vertices {get; private set;} public List Indices {get; private set;} public BoundingBox Box { get { return BoundingBox.CreateFromPoints(Vertices); } } public BoundingSphere Sphere { get { return BoundingSphere.CreateFromPoints(Vertices); } } public List JVertices { get { List vertices = new List(); foreach(Vector3 vert in Vertices) { vertices.Add(GetJitterVector(vert)); } return vertices; } } public List JTriangles { get { List triangles = new List(); for(int i = 0; i < Indices.Count / 3; i++) { triangles.Add(new TriangleVertexIndices( Indices[i * 3 + 0], Indices[i * 3 + 1], Indices[i * 3 + 2] )); } return triangles; } } public Geometry(Model model) { Vertices = new List(); Indices = new List(); Matrix[] bones = new Matrix[model.Bones.Count]; model.CopyAbsoluteBoneTransformsTo(bones); foreach (ModelMesh mm in model.Meshes) { Matrix bone = bones[mm.ParentBone.Index]; foreach (ModelMeshPart mmp in mm.MeshParts) { int offset = Vertices.Count; Vector3[] verts = new Vector3[mmp.NumVertices]; mmp.VertexBuffer.GetData(mmp.VertexOffset * mmp.VertexBuffer.VertexDeclaration.VertexStride, verts, 0, mmp.NumVertices, mmp.VertexBuffer.VertexDeclaration.VertexStride); Vector3.Transform(verts, ref bone, verts); Vertices.AddRange(verts); ushort[] indices = new ushort[mmp.PrimitiveCount * 3]; mmp.IndexBuffer.GetData(mmp.StartIndex * 2, indices, 0, mmp.PrimitiveCount * 3); TriangleVertexIndices[] tvi = new TriangleVertexIndices[mmp.PrimitiveCount]; for (int i = 0; i != indices.Length; i++) { indices[i] += (ushort) offset; } Indices.AddRange(indices); } } } public static Matrix GetXnaMatrix(JMatrix jmat) { return new Matrix( jmat.M11, jmat.M12, jmat.M13, 0.0f, jmat.M21, jmat.M22, jmat.M23, 0.0f, jmat.M31, jmat.M32, jmat.M33, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f ); } public static JMatrix GetJitterMatrix(Matrix xmat) { return new JMatrix( xmat.M11, xmat.M12, xmat.M13, xmat.M21, xmat.M22, xmat.M23, xmat.M31, xmat.M32, xmat.M33 ); } public static Vector3 GetXnaVector(JVector jvec) { return new Vector3(jvec.X, jvec.Y, jvec.Z); } public static JVector GetJitterVector(Vector3 xvec) { return new JVector(xvec.X, xvec.Y, xvec.Z); } public static Quaternion GetRelativeRotation(Vector3 u, Vector3 v) { Quaternion rot; if(u == v) { rot = Quaternion.Identity; } else if(u == (-v)) { rot = Quaternion.CreateFromAxisAngle(GetOrthogonalVector(u), (float) Math.PI); } else { rot = Quaternion.CreateFromAxisAngle(Vector3.Cross(u, v), (float) Math.Acos(Vector3.Dot(u, v))); } return rot; } public static Vector3 GetRotationAxis(Quaternion rot) { Vector3 axis = new Vector3(rot.X, rot.Y, rot.Z); Vector3 naxis = Vector3.Normalize(axis); return naxis; } public static Vector3 GetOrthogonalVector(Vector3 vec) { Vector3 v; if(vec.X != 0) { v = new Vector3((-(vec.Y)-(vec.Z))/vec.X, 1, 0); } else if(vec.Y != 0) { v = new Vector3(1, (-(vec.Z)-(vec.X))/vec.Y, 0); } else if(vec.Z != 0) { v = new Vector3(1, 0, (-(vec.X)-(vec.Y))/vec.Z); } else { v = Vector3.Zero; } return Vector3.Normalize(v); } } } /*public static void GetJitterModelTriangles(Model model, List vertices, List triangles) { Matrix[] bones = new Matrix[model.Bones.Count]; model.CopyAbsoluteBoneTransformsTo(bones); foreach (ModelMesh mm in model.Meshes) { Matrix bone = bones[mm.ParentBone.Index]; foreach (ModelMeshPart mmp in mm.MeshParts) { int offset = vertices.Count; Vector3[] verts = new Vector3[mmp.NumVertices]; mmp.VertexBuffer.GetData(mmp.VertexOffset * mmp.VertexBuffer.VertexDeclaration.VertexStride, verts, 0, mmp.NumVertices, mmp.VertexBuffer.VertexDeclaration.VertexStride); foreach(Vector3 vert in verts) { vertices.Add(GetJitterVector(Vector3.Transform(vert, bone))); } short[] indices = new short[mmp.PrimitiveCount * 3]; mmp.IndexBuffer.GetData(mmp.StartIndex * 2, indices, 0, mmp.PrimitiveCount * 3); TriangleVertexIndices[] tvi = new TriangleVertexIndices[mmp.PrimitiveCount]; for (int i = 0; i != tvi.Length; ++i) { tvi[i].I0 = indices[i * 3 + 0] + offset; tvi[i].I1 = indices[i * 3 + 1] + offset; tvi[i].I2 = indices[i * 3 + 2] + offset; } triangles.AddRange(tvi); } } } */