mirror of
https://github.com/opensim/opensim.git
synced 2026-08-07 01:35:46 +08:00
* Moves the Meshmerizer to a separate plugin
* Experimental. Linux Prebuild needs testing. * One more update after this to remove the ODEMeshing directory....
This commit is contained in:
198
OpenSim/Region/Physics/Meshing/Simplex.cs
Normal file
198
OpenSim/Region/Physics/Meshing/Simplex.cs
Normal file
@@ -0,0 +1,198 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using OpenSim.Region.Physics.Manager;
|
||||
|
||||
namespace OpenSim.Region.Physics.Meshing
|
||||
{
|
||||
// A simplex is a section of a straight line.
|
||||
// It is defined by its endpoints, i.e. by two vertices
|
||||
// Operation on vertices are
|
||||
public class Simplex : IComparable<Simplex>
|
||||
{
|
||||
public Vertex v1;
|
||||
public Vertex v2;
|
||||
|
||||
public Simplex(Vertex _v1, Vertex _v2)
|
||||
{
|
||||
v1 = _v1;
|
||||
v2 = _v2;
|
||||
}
|
||||
|
||||
public int CompareTo(Simplex other)
|
||||
{
|
||||
|
||||
Vertex lv1, lv2, ov1, ov2, temp;
|
||||
|
||||
lv1 = v1;
|
||||
lv2 = v2;
|
||||
ov1 = other.v1;
|
||||
ov2 = other.v2;
|
||||
|
||||
if (lv1 > lv2)
|
||||
{
|
||||
temp = lv1;
|
||||
lv1 = lv2;
|
||||
lv2 = temp;
|
||||
}
|
||||
|
||||
if (ov1 > ov2)
|
||||
{
|
||||
temp = ov1;
|
||||
ov1 = ov2;
|
||||
ov2 = temp;
|
||||
}
|
||||
|
||||
if (lv1 > ov1)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
if (lv1 < ov1)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (lv2 > ov2)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
if (lv2 < ov2)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
private static void intersectParameter(PhysicsVector p1, PhysicsVector r1, PhysicsVector p2, PhysicsVector r2, ref float lambda, ref float mu)
|
||||
{
|
||||
// Intersects two straights
|
||||
// p1, p2, points on the straight
|
||||
// r1, r2, directional vectors of the straight. Not necessarily of length 1!
|
||||
// note, that l, m can be scaled such, that the range 0..1 is mapped to the area between two points,
|
||||
// thus allowing to decide whether an intersection is between two points
|
||||
|
||||
float r1x = r1.X;
|
||||
float r1y = r1.Y;
|
||||
float r2x = r2.X;
|
||||
float r2y = r2.Y;
|
||||
|
||||
float denom = r1y*r2x - r1x*r2y;
|
||||
|
||||
float p1x = p1.X;
|
||||
float p1y = p1.Y;
|
||||
float p2x = p2.X;
|
||||
float p2y = p2.Y;
|
||||
|
||||
float z1=-p2x * r2y + p1x * r2y + (p2y - p1y) * r2x;
|
||||
float z2=-p2x * r1y + p1x * r1y + (p2y - p1y) * r1x;
|
||||
|
||||
if (denom == 0.0f) // Means the straights are parallel. Either no intersection or an infinite number of them
|
||||
{
|
||||
if (z1==0.0f) {// Means they are identical -> many, many intersections
|
||||
lambda = Single.NaN;
|
||||
mu = Single.NaN;
|
||||
} else {
|
||||
lambda = Single.PositiveInfinity;
|
||||
mu = Single.PositiveInfinity;
|
||||
}
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
lambda = z1 / denom;
|
||||
mu = z2 / denom;
|
||||
|
||||
}
|
||||
|
||||
|
||||
// Intersects the simplex with another one.
|
||||
// the borders are used to deal with float inaccuracies
|
||||
// As a rule of thumb, the borders are
|
||||
// lowerBorder1 : 0.0
|
||||
// lowerBorder2 : 0.0
|
||||
// upperBorder1 : 1.0
|
||||
// upperBorder2 : 1.0
|
||||
// Set these to values near the given parameters (e.g. 0.001 instead of 1 to exclude simplex starts safely, or to -0.001 to include them safely)
|
||||
public static PhysicsVector Intersect(
|
||||
Simplex s1,
|
||||
Simplex s2,
|
||||
float lowerBorder1,
|
||||
float lowerBorder2,
|
||||
float upperBorder1,
|
||||
float upperBorder2)
|
||||
{
|
||||
PhysicsVector firstSimplexDirection = s1.v2 - s1.v1;
|
||||
PhysicsVector secondSimplexDirection = s2.v2 - s2.v1;
|
||||
|
||||
float lambda = 0.0f;
|
||||
float mu = 0.0f;
|
||||
|
||||
// Give us the parameters of an intersection. This subroutine does *not* take the constraints
|
||||
// (intersection must be between v1 and v2 and it must be in the positive direction of the ray)
|
||||
// into account. We do that afterwards.
|
||||
intersectParameter(s1.v1, firstSimplexDirection, s2.v1, secondSimplexDirection, ref lambda, ref mu);
|
||||
|
||||
if (Single.IsInfinity(lambda)) // Special case. No intersection at all. directions parallel.
|
||||
return null;
|
||||
|
||||
if (Single.IsNaN(lambda)) // Special case. many, many intersections.
|
||||
return null;
|
||||
|
||||
if (lambda > upperBorder1) // We're behind v2
|
||||
return null;
|
||||
|
||||
if (lambda < lowerBorder1)
|
||||
return null;
|
||||
|
||||
if (mu < lowerBorder2) // outside simplex 2
|
||||
return null;
|
||||
|
||||
if (mu > upperBorder2) // outside simplex 2
|
||||
return null;
|
||||
|
||||
return s1.v1 + lambda * firstSimplexDirection;
|
||||
|
||||
}
|
||||
|
||||
// Intersects the simplex with a ray. The ray is defined as all p=origin + lambda*direction
|
||||
// where lambda >= 0
|
||||
public PhysicsVector RayIntersect(Vertex origin, PhysicsVector direction, bool bEndsIncluded)
|
||||
{
|
||||
PhysicsVector simplexDirection = v2 - v1;
|
||||
|
||||
float lambda = 0.0f;
|
||||
float mu = 0.0f;
|
||||
|
||||
// Give us the parameters of an intersection. This subroutine does *not* take the constraints
|
||||
// (intersection must be between v1 and v2 and it must be in the positive direction of the ray)
|
||||
// into account. We do that afterwards.
|
||||
intersectParameter(v1, simplexDirection, origin, direction, ref lambda, ref mu);
|
||||
|
||||
if (Single.IsInfinity(lambda)) // Special case. No intersection at all. directions parallel.
|
||||
return null;
|
||||
|
||||
if (Single.IsNaN(lambda)) // Special case. many, many intersections.
|
||||
return null;
|
||||
|
||||
if (mu < 0.0) // We're on the wrong side of the ray
|
||||
return null;
|
||||
|
||||
if (lambda > 1.0) // We're behind v2
|
||||
return null;
|
||||
|
||||
if (lambda == 1.0 && !bEndsIncluded)
|
||||
return null; // The end of the simplices are not included
|
||||
|
||||
if (lambda < 0.0f) // we're before v1;
|
||||
return null;
|
||||
|
||||
return this.v1 + lambda * simplexDirection;
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user