Code:
private static void AddTriangles(TriangleCollection s, WMOInstance wi)
{
float dx = wi.pos.X;
float dy = wi.pos.Y;
float dz = wi.pos.Z;
float dir_x = wi.dir.Z;
float dir_y = wi.dir.Y - 90;
float dir_z = -wi.dir.X;
var newrot = new Vector3();
newrot.X = wi.dir.Z;
newrot.Y = -wi.dir.X;
newrot.Z = wi.dir.Y;
WMO wmo = wi.wmo;
foreach (var g in wmo.groups)
{
int[] vertices = new int[g.nVertices];
for (int i = 0; i < g.nVertices; i++)
{
int off = i*3;
float x = g.vertices[off];
float y = g.vertices[off + 2];
float z = g.vertices[off + 1];
rotate(z, y, dir_x, out z, out y);
rotate(x, y, dir_z, out x, out y);
rotate(x, z, dir_y, out x, out z);
float xx = x + dx;
float yy = y + dy;
float zz = -z + dz;
float finalx = ChunkReader.ZEROPOINT - zz;
float finaly = ChunkReader.ZEROPOINT - xx;
float finalz = yy;
vertices[i] = s.AddVertex(finalx, finaly, finalz);
}
for (int i = 0; i < g.nTriangles; i++)
{
int off = i*3;
int i0 = vertices[g.triangles[off]];
int i1 = vertices[g.triangles[off + 1]];
int i2 = vertices[g.triangles[off + 2]];
int t = s.AddTriangle(i0, i1, i2, ChunkedTriangleCollection.TriangleFlagObject);
}
}
int doodadset = wi.doodadset;
if (doodadset < wmo.nDoodadSets)
{
uint firstDoodad = wmo.doodads[doodadset].firstInstance;
uint nDoodads = wmo.doodads[doodadset].nInstances;
for (uint i = 0; i < nDoodads; i++)
{
uint d = firstDoodad + i;
ModelInstance mi = wmo.doodadInstances[d];
if (mi != null)
AddTrianglesGroupDoodads2(s, mi, wi, newrot); // Does not work :(
}
}
}
// modd
private static void AddTrianglesGroupDoodads2(TriangleCollection s, ModelInstance mi, WMOInstance wi, Vector3 newrot)
{
Model m = mi.model;
if (m == null)
return;
if (m.boundingTriangles == null)
return;
// We got bounding stuff, that is better
int nBoundingVertices = m.boundingVertices.Length / 3;
int[] vertices = new int[nBoundingVertices];
Microsoft.Xna.Framework.Quaternion quat = new Microsoft.Xna.Framework.Quaternion { X = mi.dir.Y, Y = mi.dir.Z, Z = mi.dir.X, W = mi.W };
Vector3 vTemp = new Vector3();
float fAngle;
ToAxisAngle(quat, out vTemp, out fAngle);
vTemp.Y = -vTemp.Y;
Microsoft.Xna.Framework.Quaternion newquat = Microsoft.Xna.Framework.Quaternion.CreateFromAxisAngle(vTemp, fAngle);
Vector3 vPos = new Vector3(mi.pos.X, mi.pos.Z, mi.pos.Y);
scaleMatrix = Matrix.CreateScale(mi.sc);
worldMatrix = scaleMatrix * Matrix.CreateFromQuaternion(newquat) * Matrix.CreateTranslation(vPos);
var WmoWorld = new Matrix();
var matWorld = new Matrix();
var matTemp = new Matrix();
var matRot = new Matrix();
float ax = ChunkReader.ZEROPOINT - wi.pos.Z;
float ay = ChunkReader.ZEROPOINT - wi.pos.X;
float az = wi.pos.Y;
matWorld = Matrix.CreateTranslation(ChunkReader.ZEROPOINT - wi.pos.Z, ChunkReader.ZEROPOINT - wi.pos.X, wi.pos.Y);
matRot = Matrix.Identity;
matTemp = Matrix.CreateRotationX((float)deg2rad(newrot.X));
matRot = Matrix.Multiply(matRot, matTemp);
matTemp = Matrix.CreateRotationY((float)deg2rad(newrot.Y));
matRot = Matrix.Multiply(matRot, matTemp);
matTemp = Matrix.CreateRotationZ((float)deg2rad(newrot.Z + 180));
matRot = Matrix.Multiply(matRot, matTemp);
WmoWorld = Matrix.Multiply(matRot, matWorld);
var MatFinal = Matrix.Multiply(worldMatrix, WmoWorld);
int count = 0;
for (uint i = 0; i < nBoundingVertices; i++)
{
count++;
uint off = i * 3;
float x = m.boundingVertices[off];
float z = m.boundingVertices[off + 2];
float y = m.boundingVertices[off + 1];
Vector3 rotatedVector = Vector3.Transform(new Vector3(-x, y, -z), MatFinal);
vertices[i] = s.AddVertex(rotatedVector.X, rotatedVector.Y, rotatedVector.Z);
}
int nBoundingTriangles = m.boundingTriangles.Length / 3;
for (uint i = 0; i < nBoundingTriangles; i++)
{
uint off = i * 3;
int v0 = vertices[m.boundingTriangles[off]];
int v1 = vertices[m.boundingTriangles[off + 1]];
int v2 = vertices[m.boundingTriangles[off + 2]];
s.AddTriangle(v0, v1, v2, ChunkedTriangleCollection.TriangleFlagModel );
}
}
/// <summary>
/// Convert this instance to an axis-angle representation.
/// </summary>
/// <returns>A Vector4 that is the axis-angle representation of this quaternion.</returns>
public static void ToAxisAngle(Microsoft.Xna.Framework.Quaternion q, out Vector3 axis, out float angle)
{
if (q.W > 1.0f)
q.Normalize();
Vector4 result = new Vector4();
result.W = 2.0f * (float)Math.Acos(q.W); // angle
float den = (float)Math.Sqrt(1.0 - q.W * q.W);
if (den > 0.0001f)
{
axis.X = q.X / den;
axis.Y = q.Y / den;
axis.Z = q.Z / den;
}
else
{
// This occurs when the angle is zero.
// Not a problem: just set an arbitrary normalized axis.
axis.X = 1;
axis.Y = 0;
axis.Z = 0;
}
angle = result.W;
}