refactoring PrimMesher to add viewer compatable features and some code cleanup

0.6.0-stable
Dahlia Trimble 2008-10-10 08:22:13 +00:00
parent 5c5a640aba
commit 7fbe942792
3 changed files with 283 additions and 91 deletions

View File

@ -30,6 +30,7 @@ using System.Collections.Generic;
using System.IO;
using System.Runtime.InteropServices;
using OpenSim.Region.Physics.Manager;
using PrimMesher;
namespace OpenSim.Region.Physics.Meshing
{
@ -40,7 +41,7 @@ namespace OpenSim.Region.Physics.Meshing
GCHandle pinnedVirtexes;
GCHandle pinnedIndex;
public PrimMesh primMesh = null;
//public float[] normals;
public float[] normals;
public Mesh()
{
@ -142,6 +143,68 @@ namespace OpenSim.Region.Physics.Meshing
}
}
public void CalcNormals()
{
int iTriangles = triangles.Count;
this.normals = new float[iTriangles * 3];
int i = 0;
foreach (Triangle t in triangles)
{
float ux, uy, uz;
float vx, vy, vz;
float wx, wy, wz;
ux = t.v1.X;
uy = t.v1.Y;
uz = t.v1.Z;
vx = t.v2.X;
vy = t.v2.Y;
vz = t.v2.Z;
wx = t.v3.X;
wy = t.v3.Y;
wz = t.v3.Z;
// Vectors for edges
float e1x, e1y, e1z;
float e2x, e2y, e2z;
e1x = ux - vx;
e1y = uy - vy;
e1z = uz - vz;
e2x = ux - wx;
e2y = uy - wy;
e2z = uz - wz;
// Cross product for normal
float nx, ny, nz;
nx = e1y * e2z - e1z * e2y;
ny = e1z * e2x - e1x * e2z;
nz = e1x * e2y - e1y * e2x;
// Length
float l = (float)Math.Sqrt(nx * nx + ny * ny + nz * nz);
float lReciprocal = 1.0f / l;
// Normalized "normal"
//nx /= l;
//ny /= l;
//nz /= l;
normals[i] = nx * lReciprocal;
normals[i + 1] = ny * lReciprocal;
normals[i + 2] = nz * lReciprocal;
i += 3;
}
}
public List<PhysicsVector> getVertexList()
{
List<PhysicsVector> result = new List<PhysicsVector>();

View File

@ -31,6 +31,7 @@ using System.Collections.Generic;
using OpenSim.Framework;
using OpenSim.Region.Physics.Manager;
using OpenMetaverse;
using PrimMesher;
namespace OpenSim.Region.Physics.Meshing
{

View File

@ -27,12 +27,77 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using OpenSim.Region.Physics.Manager;
using OpenMetaverse;
namespace OpenSim.Region.Physics.Meshing
namespace PrimMesher
{
public struct Quat
{
/// <summary>X value</summary>
public float X;
/// <summary>Y value</summary>
public float Y;
/// <summary>Z value</summary>
public float Z;
/// <summary>W value</summary>
public float W;
public Quat(float x, float y, float z, float w)
{
X = x;
Y = y;
Z = z;
W = w;
}
public Quat(Coord axis, float angle)
{
axis = axis.Normalize();
angle *= 0.5f;
float c = (float)Math.Cos(angle);
float s = (float)Math.Sin(angle);
X = axis.X * s;
Y = axis.Y * s;
Z = axis.Z * s;
W = c;
Normalize();
}
public float Length()
{
return (float)Math.Sqrt(X * X + Y * Y + Z * Z + W * W);
}
public Quat Normalize()
{
const float MAG_THRESHOLD = 0.0000001f;
float mag = Length();
// Catch very small rounding errors when normalizing
if (mag > MAG_THRESHOLD)
{
float oomag = 1f / mag;
X *= oomag;
Y *= oomag;
Z *= oomag;
W *= oomag;
}
else
{
X = 0f;
Y = 0f;
Z = 0f;
W = 1f;
}
return this;
}
}
public struct Coord
{
public float X;
@ -46,23 +111,119 @@ namespace OpenSim.Region.Physics.Meshing
this.Z = z;
}
public float Length()
{
return (float)Math.Sqrt(this.X * this.X + this.Y * this.Y + this.Z * this.Z);
}
public Coord Normalize()
{
const float MAG_THRESHOLD = 0.0000001f;
float mag = Length();
// Catch very small rounding errors when normalizing
if (mag > MAG_THRESHOLD)
{
float oomag = 1.0f / mag;
this.X *= oomag;
this.Y *= oomag;
this.Z *= oomag;
}
else
{
this.X = 0.0f;
this.Y = 0.0f;
this.Z = 0.0f;
}
return this;
}
public override string ToString()
{
return this.X.ToString() + " " + this.Y.ToString() + " " + this.Z.ToString();
}
public static Coord Cross(Coord c1, Coord c2)
{
return new Coord(
c1.Y * c2.Z - c2.Y * c1.Z,
c1.Z * c2.X - c2.Z * c1.X,
c1.X * c2.Y - c2.X * c1.Y
);
}
public static Coord operator *(Coord v, Quat q)
{
// From http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/transforms/
Coord c2 = new Coord(0.0f, 0.0f, 0.0f);
c2.X = q.W * q.W * v.X +
2f * q.Y * q.W * v.Z -
2f * q.Z * q.W * v.Y +
q.X * q.X * v.X +
2f * q.Y * q.X * v.Y +
2f * q.Z * q.X * v.Z -
q.Z * q.Z * v.X -
q.Y * q.Y * v.X;
c2.Y =
2f * q.X * q.Y * v.X +
q.Y * q.Y * v.Y +
2f * q.Z * q.Y * v.Z +
2f * q.W * q.Z * v.X -
q.Z * q.Z * v.Y +
q.W * q.W * v.Y -
2f * q.X * q.W * v.Z -
q.X * q.X * v.Y;
c2.Z =
2f * q.X * q.Z * v.X +
2f * q.Y * q.Z * v.Y +
q.Z * q.Z * v.Z -
2f * q.W * q.Y * v.X -
q.Y * q.Y * v.Z +
2f * q.W * q.X * v.Y -
q.X * q.X * v.Z +
q.W * q.W * v.Z;
return c2;
}
}
public struct Face
{
// vertices
public int v1;
public int v2;
public int v3;
//normals
public int n1;
public int n2;
public int n3;
public Face(int v1, int v2, int v3)
{
this.v1 = v1;
this.v2 = v2;
this.v3 = v3;
this.n1 = 0;
this.n2 = 0;
this.n3 = 0;
}
public Face(int v1, int v2, int v3, int n1, int n2, int n3)
{
this.v1 = v1;
this.v2 = v2;
this.v3 = v3;
this.n1 = n1;
this.n2 = n2;
this.n3 = n3;
}
}
@ -80,81 +241,6 @@ namespace OpenSim.Region.Physics.Meshing
}
}
//internal float angles3[][] = [
//[0.0f, 1.0f, 0.0f],
//[0.33333333333333331f, -0.49999999999999978f, 0.86602540378443871f],
//[0.66666666666666663f, -0.50000000000000044f, -0.86602540378443837f],
//[1.0f, 1.0f, -2.4492127076447545e-016f]];
/*
angles3 = [
[0.0, 1.0, 0.0],
[0.33333333333333331, -0.49999999999999978, 0.86602540378443871],
[0.66666666666666663, -0.50000000000000044, -0.86602540378443837],
[1.0, 1.0, -2.4492127076447545e-016]]
angles4 = [
[0.0, 1.0, 0.0],
[0.25, 0.0, 1.0],
[0.5, -1.0, 0.0],
[0.75, 0.0, -1.0],
[1.0, 1.0, 0.0]]
angles24 = [
[0.0, 0.5, 0.0],
[0.041666666666666664, 0.48296291314453416, 0.12940952255126037],
[0.083333333333333329, 0.43301270189221935, 0.25],
[0.125, 0.35355339059327379, 0.35355339059327373],
[0.16666666666666666, 0.25, 0.4330127018922193],
[0.20833333333333331, 0.12940952255126048, 0.4829629131445341],
[0.25, 0.0, 0.5],
[0.29166666666666663, -0.12940952255126031, 0.48296291314453416],
[0.33333333333333331, -0.25, 0.43301270189221935],
[0.375, -0.35355339059327373, 0.35355339059327379],
[0.41666666666666663, -0.43301270189221924, 0.25],
[0.45833333333333331, -0.4829629131445341, 0.12940952255126051],
[0.5, -0.5, 0.0],
[0.54166666666666663, -0.48296291314453421, -0.12940952255126018],
[0.58333333333333326, -0.43301270189221941, -0.25],
[0.62499999999999989, -0.35355339059327395, -0.35355339059327356],
[0.66666666666666663, -0.25, -0.43301270189221919],
[0.70833333333333326, -0.12940952255126076, -0.48296291314453405],
[0.75, 0.0, -0.5],
[0.79166666666666663, 0.12940952255126015, -0.48296291314453421],
[0.83333333333333326, 0.25, -0.43301270189221952],
[0.875, 0.35355339059327368, -0.35355339059327384],
[0.91666666666666663, 0.43301270189221919, -0.25],
[0.95833333333333326, 0.48296291314453405, -0.12940952255126079],
[1.0, 0.5, 0.0]]
angles24 = [
[0.0, 1.0, 0.0],
[0.041666666666666664, 0.96592582628906831, 0.25881904510252074],
[0.083333333333333329, 0.86602540378443871, 0.5],
[0.125, 0.70710678118654757, 0.70710678118654746],
[0.16666666666666667, 0.5, 0.8660254037844386],
[0.20833333333333331, 0.25881904510252096, 0.9659258262890682],
[0.25, 6.1230317691118863e-017, 1.0],
[0.29166666666666663, -0.25881904510252063, 0.96592582628906831],
[0.33333333333333333, -0.5, 0.86602540378443871],
[0.375, -0.70710678118654746, 0.70710678118654757],
[0.41666666666666663, -0.86602540378443849, 0.5],
[0.45833333333333331, -0.9659258262890682, 0.25881904510252102],
[0.5, -1.0, 1.2246063538223773e-016],
[0.54166666666666663, -0.96592582628906842, -0.25881904510252035],
[0.58333333333333326, -0.86602540378443882, -0.5],
[0.62499999999999989, -0.70710678118654791, -0.70710678118654713],
[0.66666666666666667, -0.5, -0.86602540378443837],
[0.70833333333333326, -0.25881904510252152, -0.96592582628906809],
[0.75, -1.8369095307335659e-016, -1.0],
[0.79166666666666663, 0.2588190451025203, -0.96592582628906842],
[0.83333333333333326, 0.5, -0.86602540378443904],
[0.875, 0.70710678118654735, -0.70710678118654768],
[0.91666666666666663, 0.86602540378443837, -0.5],
[0.95833333333333326, 0.96592582628906809, -0.25881904510252157],
[1.0, 1.0, -2.4492127076447545e-016]]
*/
internal class AngleList
{
private float iX, iY; // intersection point
@ -226,7 +312,7 @@ angles24 = [
internal List<Angle> angles;
internal void makeAngles( int sides, float startAngle, float stopAngle )
internal void makeAngles(int sides, float startAngle, float stopAngle)
{
angles = new List<Angle>();
double twoPi = System.Math.PI * 2.0;
@ -556,7 +642,7 @@ angles24 = [
}
}
public void AddRot(Quaternion q)
public void AddRot(Quat q)
{
int i;
int numVerts = this.coords.Count;
@ -565,7 +651,7 @@ angles24 = [
for (i = 0; i < numVerts; i++)
{
vert = this.coords[i];
Vertex v = new Vertex(vert.X, vert.Y, vert.Z) * q;
Coord v = new Coord(vert.X, vert.Y, vert.Z) * q;
vert.X = v.X;
vert.Y = v.Y;
@ -646,6 +732,7 @@ angles24 = [
private const float twoPi = 2.0f * (float)Math.PI;
public List<Coord> coords;
public List<Coord> normals;
public List<Face> faces;
public int sides = 4;
@ -712,7 +799,7 @@ angles24 = [
if (sides < 3)
this.sides = 3;
if ( hollowSides < 3)
if (hollowSides < 3)
this.hollowSides = 3;
if (profileStart < 0.0f)
this.profileStart = 0.0f;
@ -795,7 +882,7 @@ angles24 = [
Profile profile = new Profile(this.sides, this.profileStart, this.profileEnd, hollow, this.hollowSides, true);
if (initialProfileRot != 0.0f)
profile.AddRot(Quaternion.CreateFromAxisAngle(new Vector3(0.0f, 0.0f, 1.0f), initialProfileRot));
profile.AddRot(new Quat(new Coord(0.0f, 0.0f, 1.0f), initialProfileRot));
bool done = false;
while (!done)
@ -819,7 +906,7 @@ angles24 = [
float twist = twistBegin + twistTotal * percentOfPath;
if (twist != 0.0f)
newLayer.AddRot(Quaternion.CreateFromAxisAngle(new Vector3(0.0f, 0.0f, 1.0f), twist));
newLayer.AddRot(new Quat(new Coord(0.0f, 0.0f, 1.0f), twist));
newLayer.AddPos(xOffset, yOffset, zOffset);
@ -972,7 +1059,7 @@ angles24 = [
Profile profile = new Profile(this.sides, this.profileStart, this.profileEnd, hollow, this.hollowSides, needEndFaces);
if (initialProfileRot != 0.0f)
profile.AddRot(Quaternion.CreateFromAxisAngle(new Vector3(0.0f, 0.0f, 1.0f), initialProfileRot));
profile.AddRot(new Quat(new Coord(0.0f, 0.0f, 1.0f), initialProfileRot));
bool done = false;
while (!done) // loop through the length of the path and add the layers
@ -980,7 +1067,7 @@ angles24 = [
bool isEndLayer = false;
if (angle == startAngle || angle >= endAngle)
isEndLayer = true;
Profile newLayer = profile.Clone(isEndLayer && needEndFaces);
float xProfileScale = (1.0f - Math.Abs(this.skew)) * this.holeSizeX;
@ -1019,12 +1106,12 @@ angles24 = [
// next apply twist rotation to the profile layer
if (twistTotal != 0.0f || twistBegin != 0.0f)
newLayer.AddRot(Quaternion.CreateFromAxisAngle(new Vector3(0.0f, 0.0f, 1.0f), twist));
newLayer.AddRot(new Quat(new Coord(0.0f, 0.0f, 1.0f), twist));
// now orient the rotation of the profile layer relative to it's position on the path
// adding taperY to the angle used to generate the quat appears to approximate the viewer
//newLayer.AddRot(new Quaternion(new Vertex(1.0f, 0.0f, 0.0f), angle + this.topShearY * 0.9f));
newLayer.AddRot(Quaternion.CreateFromAxisAngle(new Vector3(1.0f, 0.0f, 0.0f), angle + this.topShearY));
newLayer.AddRot(new Quat(new Coord(1.0f, 0.0f, 0.0f), angle + this.topShearY));
newLayer.AddPos(xOffset, yOffset, zOffset);
if (angle == startAngle)
@ -1084,6 +1171,47 @@ angles24 = [
}
}
public Coord SurfaceNormal(int faceIndex)
{
int numFaces = faces.Count;
if (faceIndex < 0 || faceIndex >= faces.Count)
return new Coord(0.0f, 0.0f, 0.0f);
Face face = faces[faceIndex];
Coord c1 = coords[face.v1];
Coord c2 = coords[face.v2];
Coord c3 = coords[face.v3];
Coord edge1 = new Coord(c2.X - c1.X, c2.Y - c1.Y, c2.Z - c1.Z);
Coord edge2 = new Coord(c3.X - c1.X, c3.Y - c1.Y, c3.Z - c1.Z);
Coord normal = Coord.Cross(edge1, edge2);
normal.Normalize();
return normal;
}
public void CalcNormals()
{
int numFaces = faces.Count;
this.normals = new List<Coord>();
for (int i = 0; i < numFaces; i++)
{
Face face = faces[i];
this.normals.Add(SurfaceNormal(i).Normalize());
int normIndex = normals.Count - 1;
face.n1 = normIndex;
face.n2 = normIndex;
face.n3 = normIndex;
this.faces[i] = face;
}
}
public void AddPos(float x, float y, float z)
{
int i;
@ -1100,7 +1228,7 @@ angles24 = [
}
}
public void AddRot(Quaternion q)
public void AddRot(Quat q)
{
int i;
int numVerts = this.coords.Count;
@ -1109,7 +1237,7 @@ angles24 = [
for (i = 0; i < numVerts; i++)
{
vert = this.coords[i];
Vertex v = new Vertex(vert.X, vert.Y, vert.Z) * q;
Coord v = new Coord(vert.X, vert.Y, vert.Z) * q;
vert.X = v.X;
vert.Y = v.Y;