KinPortal/Game/Geometry.cs
2020-05-15 12:18:51 +02:00

162 lines
5.0 KiB
C#
Executable File

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<Vector3> Vertices {get; private set;}
public List<ushort> Indices {get; private set;}
public BoundingBox Box {
get {
return BoundingBox.CreateFromPoints(Vertices);
}
}
public BoundingSphere Sphere {
get {
return BoundingSphere.CreateFromPoints(Vertices);
}
}
public List<JVector> JVertices {
get {
List<JVector> vertices = new List<JVector>();
foreach(Vector3 vert in Vertices) {
vertices.Add(GetJitterVector(vert));
}
return vertices;
}
}
public List<TriangleVertexIndices> JTriangles {
get {
List<TriangleVertexIndices> triangles = new List<TriangleVertexIndices>();
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<Vector3>();
Indices = new List<ushort>();
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<Vector3>(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<ushort>(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<JVector> vertices, List<TriangleVertexIndices> 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<Vector3>(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<short>(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);
}
}
}
*/