diff options
Diffstat (limited to '')
-rw-r--r-- | OpenSim/Region/Physics/Meshing/Simplex.cs | 394 |
1 files changed, 197 insertions, 197 deletions
diff --git a/OpenSim/Region/Physics/Meshing/Simplex.cs b/OpenSim/Region/Physics/Meshing/Simplex.cs index 4944f22..42dbefa 100644 --- a/OpenSim/Region/Physics/Meshing/Simplex.cs +++ b/OpenSim/Region/Physics/Meshing/Simplex.cs | |||
@@ -1,198 +1,198 @@ | |||
1 | using System; | 1 | using System; |
2 | using System.Collections.Generic; | 2 | using System.Collections.Generic; |
3 | using System.Text; | 3 | using System.Text; |
4 | using OpenSim.Region.Physics.Manager; | 4 | using OpenSim.Region.Physics.Manager; |
5 | 5 | ||
6 | namespace OpenSim.Region.Physics.Meshing | 6 | namespace OpenSim.Region.Physics.Meshing |
7 | { | 7 | { |
8 | // A simplex is a section of a straight line. | 8 | // A simplex is a section of a straight line. |
9 | // It is defined by its endpoints, i.e. by two vertices | 9 | // It is defined by its endpoints, i.e. by two vertices |
10 | // Operation on vertices are | 10 | // Operation on vertices are |
11 | public class Simplex : IComparable<Simplex> | 11 | public class Simplex : IComparable<Simplex> |
12 | { | 12 | { |
13 | public Vertex v1; | 13 | public Vertex v1; |
14 | public Vertex v2; | 14 | public Vertex v2; |
15 | 15 | ||
16 | public Simplex(Vertex _v1, Vertex _v2) | 16 | public Simplex(Vertex _v1, Vertex _v2) |
17 | { | 17 | { |
18 | v1 = _v1; | 18 | v1 = _v1; |
19 | v2 = _v2; | 19 | v2 = _v2; |
20 | } | 20 | } |
21 | 21 | ||
22 | public int CompareTo(Simplex other) | 22 | public int CompareTo(Simplex other) |
23 | { | 23 | { |
24 | 24 | ||
25 | Vertex lv1, lv2, ov1, ov2, temp; | 25 | Vertex lv1, lv2, ov1, ov2, temp; |
26 | 26 | ||
27 | lv1 = v1; | 27 | lv1 = v1; |
28 | lv2 = v2; | 28 | lv2 = v2; |
29 | ov1 = other.v1; | 29 | ov1 = other.v1; |
30 | ov2 = other.v2; | 30 | ov2 = other.v2; |
31 | 31 | ||
32 | if (lv1 > lv2) | 32 | if (lv1 > lv2) |
33 | { | 33 | { |
34 | temp = lv1; | 34 | temp = lv1; |
35 | lv1 = lv2; | 35 | lv1 = lv2; |
36 | lv2 = temp; | 36 | lv2 = temp; |
37 | } | 37 | } |
38 | 38 | ||
39 | if (ov1 > ov2) | 39 | if (ov1 > ov2) |
40 | { | 40 | { |
41 | temp = ov1; | 41 | temp = ov1; |
42 | ov1 = ov2; | 42 | ov1 = ov2; |
43 | ov2 = temp; | 43 | ov2 = temp; |
44 | } | 44 | } |
45 | 45 | ||
46 | if (lv1 > ov1) | 46 | if (lv1 > ov1) |
47 | { | 47 | { |
48 | return 1; | 48 | return 1; |
49 | } | 49 | } |
50 | if (lv1 < ov1) | 50 | if (lv1 < ov1) |
51 | { | 51 | { |
52 | return -1; | 52 | return -1; |
53 | } | 53 | } |
54 | 54 | ||
55 | if (lv2 > ov2) | 55 | if (lv2 > ov2) |
56 | { | 56 | { |
57 | return 1; | 57 | return 1; |
58 | } | 58 | } |
59 | if (lv2 < ov2) | 59 | if (lv2 < ov2) |
60 | { | 60 | { |
61 | return -1; | 61 | return -1; |
62 | } | 62 | } |
63 | 63 | ||
64 | return 0; | 64 | return 0; |
65 | } | 65 | } |
66 | 66 | ||
67 | private static void intersectParameter(PhysicsVector p1, PhysicsVector r1, PhysicsVector p2, PhysicsVector r2, ref float lambda, ref float mu) | 67 | private static void intersectParameter(PhysicsVector p1, PhysicsVector r1, PhysicsVector p2, PhysicsVector r2, ref float lambda, ref float mu) |
68 | { | 68 | { |
69 | // Intersects two straights | 69 | // Intersects two straights |
70 | // p1, p2, points on the straight | 70 | // p1, p2, points on the straight |
71 | // r1, r2, directional vectors of the straight. Not necessarily of length 1! | 71 | // r1, r2, directional vectors of the straight. Not necessarily of length 1! |
72 | // note, that l, m can be scaled such, that the range 0..1 is mapped to the area between two points, | 72 | // note, that l, m can be scaled such, that the range 0..1 is mapped to the area between two points, |
73 | // thus allowing to decide whether an intersection is between two points | 73 | // thus allowing to decide whether an intersection is between two points |
74 | 74 | ||
75 | float r1x = r1.X; | 75 | float r1x = r1.X; |
76 | float r1y = r1.Y; | 76 | float r1y = r1.Y; |
77 | float r2x = r2.X; | 77 | float r2x = r2.X; |
78 | float r2y = r2.Y; | 78 | float r2y = r2.Y; |
79 | 79 | ||
80 | float denom = r1y*r2x - r1x*r2y; | 80 | float denom = r1y*r2x - r1x*r2y; |
81 | 81 | ||
82 | float p1x = p1.X; | 82 | float p1x = p1.X; |
83 | float p1y = p1.Y; | 83 | float p1y = p1.Y; |
84 | float p2x = p2.X; | 84 | float p2x = p2.X; |
85 | float p2y = p2.Y; | 85 | float p2y = p2.Y; |
86 | 86 | ||
87 | float z1=-p2x * r2y + p1x * r2y + (p2y - p1y) * r2x; | 87 | float z1=-p2x * r2y + p1x * r2y + (p2y - p1y) * r2x; |
88 | float z2=-p2x * r1y + p1x * r1y + (p2y - p1y) * r1x; | 88 | float z2=-p2x * r1y + p1x * r1y + (p2y - p1y) * r1x; |
89 | 89 | ||
90 | if (denom == 0.0f) // Means the straights are parallel. Either no intersection or an infinite number of them | 90 | if (denom == 0.0f) // Means the straights are parallel. Either no intersection or an infinite number of them |
91 | { | 91 | { |
92 | if (z1==0.0f) {// Means they are identical -> many, many intersections | 92 | if (z1==0.0f) {// Means they are identical -> many, many intersections |
93 | lambda = Single.NaN; | 93 | lambda = Single.NaN; |
94 | mu = Single.NaN; | 94 | mu = Single.NaN; |
95 | } else { | 95 | } else { |
96 | lambda = Single.PositiveInfinity; | 96 | lambda = Single.PositiveInfinity; |
97 | mu = Single.PositiveInfinity; | 97 | mu = Single.PositiveInfinity; |
98 | } | 98 | } |
99 | return; | 99 | return; |
100 | 100 | ||
101 | } | 101 | } |
102 | 102 | ||
103 | 103 | ||
104 | 104 | ||
105 | lambda = z1 / denom; | 105 | lambda = z1 / denom; |
106 | mu = z2 / denom; | 106 | mu = z2 / denom; |
107 | 107 | ||
108 | } | 108 | } |
109 | 109 | ||
110 | 110 | ||
111 | // Intersects the simplex with another one. | 111 | // Intersects the simplex with another one. |
112 | // the borders are used to deal with float inaccuracies | 112 | // the borders are used to deal with float inaccuracies |
113 | // As a rule of thumb, the borders are | 113 | // As a rule of thumb, the borders are |
114 | // lowerBorder1 : 0.0 | 114 | // lowerBorder1 : 0.0 |
115 | // lowerBorder2 : 0.0 | 115 | // lowerBorder2 : 0.0 |
116 | // upperBorder1 : 1.0 | 116 | // upperBorder1 : 1.0 |
117 | // upperBorder2 : 1.0 | 117 | // upperBorder2 : 1.0 |
118 | // 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) | 118 | // 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) |
119 | public static PhysicsVector Intersect( | 119 | public static PhysicsVector Intersect( |
120 | Simplex s1, | 120 | Simplex s1, |
121 | Simplex s2, | 121 | Simplex s2, |
122 | float lowerBorder1, | 122 | float lowerBorder1, |
123 | float lowerBorder2, | 123 | float lowerBorder2, |
124 | float upperBorder1, | 124 | float upperBorder1, |
125 | float upperBorder2) | 125 | float upperBorder2) |
126 | { | 126 | { |
127 | PhysicsVector firstSimplexDirection = s1.v2 - s1.v1; | 127 | PhysicsVector firstSimplexDirection = s1.v2 - s1.v1; |
128 | PhysicsVector secondSimplexDirection = s2.v2 - s2.v1; | 128 | PhysicsVector secondSimplexDirection = s2.v2 - s2.v1; |
129 | 129 | ||
130 | float lambda = 0.0f; | 130 | float lambda = 0.0f; |
131 | float mu = 0.0f; | 131 | float mu = 0.0f; |
132 | 132 | ||
133 | // Give us the parameters of an intersection. This subroutine does *not* take the constraints | 133 | // Give us the parameters of an intersection. This subroutine does *not* take the constraints |
134 | // (intersection must be between v1 and v2 and it must be in the positive direction of the ray) | 134 | // (intersection must be between v1 and v2 and it must be in the positive direction of the ray) |
135 | // into account. We do that afterwards. | 135 | // into account. We do that afterwards. |
136 | intersectParameter(s1.v1, firstSimplexDirection, s2.v1, secondSimplexDirection, ref lambda, ref mu); | 136 | intersectParameter(s1.v1, firstSimplexDirection, s2.v1, secondSimplexDirection, ref lambda, ref mu); |
137 | 137 | ||
138 | if (Single.IsInfinity(lambda)) // Special case. No intersection at all. directions parallel. | 138 | if (Single.IsInfinity(lambda)) // Special case. No intersection at all. directions parallel. |
139 | return null; | 139 | return null; |
140 | 140 | ||
141 | if (Single.IsNaN(lambda)) // Special case. many, many intersections. | 141 | if (Single.IsNaN(lambda)) // Special case. many, many intersections. |
142 | return null; | 142 | return null; |
143 | 143 | ||
144 | if (lambda > upperBorder1) // We're behind v2 | 144 | if (lambda > upperBorder1) // We're behind v2 |
145 | return null; | 145 | return null; |
146 | 146 | ||
147 | if (lambda < lowerBorder1) | 147 | if (lambda < lowerBorder1) |
148 | return null; | 148 | return null; |
149 | 149 | ||
150 | if (mu < lowerBorder2) // outside simplex 2 | 150 | if (mu < lowerBorder2) // outside simplex 2 |
151 | return null; | 151 | return null; |
152 | 152 | ||
153 | if (mu > upperBorder2) // outside simplex 2 | 153 | if (mu > upperBorder2) // outside simplex 2 |
154 | return null; | 154 | return null; |
155 | 155 | ||
156 | return s1.v1 + lambda * firstSimplexDirection; | 156 | return s1.v1 + lambda * firstSimplexDirection; |
157 | 157 | ||
158 | } | 158 | } |
159 | 159 | ||
160 | // Intersects the simplex with a ray. The ray is defined as all p=origin + lambda*direction | 160 | // Intersects the simplex with a ray. The ray is defined as all p=origin + lambda*direction |
161 | // where lambda >= 0 | 161 | // where lambda >= 0 |
162 | public PhysicsVector RayIntersect(Vertex origin, PhysicsVector direction, bool bEndsIncluded) | 162 | public PhysicsVector RayIntersect(Vertex origin, PhysicsVector direction, bool bEndsIncluded) |
163 | { | 163 | { |
164 | PhysicsVector simplexDirection = v2 - v1; | 164 | PhysicsVector simplexDirection = v2 - v1; |
165 | 165 | ||
166 | float lambda = 0.0f; | 166 | float lambda = 0.0f; |
167 | float mu = 0.0f; | 167 | float mu = 0.0f; |
168 | 168 | ||
169 | // Give us the parameters of an intersection. This subroutine does *not* take the constraints | 169 | // Give us the parameters of an intersection. This subroutine does *not* take the constraints |
170 | // (intersection must be between v1 and v2 and it must be in the positive direction of the ray) | 170 | // (intersection must be between v1 and v2 and it must be in the positive direction of the ray) |
171 | // into account. We do that afterwards. | 171 | // into account. We do that afterwards. |
172 | intersectParameter(v1, simplexDirection, origin, direction, ref lambda, ref mu); | 172 | intersectParameter(v1, simplexDirection, origin, direction, ref lambda, ref mu); |
173 | 173 | ||
174 | if (Single.IsInfinity(lambda)) // Special case. No intersection at all. directions parallel. | 174 | if (Single.IsInfinity(lambda)) // Special case. No intersection at all. directions parallel. |
175 | return null; | 175 | return null; |
176 | 176 | ||
177 | if (Single.IsNaN(lambda)) // Special case. many, many intersections. | 177 | if (Single.IsNaN(lambda)) // Special case. many, many intersections. |
178 | return null; | 178 | return null; |
179 | 179 | ||
180 | if (mu < 0.0) // We're on the wrong side of the ray | 180 | if (mu < 0.0) // We're on the wrong side of the ray |
181 | return null; | 181 | return null; |
182 | 182 | ||
183 | if (lambda > 1.0) // We're behind v2 | 183 | if (lambda > 1.0) // We're behind v2 |
184 | return null; | 184 | return null; |
185 | 185 | ||
186 | if (lambda == 1.0 && !bEndsIncluded) | 186 | if (lambda == 1.0 && !bEndsIncluded) |
187 | return null; // The end of the simplices are not included | 187 | return null; // The end of the simplices are not included |
188 | 188 | ||
189 | if (lambda < 0.0f) // we're before v1; | 189 | if (lambda < 0.0f) // we're before v1; |
190 | return null; | 190 | return null; |
191 | 191 | ||
192 | return this.v1 + lambda * simplexDirection; | 192 | return this.v1 + lambda * simplexDirection; |
193 | 193 | ||
194 | } | 194 | } |
195 | 195 | ||
196 | 196 | ||
197 | } | 197 | } |
198 | } \ No newline at end of file | 198 | } \ No newline at end of file |