Hollow prims (box only), thanks Gerard! Enjoy

afrisby
dan miller 2007-09-29 04:08:33 +00:00
parent a0265300aa
commit c1d3e93fbb
2 changed files with 839 additions and 0 deletions

View File

@ -0,0 +1,279 @@
using System;
using System.Globalization;
using System.Diagnostics;
using System.Collections.Generic;
using OpenSim.Region.Physics.Manager;
public class Vertex : IComparable<Vertex>
{
public String name;
public PhysicsVector point;
public Vertex(String name, float x, float y, float z)
{
this.name = name;
point = new PhysicsVector(x, y, z);
}
public int CompareTo(Vertex other)
{
if (point.X < other.point.X)
return -1;
if (point.X > other.point.X)
return 1;
if (point.Y < other.point.Y)
return -1;
if (point.Y > other.point.Y)
return 1;
if (point.Z < other.point.Z)
return -1;
if (point.Z > other.point.Z)
return 1;
return 0;
}
public static bool operator >(Vertex me, Vertex other)
{
return me.CompareTo(other) > 0;
}
public static bool operator <(Vertex me, Vertex other)
{
return me.CompareTo(other) < 0;
}
}
public class Simplex : IComparable<Simplex>
{
public Vertex v1;
public Vertex v2;
public Simplex(Vertex _v1, Vertex _v2)
{
// Presort indices to make sorting (comparing) easier
if (_v1 > _v2)
{
v1 = _v1;
v2 = _v2;
}
else
{
v1 = _v2;
v2 = _v1;
}
}
public int CompareTo(Simplex other)
{
if (v1 > other.v1)
{
return 1;
}
if (v1 < other.v1)
{
return -1;
}
if (v2 > other.v2)
{
return 1;
}
if (v2 < other.v2)
{
return -1;
}
return 0;
}
};
public class Triangle
{
public Vertex v1;
public Vertex v2;
public Vertex v3;
float radius_square;
float cx;
float cy;
public Triangle(Vertex _v1, Vertex _v2, Vertex _v3)
{
v1 = _v1;
v2 = _v2;
v3 = _v3;
CalcCircle();
}
public bool isInCircle(float x, float y)
{
float dx, dy;
float dd;
dx = x - this.cx;
dy = y - this.cy;
dd = dx * dx + dy * dy;
if (dd < this.radius_square)
return true;
else
return false;
}
void CalcCircle()
{
// Calculate the center and the radius of a circle given by three points p1, p2, p3
// It is assumed, that the triangles vertices are already set correctly
double p1x, p2x, p1y, p2y, p3x, p3y;
// Deviation of this routine:
// A circle has the general equation (M-p)^2=r^2, where M and p are vectors
// this gives us three equations f(p)=r^2, each for one point p1, p2, p3
// putting respectively two equations together gives two equations
// f(p1)=f(p2) and f(p1)=f(p3)
// bringing all constant terms to one side brings them to the form
// M*v1=c1 resp.M*v2=c2 where v1=(p1-p2) and v2=(p1-p3) (still vectors)
// and c1, c2 are scalars (Naming conventions like the variables below)
// Now using the equations that are formed by the components of the vectors
// and isolate Mx lets you make one equation that only holds My
// The rest is straight forward and eaasy :-)
//
/* helping variables for temporary results */
double c1, c2;
double v1x, v1y, v2x, v2y;
double z, n;
double rx, ry;
// Readout the three points, the triangle consists of
p1x = v1.point.X;
p1y = v1.point.Y;
p2x = v2.point.X;
p2y = v2.point.Y;
p3x = v3.point.X;
p3y = v3.point.Y;
/* calc helping values first */
c1 = (p1x * p1x + p1y * p1y - p2x * p2x - p2y * p2y) / 2;
c2 = (p1x * p1x + p1y * p1y - p3x * p3x - p3y * p3y) / 2;
v1x = p1x - p2x;
v1y = p1y - p2y;
v2x = p1x - p3x;
v2y = p1y - p3y;
z = (c1 * v2x - c2 * v1x);
n = (v1y * v2x - v2y * v1x);
if (n == 0.0) // This is no triangle, i.e there are (at least) two points at the same location
{
radius_square = 0.0f;
return;
}
this.cy = (float)(z / n);
if (v2x != 0.0)
{
this.cx = (float)((c2 - v2y * this.cy) / v2x);
}
else if (v1x != 0.0)
{
this.cx = (float)((c1 - v1y * this.cy) / v1x);
}
else
{
Debug.Assert(false, "Malformed triangle"); /* Both terms zero means nothing good */
}
rx = (p1x - this.cx);
ry = (p1y - this.cy);
this.radius_square = (float)(rx * rx + ry * ry);
}
public List<Simplex> GetSimplices()
{
List<Simplex> result = new List<Simplex>();
Simplex s1 = new Simplex(v1, v2);
Simplex s2 = new Simplex(v2, v3);
Simplex s3 = new Simplex(v3, v1);
result.Add(s1);
result.Add(s2);
result.Add(s3);
return result;
}
public override String ToString()
{
NumberFormatInfo nfi = new NumberFormatInfo();
nfi.CurrencyDecimalDigits = 2;
nfi.CurrencyDecimalSeparator = ".";
String s1 = "<" + v1.point.X.ToString(nfi) + "," + v1.point.Y.ToString(nfi) + "," + v1.point.Z.ToString(nfi) + ">";
String s2 = "<" + v2.point.X.ToString(nfi) + "," + v2.point.Y.ToString(nfi) + "," + v2.point.Z.ToString(nfi) + ">";
String s3 = "<" + v3.point.X.ToString(nfi) + "," + v3.point.Y.ToString(nfi) + "," + v3.point.Z.ToString(nfi) + ">";
return s1 + ";" + s2 + ";" + s3;
}
public PhysicsVector getNormal()
{
// Vertices
// Vectors for edges
PhysicsVector e1;
PhysicsVector e2;
e1 = new PhysicsVector(v1.point.X - v2.point.X, v1.point.Y - v2.point.Y, v1.point.Z - v2.point.Z);
e2 = new PhysicsVector(v1.point.X - v3.point.X, v1.point.Y - v3.point.Y, v1.point.Z - v3.point.Z);
// Cross product for normal
PhysicsVector n = new PhysicsVector();
float nx, ny, nz;
n.X = e1.Y * e2.Z - e1.Z * e2.Y;
n.Y = e1.Z * e2.X - e1.X * e2.Z;
n.Z = e1.X * e2.Y - e1.Y * e2.X;
// Length
float l = (float)Math.Sqrt(n.X * n.X + n.Y * n.Y + n.Z * n.Z);
// Normalized "normal"
n.X /= l;
n.Y /= l;
n.Z /= l;
return n;
}
public void invertNormal()
{
Vertex vt;
vt = v1;
v1 = v2;
v2 = vt;
}
}

View File

@ -0,0 +1,560 @@
using System;
using System.Globalization;
using System.Diagnostics;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using OpenSim.Framework.Types;
using OpenSim.Region.Physics.Manager;
namespace OpenSim.Region.Physics.OdePlugin
{
public class Mesh
{
public List<Vertex> vertices;
public List<Triangle> triangles;
public float[] normals;
public Mesh()
{
vertices = new List<Vertex>();
triangles = new List<Triangle>();
}
public void Add(Triangle triangle)
{
int i;
i = vertices.IndexOf(triangle.v1);
if (i < 0)
throw new ArgumentException("Vertex v1 not known to mesh");
i = vertices.IndexOf(triangle.v2);
if (i < 0)
throw new ArgumentException("Vertex v2 not known to mesh");
i = vertices.IndexOf(triangle.v3);
if (i < 0)
throw new ArgumentException("Vertex v3 not known to mesh");
triangles.Add(triangle);
}
public void Add(Vertex v)
{
vertices.Add(v);
}
public float[] getVertexListAsFloat()
{
float[] result = new float[vertices.Count * 3];
for (int i = 0; i < vertices.Count; i++)
{
Vertex v = vertices[i];
PhysicsVector point = v.point;
result[3 * i + 0] = point.X;
result[3 * i + 1] = point.Y;
result[3 * i + 2] = point.Z;
}
GCHandle.Alloc(result, GCHandleType.Pinned);
return result;
}
public int[] getIndexListAsInt()
{
int[] result = new int[triangles.Count * 3];
for (int i = 0; i < triangles.Count; i++)
{
Triangle t = triangles[i];
result[3 * i + 0] = vertices.IndexOf(t.v1);
result[3 * i + 1] = vertices.IndexOf(t.v2);
result[3 * i + 2] = vertices.IndexOf(t.v3);
}
GCHandle.Alloc(result, GCHandleType.Pinned);
return result;
}
public void Append(Mesh newMesh)
{
foreach (Vertex v in newMesh.vertices)
vertices.Add(v);
foreach (Triangle t in newMesh.triangles)
Add(t);
}
}
public class Meshmerizer
{
static List<Triangle> FindInfluencedTriangles(List<Triangle> triangles, Vertex v)
{
List<Triangle> influenced = new List<Triangle>();
foreach (Triangle t in triangles)
{
float dx, dy;
if (t.isInCircle(v.point.X, v.point.Y))
{
influenced.Add(t);
}
}
return influenced;
}
static void InsertVertices(List<Vertex> vertices, int usedForSeed, List<Triangle> triangles, List<int> innerBorders)
{
// This is a variant of the delaunay algorithm
// each time a new vertex is inserted, all triangles that are influenced by it are deleted
// and replaced by new ones including the new vertex
// It is not very time efficient but easy to implement.
int iCurrentVertex;
int iMaxVertex=vertices.Count;
for (iCurrentVertex = usedForSeed; iCurrentVertex < iMaxVertex; iCurrentVertex++)
{
// Background: A triangle mesh fulfills the delaunay condition if (iff!)
// each circumlocutory circle (i.e. the circle that touches all three corners)
// of each triangle is empty of other vertices.
// Obviously a single (seeding) triangle fulfills this condition.
// If we now add one vertex, we need to reconstruct all triangles, that
// do not fulfill this condition with respect to the new triangle
// Find the triangles that are influenced by the new vertex
Vertex v=vertices[iCurrentVertex];
List<Triangle> influencedTriangles=FindInfluencedTriangles(triangles, v);
List<Simplex> simplices = new List<Simplex>();
// Reconstruction phase. First step, dissolve each triangle into it's simplices,
// i.e. it's "border lines"
// Goal is to find "inner" borders and delete them, while the hull gets conserved.
// Inner borders are special in the way that they always come twice, which is how we detect them
foreach (Triangle t in influencedTriangles)
{
List<Simplex> newSimplices = t.GetSimplices();
simplices.AddRange(newSimplices);
triangles.Remove(t);
}
// Now sort the simplices. That will make identical ones side by side in the list
simplices.Sort();
// Look for duplicate simplices here.
// Remember, they are directly side by side in the list right now
int iSimplex;
List<Simplex> innerSimplices=new List<Simplex>();
for (iSimplex = 1; iSimplex < simplices.Count; iSimplex++) // Startindex=1, so we can refer backwards
{
if (simplices[iSimplex - 1].CompareTo(simplices[iSimplex])==0)
{
innerSimplices.Add(simplices[iSimplex - 1]);
innerSimplices.Add(simplices[iSimplex]);
}
}
foreach (Simplex s in innerSimplices)
{
simplices.Remove(s);
}
// each simplex still in the list belongs to the hull of the region in question
// The new vertex (yes, we still deal with verices here :-) ) forms a triangle
// With each of these simplices. Build the new triangles and add them to the list
foreach (Simplex s in simplices)
{
Triangle t = new Triangle(s.v1, s.v2, vertices[iCurrentVertex]);
triangles.Add(t);
}
}
// At this point all vertices should be inserted into the mesh
// But the areas, that should be kept free still are filled with triangles
// We have to remove them. For this we have a list of indices to vertices.
// Each triangle that solemnly constists of vertices from the inner border
// are deleted
List<Triangle> innerTriangles = new List<Triangle>();
foreach (Triangle t in triangles)
{
if (
innerBorders.Contains(vertices.IndexOf(t.v1))
&& innerBorders.Contains(vertices.IndexOf(t.v2))
&& innerBorders.Contains(vertices.IndexOf(t.v3))
)
innerTriangles.Add(t);
}
foreach (Triangle t in innerTriangles)
{
triangles.Remove(t);
}
}
static Mesh CreateBoxMeshX(PrimitiveBaseShape primShape, PhysicsVector size)
// Builds the x (+ and -) surfaces of a box shaped prim
{
UInt16 hollowFactor = primShape.ProfileHollow;
Mesh meshMX = new Mesh();
// Surface 0, -X
meshMX.Add(new Vertex("-X-Y-Z", -size.X / 2.0f, -size.Y / 2.0f, -size.Z / 2.0f));
meshMX.Add(new Vertex("-X+Y-Z", -size.X / 2.0f, +size.Y / 2.0f, -size.Z / 2.0f));
meshMX.Add(new Vertex("-X-Y+Z", -size.X / 2.0f, -size.Y / 2.0f, +size.Z / 2.0f));
meshMX.Add(new Vertex("-X+Y+Z", -size.X / 2.0f, +size.Y / 2.0f, +size.Z / 2.0f));
meshMX.Add(new Triangle(meshMX.vertices[0], meshMX.vertices[2], meshMX.vertices[1]));
meshMX.Add(new Triangle(meshMX.vertices[1], meshMX.vertices[2], meshMX.vertices[3]));
Mesh meshPX = new Mesh();
// Surface 1, +X
meshPX.Add(new Vertex("+X-Y-Z", +size.X / 2.0f, -size.Y / 2.0f, -size.Z / 2.0f));
meshPX.Add(new Vertex("+X+Y-Z", +size.X / 2.0f, +size.Y / 2.0f, -size.Z / 2.0f));
meshPX.Add(new Vertex("+X-Y+Z", +size.X / 2.0f, -size.Y / 2.0f, +size.Z / 2.0f));
meshPX.Add(new Vertex("+X+Y+Z", +size.X / 2.0f, +size.Y / 2.0f, +size.Z / 2.0f));
meshPX.Add(new Triangle(meshPX.vertices[0], meshPX.vertices[1], meshPX.vertices[2]));
meshPX.Add(new Triangle(meshPX.vertices[2], meshPX.vertices[1], meshPX.vertices[3]));
if (hollowFactor > 0)
{
float hollowFactorF = (float)hollowFactor / (float)50000;
Vertex IPP;
Vertex IPM;
Vertex IMP;
Vertex IMM;
IPP = new Vertex("Inner-X+Y+Z", -size.X * hollowFactorF / 2.0f, +size.Y * hollowFactorF / 2.0f, +size.Z / 2.0f);
IPM = new Vertex("Inner-X+Y-Z", -size.X * hollowFactorF / 2.0f, +size.Y * hollowFactorF / 2.0f, -size.Z / 2.0f);
IMP = new Vertex("Inner-X-Y+Z", -size.X * hollowFactorF / 2.0f, -size.Y * hollowFactorF / 2.0f, +size.Z / 2.0f);
IMM = new Vertex("Inner-X-Y-Z", -size.X * hollowFactorF / 2.0f, -size.Y * hollowFactorF / 2.0f, -size.Z / 2.0f);
meshMX.Add(IPP);
meshMX.Add(IPM);
meshMX.Add(IMP);
meshMX.Add(IMM);
meshMX.Add(new Triangle(IPP, IMP, IPM));
meshMX.Add(new Triangle(IPM, IMP, IMM));
foreach (Triangle t in meshMX.triangles)
{
PhysicsVector n = t.getNormal();
}
IPP = new Vertex("Inner+X+Y+Z", +size.X * hollowFactorF / 2.0f, +size.Y * hollowFactorF / 2.0f, +size.Z / 2.0f);
IPM = new Vertex("Inner+X+Y-Z", +size.X * hollowFactorF / 2.0f, +size.Y * hollowFactorF / 2.0f, -size.Z / 2.0f);
IMP = new Vertex("Inner+X-Y+Z", +size.X * hollowFactorF / 2.0f, -size.Y * hollowFactorF / 2.0f, +size.Z / 2.0f);
IMM = new Vertex("Inner+X-Y-Z", +size.X * hollowFactorF / 2.0f, -size.Y * hollowFactorF / 2.0f, -size.Z / 2.0f);
meshPX.Add(IPP);
meshPX.Add(IPM);
meshPX.Add(IMP);
meshPX.Add(IMM);
meshPX.Add(new Triangle(IPP, IPM, IMP));
meshPX.Add(new Triangle(IMP, IPM, IMM));
foreach (Triangle t in meshPX.triangles)
{
PhysicsVector n = t.getNormal();
}
}
Mesh result = new Mesh();
result.Append(meshMX);
result.Append(meshPX);
return result;
}
static Mesh CreateBoxMeshY(PrimitiveBaseShape primShape, PhysicsVector size)
// Builds the y (+ and -) surfaces of a box shaped prim
{
UInt16 hollowFactor = primShape.ProfileHollow;
// (M)inus Y
Mesh MeshMY = new Mesh();
MeshMY.Add(new Vertex("-X-Y-Z", -size.X / 2.0f, -size.Y / 2.0f, -size.Z / 2.0f));
MeshMY.Add(new Vertex("+X-Y-Z", +size.X / 2.0f, -size.Y / 2.0f, -size.Z / 2.0f));
MeshMY.Add(new Vertex("-X-Y+Z", -size.X / 2.0f, -size.Y / 2.0f, +size.Z / 2.0f));
MeshMY.Add(new Vertex("+X-Y+Z", +size.X / 2.0f, -size.Y / 2.0f, +size.Z / 2.0f));
MeshMY.Add(new Triangle(MeshMY.vertices[0], MeshMY.vertices[1], MeshMY.vertices[2]));
MeshMY.Add(new Triangle(MeshMY.vertices[2], MeshMY.vertices[1], MeshMY.vertices[3]));
// (P)lus Y
Mesh MeshPY = new Mesh();
MeshPY.Add(new Vertex("-X+Y-Z", -size.X / 2.0f, +size.Y / 2.0f, -size.Z / 2.0f));
MeshPY.Add(new Vertex("+X+Y-Z", +size.X / 2.0f, +size.Y / 2.0f, -size.Z / 2.0f));
MeshPY.Add(new Vertex("-X+Y+Z", -size.X / 2.0f, +size.Y / 2.0f, +size.Z / 2.0f));
MeshPY.Add(new Vertex("+X+Y+Z", +size.X / 2.0f, +size.Y / 2.0f, +size.Z / 2.0f));
MeshPY.Add(new Triangle(MeshPY.vertices[1], MeshPY.vertices[0], MeshPY.vertices[2]));
MeshPY.Add(new Triangle(MeshPY.vertices[1], MeshPY.vertices[2], MeshPY.vertices[3]));
if (hollowFactor > 0)
{
float hollowFactorF = (float)hollowFactor / (float)50000;
Vertex IPP;
Vertex IPM;
Vertex IMP;
Vertex IMM;
IPP = new Vertex("Inner+X-Y+Z", +size.X * hollowFactorF / 2.0f, -size.Y * hollowFactorF / 2.0f, +size.Z / 2.0f);
IPM = new Vertex("Inner+X-Y-Z", +size.X * hollowFactorF / 2.0f, -size.Y * hollowFactorF / 2.0f, -size.Z / 2.0f);
IMP = new Vertex("Inner-X-Y+Z", -size.X * hollowFactorF / 2.0f, -size.Y * hollowFactorF / 2.0f, +size.Z / 2.0f);
IMM = new Vertex("Inner-X-Y-Z", -size.X * hollowFactorF / 2.0f, -size.Y * hollowFactorF / 2.0f, -size.Z / 2.0f);
MeshMY.Add(IPP);
MeshMY.Add(IPM);
MeshMY.Add(IMP);
MeshMY.Add(IMM);
MeshMY.Add(new Triangle(IPP, IPM, IMP));
MeshMY.Add(new Triangle(IMP, IPM, IMM));
foreach (Triangle t in MeshMY.triangles)
{
PhysicsVector n = t.getNormal();
}
IPP = new Vertex("Inner+X+Y+Z", +size.X * hollowFactorF / 2.0f, +size.Y * hollowFactorF / 2.0f, +size.Z / 2.0f);
IPM=new Vertex("Inner+X+Y-Z", +size.X * hollowFactorF / 2.0f, +size.Y * hollowFactorF / 2.0f, -size.Z / 2.0f);
IMP=new Vertex("Inner-X+Y+Z", -size.X * hollowFactorF / 2.0f, +size.Y * hollowFactorF / 2.0f, +size.Z / 2.0f);
IMM=new Vertex("Inner-X+Y-Z", -size.X * hollowFactorF / 2.0f, +size.Y * hollowFactorF / 2.0f, -size.Z / 2.0f);
MeshPY.Add(IPP);
MeshPY.Add(IPM);
MeshPY.Add(IMP);
MeshPY.Add(IMM);
MeshPY.Add(new Triangle(IPM, IPP, IMP));
MeshPY.Add(new Triangle(IMP, IMM, IPM));
foreach (Triangle t in MeshPY.triangles)
{
PhysicsVector n = t.getNormal();
}
}
Mesh result = new Mesh();
result.Append(MeshMY);
result.Append(MeshPY);
return result;
}
static Mesh CreateBoxMeshZ(PrimitiveBaseShape primShape, PhysicsVector size)
// Builds the z (+ and -) surfaces of a box shaped prim
{
UInt16 hollowFactor = primShape.ProfileHollow;
// Base, i.e. outer shape
// (M)inus Z
Mesh MZ = new Mesh();
MZ.Add(new Vertex("-X-Y-Z", -size.X / 2.0f, -size.Y / 2.0f, -size.Z / 2.0f));
MZ.Add(new Vertex("+X-Y-Z", +size.X / 2.0f, -size.Y / 2.0f, -size.Z / 2.0f));
MZ.Add(new Vertex("-X+Y-Z", -size.X / 2.0f, +size.Y / 2.0f, -size.Z / 2.0f));
MZ.Add(new Vertex("+X+Y-Z", +size.X / 2.0f, +size.Y / 2.0f, -size.Z / 2.0f));
MZ.Add(new Triangle(MZ.vertices[1], MZ.vertices[0], MZ.vertices[2]));
MZ.Add(new Triangle(MZ.vertices[1], MZ.vertices[2], MZ.vertices[3]));
// (P)lus Z
Mesh PZ = new Mesh();
PZ.Add(new Vertex("-X-Y+Z", -size.X / 2.0f, -size.Y / 2.0f, 0.0f));
PZ.Add(new Vertex("+X-Y+Z", +size.X / 2.0f, -size.Y / 2.0f, 0.0f));
PZ.Add(new Vertex("-X+Y+Z", -size.X / 2.0f, +size.Y / 2.0f, 0.0f));
PZ.Add(new Vertex("+X+Y+Z", +size.X / 2.0f, +size.Y / 2.0f, 0.0f));
// Surface 5, +Z
PZ.Add(new Triangle(PZ.vertices[0], PZ.vertices[1], PZ.vertices[2]));
PZ.Add(new Triangle(PZ.vertices[2], PZ.vertices[1], PZ.vertices[3]));
if (hollowFactor > 0)
{
float hollowFactorF = (float)hollowFactor / (float)50000;
MZ.Add(new Vertex("-X-Y-Z", -size.X * hollowFactorF / 2.0f, -size.Y * hollowFactorF / 2.0f, 0.0f));
MZ.Add(new Vertex("-X+Y-Z", +size.X * hollowFactorF / 2.0f, -size.Y * hollowFactorF / 2.0f, 0.0f));
MZ.Add(new Vertex("-X-Y+Z", -size.X * hollowFactorF / 2.0f, +size.Y * hollowFactorF / 2.0f, 0.0f));
MZ.Add(new Vertex("-X+Y+Z", +size.X * hollowFactorF / 2.0f, +size.Y * hollowFactorF / 2.0f, 0.0f));
List<int> innerBorders = new List<int>();
innerBorders.Add(4);
innerBorders.Add(5);
innerBorders.Add(6);
innerBorders.Add(7);
InsertVertices(MZ.vertices, 4, MZ.triangles, innerBorders);
PZ.Add(new Vertex("-X-Y-Z", -size.X * hollowFactorF / 2.0f, -size.Y * hollowFactorF / 2.0f, 0.0f));
PZ.Add(new Vertex("-X+Y-Z", +size.X * hollowFactorF / 2.0f, -size.Y * hollowFactorF / 2.0f, 0.0f));
PZ.Add(new Vertex("-X-Y+Z", -size.X * hollowFactorF / 2.0f, +size.Y * hollowFactorF / 2.0f, 0.0f));
PZ.Add(new Vertex("-X+Y+Z", +size.X * hollowFactorF / 2.0f, +size.Y * hollowFactorF / 2.0f, 0.0f));
innerBorders = new List<int>();
innerBorders.Add(4);
innerBorders.Add(5);
innerBorders.Add(6);
innerBorders.Add(7);
InsertVertices(PZ.vertices, 4, PZ.triangles, innerBorders);
}
foreach (Vertex v in PZ.vertices)
{
v.point.Z = size.Z / 2.0f;
}
foreach (Vertex v in MZ.vertices)
{
v.point.Z = -size.Z / 2.0f;
}
foreach (Triangle t in MZ.triangles)
{
PhysicsVector n = t.getNormal();
if (n.Z > 0.0)
t.invertNormal();
}
foreach (Triangle t in PZ.triangles)
{
PhysicsVector n = t.getNormal();
if (n.Z < 0.0)
t.invertNormal();
}
Mesh result = new Mesh();
result.Append(MZ);
result.Append(PZ);
return result;
}
static Mesh CreateBoxMesh(PrimitiveBaseShape primShape, PhysicsVector size)
{
Mesh result = new Mesh();
Mesh MeshX = Meshmerizer.CreateBoxMeshX(primShape, size);
Mesh MeshY = Meshmerizer.CreateBoxMeshY(primShape, size);
Mesh MeshZ = Meshmerizer.CreateBoxMeshZ(primShape, size);
result.Append(MeshX);
result.Append(MeshY);
result.Append(MeshZ);
return result;
}
public static void CalcNormals(Mesh mesh)
{
int iTriangles = mesh.triangles.Count;
mesh.normals = new float[iTriangles*3];
int i=0;
foreach (Triangle t in mesh.triangles)
{
float ux, uy, uz;
float vx, vy, vz;
float wx, wy, wz;
ux = t.v1.point.X;
uy = t.v1.point.Y;
uz = t.v1.point.Z;
vx = t.v2.point.X;
vy = t.v2.point.Y;
vz = t.v2.point.Z;
wx = t.v3.point.X;
wy = t.v3.point.Y;
wz = t.v3.point.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);
// Normalized "normal"
nx /= l;
ny /= l;
nz /= l;
mesh.normals[i] = nx;
mesh.normals[i + 1] = ny;
mesh.normals[i + 2] = nz;
i+=3;
}
}
public static Mesh CreateMesh(PrimitiveBaseShape primShape, PhysicsVector size)
{
Mesh mesh = null;
switch (primShape.ProfileShape)
{
case ProfileShape.Square:
mesh=CreateBoxMesh(primShape, size);
CalcNormals(mesh);
break;
default:
mesh=null;
break;
}
return mesh;
}
}
}