aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region')
-rw-r--r--OpenSim/Region/Physics/BulletXPlugin/TriangleIndexVertexArray.cs322
-rw-r--r--OpenSim/Region/Physics/Manager/IMesher.cs52
-rw-r--r--OpenSim/Region/Physics/Meshing/Extruder.cs166
-rw-r--r--OpenSim/Region/Physics/Meshing/HelperTypes.cs610
-rw-r--r--OpenSim/Region/Physics/Meshing/Mesh.cs426
-rw-r--r--OpenSim/Region/Physics/Meshing/Meshmerizer.cs786
-rw-r--r--OpenSim/Region/Physics/Meshing/SimpleHull.cs726
-rw-r--r--OpenSim/Region/Physics/Meshing/Simplex.cs394
8 files changed, 1741 insertions, 1741 deletions
diff --git a/OpenSim/Region/Physics/BulletXPlugin/TriangleIndexVertexArray.cs b/OpenSim/Region/Physics/BulletXPlugin/TriangleIndexVertexArray.cs
index fb30296..4f63687 100644
--- a/OpenSim/Region/Physics/BulletXPlugin/TriangleIndexVertexArray.cs
+++ b/OpenSim/Region/Physics/BulletXPlugin/TriangleIndexVertexArray.cs
@@ -1,161 +1,161 @@
1/* 1/*
2 Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru 2 Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
3 Bullet original C++ version Copyright (c) 2003-2007 Erwin Coumans http://bulletphysics.com 3 Bullet original C++ version Copyright (c) 2003-2007 Erwin Coumans http://bulletphysics.com
4 4
5 This software is provided 'as-is', without any express or implied 5 This software is provided 'as-is', without any express or implied
6 warranty. In no event will the authors be held liable for any damages 6 warranty. In no event will the authors be held liable for any damages
7 arising from the use of this software. 7 arising from the use of this software.
8 8
9 Permission is granted to anyone to use this software for any purpose, 9 Permission is granted to anyone to use this software for any purpose,
10 including commercial applications, and to alter it and redistribute it 10 including commercial applications, and to alter it and redistribute it
11 freely, subject to the following restrictions: 11 freely, subject to the following restrictions:
12 12
13 1. The origin of this software must not be misrepresented; you must not 13 1. The origin of this software must not be misrepresented; you must not
14 claim that you wrote the original software. If you use this software 14 claim that you wrote the original software. If you use this software
15 in a product, an acknowledgment in the product documentation would be 15 in a product, an acknowledgment in the product documentation would be
16 appreciated but is not required. 16 appreciated but is not required.
17 2. Altered source versions must be plainly marked as such, and must not be 17 2. Altered source versions must be plainly marked as such, and must not be
18 misrepresented as being the original software. 18 misrepresented as being the original software.
19 3. This notice may not be removed or altered from any source distribution. 19 3. This notice may not be removed or altered from any source distribution.
20*/ 20*/
21 21
22/* 22/*
23 23
24 This file contains a class TriangleIndexVertexArray. I tried using the class with the same name 24 This file contains a class TriangleIndexVertexArray. I tried using the class with the same name
25 from the BulletX implementation and found it unusable for the purpose of using triangle meshes 25 from the BulletX implementation and found it unusable for the purpose of using triangle meshes
26 within BulletX as the implementation was painfully incomplete. 26 within BulletX as the implementation was painfully incomplete.
27 The attempt to derive from the original class failed as viable members were hidden. 27 The attempt to derive from the original class failed as viable members were hidden.
28 Fiddling around with BulletX itself was not my intention. 28 Fiddling around with BulletX itself was not my intention.
29 So I copied the class to the BulletX-plugin and modified it. 29 So I copied the class to the BulletX-plugin and modified it.
30 If you want to fiddle around with it it's up to you to move all this to BulletX. 30 If you want to fiddle around with it it's up to you to move all this to BulletX.
31 If someone someday implements the missing functionality in BulletX, feel free to remove this class. 31 If someone someday implements the missing functionality in BulletX, feel free to remove this class.
32 It's just an ugly hack. 32 It's just an ugly hack.
33 33
34 */ 34 */
35using System; 35using System;
36using System.Collections.Generic; 36using System.Collections.Generic;
37using System.Text; 37using System.Text;
38using MonoXnaCompactMaths; 38using MonoXnaCompactMaths;
39 39
40namespace OpenSim.Region.Physics.BulletXPlugin 40namespace OpenSim.Region.Physics.BulletXPlugin
41{ 41{
42 /// <summary> 42 /// <summary>
43 /// IndexedMesh indexes into existing vertex and index arrays, in a similar way OpenGL glDrawElements 43 /// IndexedMesh indexes into existing vertex and index arrays, in a similar way OpenGL glDrawElements
44 /// instead of the number of indices, we pass the number of triangles 44 /// instead of the number of indices, we pass the number of triangles
45 /// </summary> 45 /// </summary>
46 public struct IndexedMesh 46 public struct IndexedMesh
47 { 47 {
48 private int _numTriangles; 48 private int _numTriangles;
49 private int[] _triangleIndexBase; 49 private int[] _triangleIndexBase;
50 private int _triangleIndexStride; 50 private int _triangleIndexStride;
51 private int _numVertices; 51 private int _numVertices;
52 private Vector3[] _vertexBase; 52 private Vector3[] _vertexBase;
53 private int _vertexStride; 53 private int _vertexStride;
54 54
55 public IndexedMesh(int numTriangleIndices, int[] triangleIndexBase, int triangleIndexStride, int numVertices, Vector3[] vertexBase, int vertexStride) 55 public IndexedMesh(int numTriangleIndices, int[] triangleIndexBase, int triangleIndexStride, int numVertices, Vector3[] vertexBase, int vertexStride)
56 { 56 {
57 _numTriangles = numTriangleIndices; 57 _numTriangles = numTriangleIndices;
58 _triangleIndexBase = triangleIndexBase; 58 _triangleIndexBase = triangleIndexBase;
59 _triangleIndexStride = triangleIndexStride; 59 _triangleIndexStride = triangleIndexStride;
60 _vertexBase = vertexBase; 60 _vertexBase = vertexBase;
61 _numVertices = numVertices; 61 _numVertices = numVertices;
62 _vertexStride = vertexStride; 62 _vertexStride = vertexStride;
63 } 63 }
64 64
65 public IndexedMesh(int[] triangleIndexBase, Vector3[] vertexBase) 65 public IndexedMesh(int[] triangleIndexBase, Vector3[] vertexBase)
66 { 66 {
67 _numTriangles = triangleIndexBase.Length; 67 _numTriangles = triangleIndexBase.Length;
68 _triangleIndexBase = triangleIndexBase; 68 _triangleIndexBase = triangleIndexBase;
69 _triangleIndexStride = 32; 69 _triangleIndexStride = 32;
70 _vertexBase = vertexBase; 70 _vertexBase = vertexBase;
71 _numVertices = vertexBase.Length; 71 _numVertices = vertexBase.Length;
72 _vertexStride = 24; 72 _vertexStride = 24;
73 } 73 }
74 74
75 public int TriangleCount { get { return _numTriangles; } set { _numTriangles = value; } } 75 public int TriangleCount { get { return _numTriangles; } set { _numTriangles = value; } }
76 public int[] TriangleIndexBase { get { return _triangleIndexBase; } set { _triangleIndexBase = value; } } 76 public int[] TriangleIndexBase { get { return _triangleIndexBase; } set { _triangleIndexBase = value; } }
77 public int TriangleIndexStride { get { return _triangleIndexStride; } set { _triangleIndexStride = value; } } 77 public int TriangleIndexStride { get { return _triangleIndexStride; } set { _triangleIndexStride = value; } }
78 public int VertexCount { get { return _numVertices; } set { _numVertices = value; } } 78 public int VertexCount { get { return _numVertices; } set { _numVertices = value; } }
79 public Vector3[] VertexBase { get { return _vertexBase; } set { _vertexBase = value; } } 79 public Vector3[] VertexBase { get { return _vertexBase; } set { _vertexBase = value; } }
80 public int VertexStride { get { return _vertexStride; } set { _vertexStride = value; } } 80 public int VertexStride { get { return _vertexStride; } set { _vertexStride = value; } }
81 } 81 }
82 82
83 /// <summary> 83 /// <summary>
84 /// TriangleIndexVertexArray allows to use multiple meshes, by indexing into existing triangle/index arrays. 84 /// TriangleIndexVertexArray allows to use multiple meshes, by indexing into existing triangle/index arrays.
85 /// Additional meshes can be added using addIndexedMesh 85 /// Additional meshes can be added using addIndexedMesh
86 /// </summary> 86 /// </summary>
87 public class TriangleIndexVertexArray : XnaDevRu.BulletX.StridingMeshInterface 87 public class TriangleIndexVertexArray : XnaDevRu.BulletX.StridingMeshInterface
88 { 88 {
89 List<IndexedMesh> _indexedMeshes = new List<IndexedMesh>(); 89 List<IndexedMesh> _indexedMeshes = new List<IndexedMesh>();
90 90
91 public TriangleIndexVertexArray() { } 91 public TriangleIndexVertexArray() { }
92 92
93 public TriangleIndexVertexArray(int numTriangleIndices, int[] triangleIndexBase, int triangleIndexStride, int numVertices, Vector3[] vertexBase, int vertexStride) 93 public TriangleIndexVertexArray(int numTriangleIndices, int[] triangleIndexBase, int triangleIndexStride, int numVertices, Vector3[] vertexBase, int vertexStride)
94 { 94 {
95 IndexedMesh mesh = new IndexedMesh(); 95 IndexedMesh mesh = new IndexedMesh();
96 mesh.TriangleCount = numTriangleIndices; 96 mesh.TriangleCount = numTriangleIndices;
97 mesh.TriangleIndexBase = triangleIndexBase; 97 mesh.TriangleIndexBase = triangleIndexBase;
98 mesh.TriangleIndexStride = triangleIndexStride; 98 mesh.TriangleIndexStride = triangleIndexStride;
99 mesh.VertexBase = vertexBase; 99 mesh.VertexBase = vertexBase;
100 mesh.VertexCount = numVertices; 100 mesh.VertexCount = numVertices;
101 mesh.VertexStride = vertexStride; 101 mesh.VertexStride = vertexStride;
102 102
103 AddIndexedMesh(mesh); 103 AddIndexedMesh(mesh);
104 } 104 }
105 105
106 public TriangleIndexVertexArray(int[] triangleIndexBase, Vector3[] vertexBase) 106 public TriangleIndexVertexArray(int[] triangleIndexBase, Vector3[] vertexBase)
107 : this(triangleIndexBase.Length, triangleIndexBase, 32, vertexBase.Length, vertexBase, 24) { } 107 : this(triangleIndexBase.Length, triangleIndexBase, 32, vertexBase.Length, vertexBase, 24) { }
108 108
109 public void AddIndexedMesh(IndexedMesh indexedMesh) 109 public void AddIndexedMesh(IndexedMesh indexedMesh)
110 { 110 {
111 _indexedMeshes.Add(indexedMesh); 111 _indexedMeshes.Add(indexedMesh);
112 } 112 }
113 113
114 public override void GetLockedVertexIndexBase(out List<Vector3> verts, out List<int> indicies, out int numfaces, int subpart) 114 public override void GetLockedVertexIndexBase(out List<Vector3> verts, out List<int> indicies, out int numfaces, int subpart)
115 { 115 {
116 throw new Exception("The method or operation is not implemented."); 116 throw new Exception("The method or operation is not implemented.");
117 } 117 }
118 118
119 public override void GetLockedReadOnlyVertexIndexBase(out List<Vector3> verts, out List<int> indicies, out int numfaces, int subpart) 119 public override void GetLockedReadOnlyVertexIndexBase(out List<Vector3> verts, out List<int> indicies, out int numfaces, int subpart)
120 { 120 {
121 IndexedMesh m = _indexedMeshes[0]; 121 IndexedMesh m = _indexedMeshes[0];
122 Vector3[] vertexBase = m.VertexBase; 122 Vector3[] vertexBase = m.VertexBase;
123 verts = new List<Vector3>(); 123 verts = new List<Vector3>();
124 foreach (Vector3 v in vertexBase) 124 foreach (Vector3 v in vertexBase)
125 { 125 {
126 verts.Add(v); 126 verts.Add(v);
127 } 127 }
128 int[] indexBase = m.TriangleIndexBase; 128 int[] indexBase = m.TriangleIndexBase;
129 indicies = new List<int>(); 129 indicies = new List<int>();
130 foreach (int i in indexBase) 130 foreach (int i in indexBase)
131 { 131 {
132 indicies.Add(i); 132 indicies.Add(i);
133 } 133 }
134 numfaces = vertexBase.GetLength(0); 134 numfaces = vertexBase.GetLength(0);
135 } 135 }
136 136
137 public override void UnLockVertexBase(int subpart) 137 public override void UnLockVertexBase(int subpart)
138 { 138 {
139 throw new Exception("The method or operation is not implemented."); 139 throw new Exception("The method or operation is not implemented.");
140 } 140 }
141 141
142 public override void UnLockReadOnlyVertexBase(int subpart) 142 public override void UnLockReadOnlyVertexBase(int subpart)
143 { 143 {
144 } 144 }
145 145
146 public override int SubPartsCount() 146 public override int SubPartsCount()
147 { 147 {
148 return _indexedMeshes.Count; 148 return _indexedMeshes.Count;
149 } 149 }
150 150
151 public override void PreallocateVertices(int numverts) 151 public override void PreallocateVertices(int numverts)
152 { 152 {
153 throw new Exception("The method or operation is not implemented."); 153 throw new Exception("The method or operation is not implemented.");
154 } 154 }
155 155
156 public override void PreallocateIndices(int numindices) 156 public override void PreallocateIndices(int numindices)
157 { 157 {
158 throw new Exception("The method or operation is not implemented."); 158 throw new Exception("The method or operation is not implemented.");
159 } 159 }
160 } 160 }
161} 161}
diff --git a/OpenSim/Region/Physics/Manager/IMesher.cs b/OpenSim/Region/Physics/Manager/IMesher.cs
index 037616c..be3b272 100644
--- a/OpenSim/Region/Physics/Manager/IMesher.cs
+++ b/OpenSim/Region/Physics/Manager/IMesher.cs
@@ -1,26 +1,26 @@
1using System; 1using System;
2using System.Collections.Generic; 2using System.Collections.Generic;
3using System.Text; 3using System.Text;
4 4
5using OpenSim.Framework; 5using OpenSim.Framework;
6 6
7namespace OpenSim.Region.Physics.Manager 7namespace OpenSim.Region.Physics.Manager
8{ 8{
9 public interface IMesher 9 public interface IMesher
10 { 10 {
11 IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, PhysicsVector size); 11 IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, PhysicsVector size);
12 } 12 }
13 13
14 public interface IVertex { 14 public interface IVertex {
15 } 15 }
16 16
17 public interface IMesh 17 public interface IMesh
18 { 18 {
19 List<PhysicsVector> getVertexList(); 19 List<PhysicsVector> getVertexList();
20 int[] getIndexListAsInt(); 20 int[] getIndexListAsInt();
21 int[] getIndexListAsIntLocked(); 21 int[] getIndexListAsIntLocked();
22 float[] getVertexListAsFloatLocked(); 22 float[] getVertexListAsFloatLocked();
23 23
24 24
25 } 25 }
26} 26}
diff --git a/OpenSim/Region/Physics/Meshing/Extruder.cs b/OpenSim/Region/Physics/Meshing/Extruder.cs
index 63d727f..c8fd91b 100644
--- a/OpenSim/Region/Physics/Meshing/Extruder.cs
+++ b/OpenSim/Region/Physics/Meshing/Extruder.cs
@@ -1,83 +1,83 @@
1using System; 1using System;
2using System.Collections.Generic; 2using System.Collections.Generic;
3using System.Text; 3using System.Text;
4 4
5namespace OpenSim.Region.Physics.Meshing 5namespace OpenSim.Region.Physics.Meshing
6{ 6{
7 class Extruder 7 class Extruder
8 { 8 {
9 public float startParameter; 9 public float startParameter;
10 public float stopParameter; 10 public float stopParameter;
11 public Manager.PhysicsVector size; 11 public Manager.PhysicsVector size;
12 12
13 public Mesh Extrude(Mesh m) 13 public Mesh Extrude(Mesh m)
14 { 14 {
15 // Currently only works for iSteps=1; 15 // Currently only works for iSteps=1;
16 Mesh result = new Mesh(); 16 Mesh result = new Mesh();
17 17
18 Mesh workingPlus = m.Clone(); 18 Mesh workingPlus = m.Clone();
19 Mesh workingMinus = m.Clone(); 19 Mesh workingMinus = m.Clone();
20 20
21 foreach (Vertex v in workingPlus.vertices) 21 foreach (Vertex v in workingPlus.vertices)
22 { 22 {
23 if (v == null) 23 if (v == null)
24 continue; 24 continue;
25 25
26 v.Z = +.5f; 26 v.Z = +.5f;
27 v.X *= size.X; 27 v.X *= size.X;
28 v.Y *= size.Y; 28 v.Y *= size.Y;
29 v.Z *= size.Z; 29 v.Z *= size.Z;
30 } 30 }
31 31
32 foreach (Vertex v in workingMinus.vertices) 32 foreach (Vertex v in workingMinus.vertices)
33 { 33 {
34 if (v == null) 34 if (v == null)
35 continue; 35 continue;
36 36
37 v.Z = -.5f; 37 v.Z = -.5f;
38 v.X *= size.X; 38 v.X *= size.X;
39 v.Y *= size.Y; 39 v.Y *= size.Y;
40 v.Z *= size.Z; 40 v.Z *= size.Z;
41 } 41 }
42 42
43 foreach (Triangle t in workingMinus.triangles) 43 foreach (Triangle t in workingMinus.triangles)
44 { 44 {
45 t.invertNormal(); 45 t.invertNormal();
46 } 46 }
47 47
48 result.Append(workingMinus); 48 result.Append(workingMinus);
49 result.Append(workingPlus); 49 result.Append(workingPlus);
50 50
51 int iLastNull = 0; 51 int iLastNull = 0;
52 for (int i = 0; i < workingPlus.vertices.Count; i++) 52 for (int i = 0; i < workingPlus.vertices.Count; i++)
53 { 53 {
54 int iNext = (i + 1); 54 int iNext = (i + 1);
55 55
56 if (workingPlus.vertices[i] == null) // Can't make a simplex here 56 if (workingPlus.vertices[i] == null) // Can't make a simplex here
57 { 57 {
58 iLastNull = i+1; 58 iLastNull = i+1;
59 continue; 59 continue;
60 } 60 }
61 61
62 if (i == workingPlus.vertices.Count-1) // End of list 62 if (i == workingPlus.vertices.Count-1) // End of list
63 { 63 {
64 iNext = iLastNull; 64 iNext = iLastNull;
65 } 65 }
66 66
67 if (workingPlus.vertices[iNext] == null) // Null means wrap to begin of last segment 67 if (workingPlus.vertices[iNext] == null) // Null means wrap to begin of last segment
68 { 68 {
69 iNext = iLastNull; 69 iNext = iLastNull;
70 } 70 }
71 71
72 Triangle tSide; 72 Triangle tSide;
73 tSide = new Triangle(workingPlus.vertices[i], workingMinus.vertices[i], workingPlus.vertices[iNext]); 73 tSide = new Triangle(workingPlus.vertices[i], workingMinus.vertices[i], workingPlus.vertices[iNext]);
74 result.Add(tSide); 74 result.Add(tSide);
75 75
76 tSide = new Triangle(workingPlus.vertices[iNext], workingMinus.vertices[i], workingMinus.vertices[iNext]); 76 tSide = new Triangle(workingPlus.vertices[iNext], workingMinus.vertices[i], workingMinus.vertices[iNext]);
77 result.Add(tSide); 77 result.Add(tSide);
78 } 78 }
79 79
80 return result; 80 return result;
81 } 81 }
82 } 82 }
83} 83}
diff --git a/OpenSim/Region/Physics/Meshing/HelperTypes.cs b/OpenSim/Region/Physics/Meshing/HelperTypes.cs
index 9e75826..be82c32 100644
--- a/OpenSim/Region/Physics/Meshing/HelperTypes.cs
+++ b/OpenSim/Region/Physics/Meshing/HelperTypes.cs
@@ -1,306 +1,306 @@
1/* 1/*
2* Copyright (c) Contributors, http://opensimulator.org/ 2* Copyright (c) Contributors, http://opensimulator.org/
3* See CONTRIBUTORS.TXT for a full list of copyright holders. 3* See CONTRIBUTORS.TXT for a full list of copyright holders.
4* 4*
5* Redistribution and use in source and binary forms, with or without 5* Redistribution and use in source and binary forms, with or without
6* modification, are permitted provided that the following conditions are met: 6* modification, are permitted provided that the following conditions are met:
7* * Redistributions of source code must retain the above copyright 7* * Redistributions of source code must retain the above copyright
8* notice, this list of conditions and the following disclaimer. 8* notice, this list of conditions and the following disclaimer.
9* * Redistributions in binary form must reproduce the above copyright 9* * Redistributions in binary form must reproduce the above copyright
10* notice, this list of conditions and the following disclaimer in the 10* notice, this list of conditions and the following disclaimer in the
11* documentation and/or other materials provided with the distribution. 11* documentation and/or other materials provided with the distribution.
12* * Neither the name of the OpenSim Project nor the 12* * Neither the name of the OpenSim Project nor the
13* names of its contributors may be used to endorse or promote products 13* names of its contributors may be used to endorse or promote products
14* derived from this software without specific prior written permission. 14* derived from this software without specific prior written permission.
15* 15*
16* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS AS IS AND ANY 16* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS AS IS AND ANY
17* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY 19* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26* 26*
27*/ 27*/
28 28
29using System; 29using System;
30using System.Collections.Generic; 30using System.Collections.Generic;
31using System.Diagnostics; 31using System.Diagnostics;
32using System.Globalization; 32using System.Globalization;
33using OpenSim.Framework.Console; 33using OpenSim.Framework.Console;
34using OpenSim.Region.Physics.Manager; 34using OpenSim.Region.Physics.Manager;
35 35
36using OpenSim.Region.Physics.Meshing; 36using OpenSim.Region.Physics.Meshing;
37 37
38public class Vertex : PhysicsVector, IComparable<Vertex> 38public class Vertex : PhysicsVector, IComparable<Vertex>
39{ 39{
40 public Vertex(float x, float y, float z) 40 public Vertex(float x, float y, float z)
41 : base(x, y, z) 41 : base(x, y, z)
42 { 42 {
43 } 43 }
44 44
45 public Vertex(PhysicsVector v) 45 public Vertex(PhysicsVector v)
46 : base(v.X, v.Y, v.Z) 46 : base(v.X, v.Y, v.Z)
47 { 47 {
48 } 48 }
49 49
50 public Vertex Clone() 50 public Vertex Clone()
51 { 51 {
52 return new Vertex(X, Y, Z); 52 return new Vertex(X, Y, Z);
53 } 53 }
54 54
55 public static Vertex FromAngle(double angle) 55 public static Vertex FromAngle(double angle)
56 { 56 {
57 return new Vertex((float)Math.Cos(angle), (float)Math.Sin(angle), 0.0f); 57 return new Vertex((float)Math.Cos(angle), (float)Math.Sin(angle), 0.0f);
58 } 58 }
59 59
60 60
61 public virtual bool Equals(Vertex v, float tolerance) 61 public virtual bool Equals(Vertex v, float tolerance)
62 { 62 {
63 PhysicsVector diff = this - v; 63 PhysicsVector diff = this - v;
64 float d = diff.length(); 64 float d = diff.length();
65 if (d < tolerance) 65 if (d < tolerance)
66 return true; 66 return true;
67 67
68 return false; 68 return false;
69 } 69 }
70 70
71 71
72 public int CompareTo(Vertex other) 72 public int CompareTo(Vertex other)
73 { 73 {
74 if (X < other.X) 74 if (X < other.X)
75 return -1; 75 return -1;
76 76
77 if (X > other.X) 77 if (X > other.X)
78 return 1; 78 return 1;
79 79
80 if (Y < other.Y) 80 if (Y < other.Y)
81 return -1; 81 return -1;
82 82
83 if (Y > other.Y) 83 if (Y > other.Y)
84 return 1; 84 return 1;
85 85
86 if (Z < other.Z) 86 if (Z < other.Z)
87 return -1; 87 return -1;
88 88
89 if (Z > other.Z) 89 if (Z > other.Z)
90 return 1; 90 return 1;
91 91
92 return 0; 92 return 0;
93 } 93 }
94 94
95 public static bool operator >(Vertex me, Vertex other) 95 public static bool operator >(Vertex me, Vertex other)
96 { 96 {
97 return me.CompareTo(other) > 0; 97 return me.CompareTo(other) > 0;
98 } 98 }
99 99
100 public static bool operator <(Vertex me, Vertex other) 100 public static bool operator <(Vertex me, Vertex other)
101 { 101 {
102 return me.CompareTo(other) < 0; 102 return me.CompareTo(other) < 0;
103 } 103 }
104 public String ToRaw() 104 public String ToRaw()
105 { 105 {
106 // Why this stuff with the number formatter? 106 // Why this stuff with the number formatter?
107 // Well, the raw format uses the english/US notation of numbers 107 // Well, the raw format uses the english/US notation of numbers
108 // where the "," separates groups of 1000 while the "." marks the border between 1 and 10E-1. 108 // where the "," separates groups of 1000 while the "." marks the border between 1 and 10E-1.
109 // The german notation uses these characters exactly vice versa! 109 // The german notation uses these characters exactly vice versa!
110 // The Float.ToString() routine is a localized one, giving different results depending on the country 110 // The Float.ToString() routine is a localized one, giving different results depending on the country
111 // settings your machine works with. Unusable for a machine readable file format :-( 111 // settings your machine works with. Unusable for a machine readable file format :-(
112 NumberFormatInfo nfi = new NumberFormatInfo(); 112 NumberFormatInfo nfi = new NumberFormatInfo();
113 nfi.NumberDecimalSeparator = "."; 113 nfi.NumberDecimalSeparator = ".";
114 nfi.NumberDecimalDigits = 3; 114 nfi.NumberDecimalDigits = 3;
115 115
116 String s1 = X.ToString("N2", nfi) + " " + Y.ToString("N2", nfi) + " " + Z.ToString("N2", nfi); 116 String s1 = X.ToString("N2", nfi) + " " + Y.ToString("N2", nfi) + " " + Z.ToString("N2", nfi);
117 117
118 return s1; 118 return s1;
119 } 119 }
120 120
121} 121}
122 122
123public class Triangle 123public class Triangle
124{ 124{
125 public Vertex v1; 125 public Vertex v1;
126 public Vertex v2; 126 public Vertex v2;
127 public Vertex v3; 127 public Vertex v3;
128 128
129 private float radius_square; 129 private float radius_square;
130 private float cx; 130 private float cx;
131 private float cy; 131 private float cy;
132 132
133 public Triangle(Vertex _v1, Vertex _v2, Vertex _v3) 133 public Triangle(Vertex _v1, Vertex _v2, Vertex _v3)
134 { 134 {
135 v1 = _v1; 135 v1 = _v1;
136 v2 = _v2; 136 v2 = _v2;
137 v3 = _v3; 137 v3 = _v3;
138 138
139 CalcCircle(); 139 CalcCircle();
140 } 140 }
141 141
142 public bool isInCircle(float x, float y) 142 public bool isInCircle(float x, float y)
143 { 143 {
144 float dx, dy; 144 float dx, dy;
145 float dd; 145 float dd;
146 146
147 dx = x - cx; 147 dx = x - cx;
148 dy = y - cy; 148 dy = y - cy;
149 149
150 dd = dx*dx + dy*dy; 150 dd = dx*dx + dy*dy;
151 if (dd < radius_square) 151 if (dd < radius_square)
152 return true; 152 return true;
153 else 153 else
154 return false; 154 return false;
155 } 155 }
156 156
157 public bool isDegraded() 157 public bool isDegraded()
158 { 158 {
159 // This means, the vertices of this triangle are somewhat strange. 159 // This means, the vertices of this triangle are somewhat strange.
160 // They either line up or at least two of them are identical 160 // They either line up or at least two of them are identical
161 return (radius_square == 0.0); 161 return (radius_square == 0.0);
162 } 162 }
163 163
164 private void CalcCircle() 164 private void CalcCircle()
165 { 165 {
166 // Calculate the center and the radius of a circle given by three points p1, p2, p3 166 // Calculate the center and the radius of a circle given by three points p1, p2, p3
167 // It is assumed, that the triangles vertices are already set correctly 167 // It is assumed, that the triangles vertices are already set correctly
168 double p1x, p2x, p1y, p2y, p3x, p3y; 168 double p1x, p2x, p1y, p2y, p3x, p3y;
169 169
170 // Deviation of this routine: 170 // Deviation of this routine:
171 // A circle has the general equation (M-p)^2=r^2, where M and p are vectors 171 // A circle has the general equation (M-p)^2=r^2, where M and p are vectors
172 // this gives us three equations f(p)=r^2, each for one point p1, p2, p3 172 // this gives us three equations f(p)=r^2, each for one point p1, p2, p3
173 // putting respectively two equations together gives two equations 173 // putting respectively two equations together gives two equations
174 // f(p1)=f(p2) and f(p1)=f(p3) 174 // f(p1)=f(p2) and f(p1)=f(p3)
175 // bringing all constant terms to one side brings them to the form 175 // bringing all constant terms to one side brings them to the form
176 // M*v1=c1 resp.M*v2=c2 where v1=(p1-p2) and v2=(p1-p3) (still vectors) 176 // M*v1=c1 resp.M*v2=c2 where v1=(p1-p2) and v2=(p1-p3) (still vectors)
177 // and c1, c2 are scalars (Naming conventions like the variables below) 177 // and c1, c2 are scalars (Naming conventions like the variables below)
178 // Now using the equations that are formed by the components of the vectors 178 // Now using the equations that are formed by the components of the vectors
179 // and isolate Mx lets you make one equation that only holds My 179 // and isolate Mx lets you make one equation that only holds My
180 // The rest is straight forward and eaasy :-) 180 // The rest is straight forward and eaasy :-)
181 // 181 //
182 182
183 /* helping variables for temporary results */ 183 /* helping variables for temporary results */
184 double c1, c2; 184 double c1, c2;
185 double v1x, v1y, v2x, v2y; 185 double v1x, v1y, v2x, v2y;
186 186
187 double z, n; 187 double z, n;
188 188
189 double rx, ry; 189 double rx, ry;
190 190
191 // Readout the three points, the triangle consists of 191 // Readout the three points, the triangle consists of
192 p1x = v1.X; 192 p1x = v1.X;
193 p1y = v1.Y; 193 p1y = v1.Y;
194 194
195 p2x = v2.X; 195 p2x = v2.X;
196 p2y = v2.Y; 196 p2y = v2.Y;
197 197
198 p3x = v3.X; 198 p3x = v3.X;
199 p3y = v3.Y; 199 p3y = v3.Y;
200 200
201 /* calc helping values first */ 201 /* calc helping values first */
202 c1 = (p1x*p1x + p1y*p1y - p2x*p2x - p2y*p2y)/2; 202 c1 = (p1x*p1x + p1y*p1y - p2x*p2x - p2y*p2y)/2;
203 c2 = (p1x*p1x + p1y*p1y - p3x*p3x - p3y*p3y)/2; 203 c2 = (p1x*p1x + p1y*p1y - p3x*p3x - p3y*p3y)/2;
204 204
205 v1x = p1x - p2x; 205 v1x = p1x - p2x;
206 v1y = p1y - p2y; 206 v1y = p1y - p2y;
207 207
208 v2x = p1x - p3x; 208 v2x = p1x - p3x;
209 v2y = p1y - p3y; 209 v2y = p1y - p3y;
210 210
211 z = (c1*v2x - c2*v1x); 211 z = (c1*v2x - c2*v1x);
212 n = (v1y*v2x - v2y*v1x); 212 n = (v1y*v2x - v2y*v1x);
213 213
214 if (n == 0.0) // This is no triangle, i.e there are (at least) two points at the same location 214 if (n == 0.0) // This is no triangle, i.e there are (at least) two points at the same location
215 { 215 {
216 radius_square = 0.0f; 216 radius_square = 0.0f;
217 return; 217 return;
218 } 218 }
219 219
220 cy = (float) (z/n); 220 cy = (float) (z/n);
221 221
222 if (v2x != 0.0) 222 if (v2x != 0.0)
223 { 223 {
224 cx = (float) ((c2 - v2y*cy)/v2x); 224 cx = (float) ((c2 - v2y*cy)/v2x);
225 } 225 }
226 else if (v1x != 0.0) 226 else if (v1x != 0.0)
227 { 227 {
228 cx = (float) ((c1 - v1y*cy)/v1x); 228 cx = (float) ((c1 - v1y*cy)/v1x);
229 } 229 }
230 else 230 else
231 { 231 {
232 Debug.Assert(false, "Malformed triangle"); /* Both terms zero means nothing good */ 232 Debug.Assert(false, "Malformed triangle"); /* Both terms zero means nothing good */
233 } 233 }
234 234
235 rx = (p1x - cx); 235 rx = (p1x - cx);
236 ry = (p1y - cy); 236 ry = (p1y - cy);
237 237
238 radius_square = (float) (rx*rx + ry*ry); 238 radius_square = (float) (rx*rx + ry*ry);
239 } 239 }
240 240
241 public List<Simplex> GetSimplices() 241 public List<Simplex> GetSimplices()
242 { 242 {
243 List<Simplex> result = new List<Simplex>(); 243 List<Simplex> result = new List<Simplex>();
244 Simplex s1 = new Simplex(v1, v2); 244 Simplex s1 = new Simplex(v1, v2);
245 Simplex s2 = new Simplex(v2, v3); 245 Simplex s2 = new Simplex(v2, v3);
246 Simplex s3 = new Simplex(v3, v1); 246 Simplex s3 = new Simplex(v3, v1);
247 247
248 result.Add(s1); 248 result.Add(s1);
249 result.Add(s2); 249 result.Add(s2);
250 result.Add(s3); 250 result.Add(s3);
251 251
252 return result; 252 return result;
253 } 253 }
254 254
255 public override String ToString() 255 public override String ToString()
256 { 256 {
257 NumberFormatInfo nfi = new NumberFormatInfo(); 257 NumberFormatInfo nfi = new NumberFormatInfo();
258 nfi.CurrencyDecimalDigits = 2; 258 nfi.CurrencyDecimalDigits = 2;
259 nfi.CurrencyDecimalSeparator = "."; 259 nfi.CurrencyDecimalSeparator = ".";
260 260
261 String s1 = "<" + v1.X.ToString(nfi) + "," + v1.Y.ToString(nfi) + "," + v1.Z.ToString(nfi) + ">"; 261 String s1 = "<" + v1.X.ToString(nfi) + "," + v1.Y.ToString(nfi) + "," + v1.Z.ToString(nfi) + ">";
262 String s2 = "<" + v2.X.ToString(nfi) + "," + v2.Y.ToString(nfi) + "," + v2.Z.ToString(nfi) + ">"; 262 String s2 = "<" + v2.X.ToString(nfi) + "," + v2.Y.ToString(nfi) + "," + v2.Z.ToString(nfi) + ">";
263 String s3 = "<" + v3.X.ToString(nfi) + "," + v3.Y.ToString(nfi) + "," + v3.Z.ToString(nfi) + ">"; 263 String s3 = "<" + v3.X.ToString(nfi) + "," + v3.Y.ToString(nfi) + "," + v3.Z.ToString(nfi) + ">";
264 264
265 return s1 + ";" + s2 + ";" + s3; 265 return s1 + ";" + s2 + ";" + s3;
266 } 266 }
267 267
268 public PhysicsVector getNormal() 268 public PhysicsVector getNormal()
269 { 269 {
270 // Vertices 270 // Vertices
271 271
272 // Vectors for edges 272 // Vectors for edges
273 PhysicsVector e1; 273 PhysicsVector e1;
274 PhysicsVector e2; 274 PhysicsVector e2;
275 275
276 e1 = new PhysicsVector(v1.X - v2.X, v1.Y - v2.Y, v1.Z - v2.Z); 276 e1 = new PhysicsVector(v1.X - v2.X, v1.Y - v2.Y, v1.Z - v2.Z);
277 e2 = new PhysicsVector(v1.X - v3.X, v1.Y - v3.Y, v1.Z - v3.Z); 277 e2 = new PhysicsVector(v1.X - v3.X, v1.Y - v3.Y, v1.Z - v3.Z);
278 278
279 // Cross product for normal 279 // Cross product for normal
280 PhysicsVector n = PhysicsVector.cross(e1, e2); 280 PhysicsVector n = PhysicsVector.cross(e1, e2);
281 281
282 // Length 282 // Length
283 float l = n.length(); 283 float l = n.length();
284 284
285 // Normalized "normal" 285 // Normalized "normal"
286 n = n / l; 286 n = n / l;
287 287
288 return n; 288 return n;
289 } 289 }
290 290
291 public void invertNormal() 291 public void invertNormal()
292 { 292 {
293 Vertex vt; 293 Vertex vt;
294 vt = v1; 294 vt = v1;
295 v1 = v2; 295 v1 = v2;
296 v2 = vt; 296 v2 = vt;
297 } 297 }
298 298
299 // Dumps a triangle in the "raw faces" format, blender can import. This is for visualisation and 299 // Dumps a triangle in the "raw faces" format, blender can import. This is for visualisation and
300 // debugging purposes 300 // debugging purposes
301 public String ToStringRaw() 301 public String ToStringRaw()
302 { 302 {
303 String output = v1.ToRaw() + " " + v2.ToRaw() + " " +v3.ToRaw(); 303 String output = v1.ToRaw() + " " + v2.ToRaw() + " " +v3.ToRaw();
304 return output; 304 return output;
305 } 305 }
306} \ No newline at end of file 306} \ No newline at end of file
diff --git a/OpenSim/Region/Physics/Meshing/Mesh.cs b/OpenSim/Region/Physics/Meshing/Mesh.cs
index fd4ce4e..f569386 100644
--- a/OpenSim/Region/Physics/Meshing/Mesh.cs
+++ b/OpenSim/Region/Physics/Meshing/Mesh.cs
@@ -1,213 +1,213 @@
1using System; 1using System;
2using System.IO; 2using System.IO;
3using System.Collections.Generic; 3using System.Collections.Generic;
4using System.Text; 4using System.Text;
5 5
6using System.Runtime.InteropServices; 6using System.Runtime.InteropServices;
7 7
8 8
9using OpenSim.Region.Physics.Manager; 9using OpenSim.Region.Physics.Manager;
10 10
11namespace OpenSim.Region.Physics.Meshing 11namespace OpenSim.Region.Physics.Meshing
12{ 12{
13 public class Mesh : IMesh 13 public class Mesh : IMesh
14 { 14 {
15 public List<Vertex> vertices; 15 public List<Vertex> vertices;
16 public List<Triangle> triangles; 16 public List<Triangle> triangles;
17 17
18 public float[] normals; 18 public float[] normals;
19 19
20 public Mesh() 20 public Mesh()
21 { 21 {
22 vertices = new List<Vertex>(); 22 vertices = new List<Vertex>();
23 triangles = new List<Triangle>(); 23 triangles = new List<Triangle>();
24 } 24 }
25 25
26 public Mesh Clone() 26 public Mesh Clone()
27 { 27 {
28 Mesh result = new Mesh(); 28 Mesh result = new Mesh();
29 29
30 foreach (Vertex v in vertices) 30 foreach (Vertex v in vertices)
31 { 31 {
32 if (v == null) 32 if (v == null)
33 result.vertices.Add(null); 33 result.vertices.Add(null);
34 else 34 else
35 result.vertices.Add(v.Clone()); 35 result.vertices.Add(v.Clone());
36 } 36 }
37 37
38 foreach (Triangle t in triangles) 38 foreach (Triangle t in triangles)
39 { 39 {
40 int iV1, iV2, iV3; 40 int iV1, iV2, iV3;
41 iV1 = this.vertices.IndexOf(t.v1); 41 iV1 = this.vertices.IndexOf(t.v1);
42 iV2 = this.vertices.IndexOf(t.v2); 42 iV2 = this.vertices.IndexOf(t.v2);
43 iV3 = this.vertices.IndexOf(t.v3); 43 iV3 = this.vertices.IndexOf(t.v3);
44 44
45 Triangle newT = new Triangle(result.vertices[iV1], result.vertices[iV2], result.vertices[iV3]); 45 Triangle newT = new Triangle(result.vertices[iV1], result.vertices[iV2], result.vertices[iV3]);
46 result.Add(newT); 46 result.Add(newT);
47 } 47 }
48 48
49 return result; 49 return result;
50 } 50 }
51 51
52 52
53 53
54 public void Add(Triangle triangle) 54 public void Add(Triangle triangle)
55 { 55 {
56 int i; 56 int i;
57 i = vertices.IndexOf(triangle.v1); 57 i = vertices.IndexOf(triangle.v1);
58 if (i < 0) 58 if (i < 0)
59 throw new ArgumentException("Vertex v1 not known to mesh"); 59 throw new ArgumentException("Vertex v1 not known to mesh");
60 i = vertices.IndexOf(triangle.v2); 60 i = vertices.IndexOf(triangle.v2);
61 if (i < 0) 61 if (i < 0)
62 throw new ArgumentException("Vertex v2 not known to mesh"); 62 throw new ArgumentException("Vertex v2 not known to mesh");
63 i = vertices.IndexOf(triangle.v3); 63 i = vertices.IndexOf(triangle.v3);
64 if (i < 0) 64 if (i < 0)
65 throw new ArgumentException("Vertex v3 not known to mesh"); 65 throw new ArgumentException("Vertex v3 not known to mesh");
66 66
67 triangles.Add(triangle); 67 triangles.Add(triangle);
68 } 68 }
69 69
70 public void Add(Vertex v) 70 public void Add(Vertex v)
71 { 71 {
72 vertices.Add(v); 72 vertices.Add(v);
73 } 73 }
74 74
75 public void Remove(Vertex v) 75 public void Remove(Vertex v)
76 { 76 {
77 int i; 77 int i;
78 78
79 // First, remove all triangles that are build on v 79 // First, remove all triangles that are build on v
80 for (i = 0; i < triangles.Count; i++) 80 for (i = 0; i < triangles.Count; i++)
81 { 81 {
82 Triangle t = triangles[i]; 82 Triangle t = triangles[i];
83 if (t.v1 == v || t.v2 == v || t.v3 == v) 83 if (t.v1 == v || t.v2 == v || t.v3 == v)
84 { 84 {
85 triangles.RemoveAt(i); 85 triangles.RemoveAt(i);
86 i--; 86 i--;
87 } 87 }
88 } 88 }
89 89
90 // Second remove v itself 90 // Second remove v itself
91 vertices.Remove(v); 91 vertices.Remove(v);
92 } 92 }
93 93
94 public void RemoveTrianglesOutside(SimpleHull hull) 94 public void RemoveTrianglesOutside(SimpleHull hull)
95 { 95 {
96 int i; 96 int i;
97 97
98 for (i = 0; i < triangles.Count; i++) 98 for (i = 0; i < triangles.Count; i++)
99 { 99 {
100 Triangle t = triangles[i]; 100 Triangle t = triangles[i];
101 Vertex v1 = t.v1; 101 Vertex v1 = t.v1;
102 Vertex v2 = t.v2; 102 Vertex v2 = t.v2;
103 Vertex v3 = t.v3; 103 Vertex v3 = t.v3;
104 PhysicsVector m = v1 + v2 + v3; 104 PhysicsVector m = v1 + v2 + v3;
105 m /= 3.0f; 105 m /= 3.0f;
106 if (!hull.IsPointIn(new Vertex(m))) 106 if (!hull.IsPointIn(new Vertex(m)))
107 { 107 {
108 triangles.RemoveAt(i); 108 triangles.RemoveAt(i);
109 i--; 109 i--;
110 } 110 }
111 } 111 }
112 } 112 }
113 113
114 114
115 public void Add(List<Vertex> lv) 115 public void Add(List<Vertex> lv)
116 { 116 {
117 foreach (Vertex v in lv) 117 foreach (Vertex v in lv)
118 { 118 {
119 vertices.Add(v); 119 vertices.Add(v);
120 } 120 }
121 } 121 }
122 122
123 public List<PhysicsVector> getVertexList() 123 public List<PhysicsVector> getVertexList()
124 { 124 {
125 List<PhysicsVector> result = new List<PhysicsVector>(); 125 List<PhysicsVector> result = new List<PhysicsVector>();
126 foreach (Vertex v in vertices) 126 foreach (Vertex v in vertices)
127 { 127 {
128 result.Add(v); 128 result.Add(v);
129 } 129 }
130 return result; 130 return result;
131 } 131 }
132 132
133 public float[] getVertexListAsFloatLocked() 133 public float[] getVertexListAsFloatLocked()
134 { 134 {
135 float[] result = new float[vertices.Count * 3]; 135 float[] result = new float[vertices.Count * 3];
136 for (int i = 0; i < vertices.Count; i++) 136 for (int i = 0; i < vertices.Count; i++)
137 { 137 {
138 Vertex v = vertices[i]; 138 Vertex v = vertices[i];
139 if (v == null) 139 if (v == null)
140 continue; 140 continue;
141 result[3 * i + 0] = v.X; 141 result[3 * i + 0] = v.X;
142 result[3 * i + 1] = v.Y; 142 result[3 * i + 1] = v.Y;
143 result[3 * i + 2] = v.Z; 143 result[3 * i + 2] = v.Z;
144 } 144 }
145 GCHandle.Alloc(result, GCHandleType.Pinned); 145 GCHandle.Alloc(result, GCHandleType.Pinned);
146 return result; 146 return result;
147 } 147 }
148 148
149 public int[] getIndexListAsInt() 149 public int[] getIndexListAsInt()
150 { 150 {
151 int[] result = new int[triangles.Count * 3]; 151 int[] result = new int[triangles.Count * 3];
152 for (int i = 0; i < triangles.Count; i++) 152 for (int i = 0; i < triangles.Count; i++)
153 { 153 {
154 Triangle t = triangles[i]; 154 Triangle t = triangles[i];
155 result[3 * i + 0] = vertices.IndexOf(t.v1); 155 result[3 * i + 0] = vertices.IndexOf(t.v1);
156 result[3 * i + 1] = vertices.IndexOf(t.v2); 156 result[3 * i + 1] = vertices.IndexOf(t.v2);
157 result[3 * i + 2] = vertices.IndexOf(t.v3); 157 result[3 * i + 2] = vertices.IndexOf(t.v3);
158 } 158 }
159 return result; 159 return result;
160 } 160 }
161 161
162 public int[] getIndexListAsIntLocked() 162 public int[] getIndexListAsIntLocked()
163 { 163 {
164 int[] result = getIndexListAsInt(); 164 int[] result = getIndexListAsInt();
165 GCHandle.Alloc(result, GCHandleType.Pinned); 165 GCHandle.Alloc(result, GCHandleType.Pinned);
166 return result; 166 return result;
167 } 167 }
168 168
169 169
170 public void Append(Mesh newMesh) 170 public void Append(Mesh newMesh)
171 { 171 {
172 foreach (Vertex v in newMesh.vertices) 172 foreach (Vertex v in newMesh.vertices)
173 vertices.Add(v); 173 vertices.Add(v);
174 174
175 foreach (Triangle t in newMesh.triangles) 175 foreach (Triangle t in newMesh.triangles)
176 Add(t); 176 Add(t);
177 177
178 } 178 }
179 179
180 // Do a linear transformation of mesh. 180 // Do a linear transformation of mesh.
181 public void TransformLinear(float[,] matrix, float[] offset) 181 public void TransformLinear(float[,] matrix, float[] offset)
182 { 182 {
183 foreach (Vertex v in vertices) 183 foreach (Vertex v in vertices)
184 { 184 {
185 if (v == null) 185 if (v == null)
186 continue; 186 continue;
187 float x, y, z; 187 float x, y, z;
188 x = v.X * matrix[0, 0] + v.Y * matrix[1, 0] + v.Z * matrix[2, 0]; 188 x = v.X * matrix[0, 0] + v.Y * matrix[1, 0] + v.Z * matrix[2, 0];
189 y = v.X * matrix[0, 1] + v.Y * matrix[1, 1] + v.Z * matrix[2, 1]; 189 y = v.X * matrix[0, 1] + v.Y * matrix[1, 1] + v.Z * matrix[2, 1];
190 z = v.X * matrix[0, 2] + v.Y * matrix[1, 2] + v.Z * matrix[2, 2]; 190 z = v.X * matrix[0, 2] + v.Y * matrix[1, 2] + v.Z * matrix[2, 2];
191 v.X = x + offset[0]; 191 v.X = x + offset[0];
192 v.Y = y + offset[1]; 192 v.Y = y + offset[1];
193 v.Z = z + offset[2]; 193 v.Z = z + offset[2];
194 } 194 }
195 } 195 }
196 196
197 public void DumpRaw(String path, String name, String title) 197 public void DumpRaw(String path, String name, String title)
198 { 198 {
199 if (path == null) 199 if (path == null)
200 return; 200 return;
201 String fileName = name + "_" + title + ".raw"; 201 String fileName = name + "_" + title + ".raw";
202 String completePath = Path.Combine(path, fileName); 202 String completePath = Path.Combine(path, fileName);
203 StreamWriter sw = new StreamWriter(completePath); 203 StreamWriter sw = new StreamWriter(completePath);
204 foreach (Triangle t in triangles) 204 foreach (Triangle t in triangles)
205 { 205 {
206 String s = t.ToStringRaw(); 206 String s = t.ToStringRaw();
207 sw.WriteLine(s); 207 sw.WriteLine(s);
208 } 208 }
209 sw.Close(); 209 sw.Close();
210 } 210 }
211 } 211 }
212 212
213} 213}
diff --git a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs
index da4ee58..9c35f81 100644
--- a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs
+++ b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs
@@ -1,393 +1,393 @@
1/* 1/*
2* Copyright (c) Contributors, http://opensimulator.org/ 2* Copyright (c) Contributors, http://opensimulator.org/
3* See CONTRIBUTORS.TXT for a full list of copyright holders. 3* See CONTRIBUTORS.TXT for a full list of copyright holders.
4* 4*
5* Redistribution and use in source and binary forms, with or without 5* Redistribution and use in source and binary forms, with or without
6* modification, are permitted provided that the following conditions are met: 6* modification, are permitted provided that the following conditions are met:
7* * Redistributions of source code must retain the above copyright 7* * Redistributions of source code must retain the above copyright
8* notice, this list of conditions and the following disclaimer. 8* notice, this list of conditions and the following disclaimer.
9* * Redistributions in binary form must reproduce the above copyright 9* * Redistributions in binary form must reproduce the above copyright
10* notice, this list of conditions and the following disclaimer in the 10* notice, this list of conditions and the following disclaimer in the
11* documentation and/or other materials provided with the distribution. 11* documentation and/or other materials provided with the distribution.
12* * Neither the name of the OpenSim Project nor the 12* * Neither the name of the OpenSim Project nor the
13* names of its contributors may be used to endorse or promote products 13* names of its contributors may be used to endorse or promote products
14* derived from this software without specific prior written permission. 14* derived from this software without specific prior written permission.
15* 15*
16* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS AS IS AND ANY 16* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS AS IS AND ANY
17* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY 19* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26* 26*
27*/ 27*/
28 28
29using System; 29using System;
30using System.IO; 30using System.IO;
31using System.Globalization; 31using System.Globalization;
32using System.Diagnostics; 32using System.Diagnostics;
33using System.Collections.Generic; 33using System.Collections.Generic;
34using System.Runtime.InteropServices; 34using System.Runtime.InteropServices;
35using OpenSim.Framework; 35using OpenSim.Framework;
36using OpenSim.Framework.Console; 36using OpenSim.Framework.Console;
37using OpenSim.Region.Physics.Manager; 37using OpenSim.Region.Physics.Manager;
38 38
39namespace OpenSim.Region.Physics.Meshing 39namespace OpenSim.Region.Physics.Meshing
40{ 40{
41 41
42 public class MeshmerizerPlugin : IMeshingPlugin 42 public class MeshmerizerPlugin : IMeshingPlugin
43 { 43 {
44 public MeshmerizerPlugin() 44 public MeshmerizerPlugin()
45 { 45 {
46 } 46 }
47 47
48 public string GetName() 48 public string GetName()
49 { 49 {
50 return "Meshmerizer"; 50 return "Meshmerizer";
51 } 51 }
52 52
53 public IMesher GetMesher() 53 public IMesher GetMesher()
54 { 54 {
55 return new Meshmerizer(); 55 return new Meshmerizer();
56 } 56 }
57 } 57 }
58 58
59 public class Meshmerizer : IMesher 59 public class Meshmerizer : IMesher
60 { 60 {
61 // Setting baseDir to a path will enable the dumping of raw files 61 // Setting baseDir to a path will enable the dumping of raw files
62 // raw files can be imported by blender so a visual inspection of the results can be done 62 // raw files can be imported by blender so a visual inspection of the results can be done
63 // const string baseDir = "rawFiles"; 63 // const string baseDir = "rawFiles";
64 const string baseDir = null; 64 const string baseDir = null;
65 65
66 static void IntersectionParameterPD(PhysicsVector p1, PhysicsVector r1, PhysicsVector p2, PhysicsVector r2, ref float lambda, ref float mu) 66 static void IntersectionParameterPD(PhysicsVector p1, PhysicsVector r1, PhysicsVector p2, PhysicsVector r2, ref float lambda, ref float mu)
67 { 67 {
68 // p1, p2, points on the straight 68 // p1, p2, points on the straight
69 // r1, r2, directional vectors of the straight. Not necessarily of length 1! 69 // r1, r2, directional vectors of the straight. Not necessarily of length 1!
70 // note, that l, m can be scaled such, that the range 0..1 is mapped to the area between two points, 70 // note, that l, m can be scaled such, that the range 0..1 is mapped to the area between two points,
71 // thus allowing to decide whether an intersection is between two points 71 // thus allowing to decide whether an intersection is between two points
72 72
73 float r1x = r1.X; 73 float r1x = r1.X;
74 float r1y = r1.Y; 74 float r1y = r1.Y;
75 float r2x = r2.X; 75 float r2x = r2.X;
76 float r2y = r2.Y; 76 float r2y = r2.Y;
77 77
78 float denom = r1y*r2x - r1x*r2y; 78 float denom = r1y*r2x - r1x*r2y;
79 79
80 if (denom == 0.0) 80 if (denom == 0.0)
81 { 81 {
82 lambda = Single.NaN; 82 lambda = Single.NaN;
83 mu = Single.NaN; 83 mu = Single.NaN;
84 return; 84 return;
85 } 85 }
86 86
87 float p1x = p1.X; 87 float p1x = p1.X;
88 float p1y = p1.Y; 88 float p1y = p1.Y;
89 float p2x = p2.X; 89 float p2x = p2.X;
90 float p2y = p2.Y; 90 float p2y = p2.Y;
91 lambda = (-p2x * r2y + p1x * r2y + (p2y - p1y) * r2x) / denom; 91 lambda = (-p2x * r2y + p1x * r2y + (p2y - p1y) * r2x) / denom;
92 mu = (-p2x * r1y + p1x * r1y + (p2y - p1y) * r1x) / denom; 92 mu = (-p2x * r1y + p1x * r1y + (p2y - p1y) * r1x) / denom;
93 93
94 } 94 }
95 95
96 private static List<Triangle> FindInfluencedTriangles(List<Triangle> triangles, Vertex v) 96 private static List<Triangle> FindInfluencedTriangles(List<Triangle> triangles, Vertex v)
97 { 97 {
98 List<Triangle> influenced = new List<Triangle>(); 98 List<Triangle> influenced = new List<Triangle>();
99 foreach (Triangle t in triangles) 99 foreach (Triangle t in triangles)
100 { 100 {
101 if (t.isInCircle(v.X, v.Y)) 101 if (t.isInCircle(v.X, v.Y))
102 { 102 {
103 influenced.Add(t); 103 influenced.Add(t);
104 } 104 }
105 } 105 }
106 return influenced; 106 return influenced;
107 } 107 }
108 108
109 109
110 private static void InsertVertices(List<Vertex> vertices, int usedForSeed, List<Triangle> triangles) 110 private static void InsertVertices(List<Vertex> vertices, int usedForSeed, List<Triangle> triangles)
111 { 111 {
112 // This is a variant of the delaunay algorithm 112 // This is a variant of the delaunay algorithm
113 // each time a new vertex is inserted, all triangles that are influenced by it are deleted 113 // each time a new vertex is inserted, all triangles that are influenced by it are deleted
114 // and replaced by new ones including the new vertex 114 // and replaced by new ones including the new vertex
115 // It is not very time efficient but easy to implement. 115 // It is not very time efficient but easy to implement.
116 116
117 int iCurrentVertex; 117 int iCurrentVertex;
118 int iMaxVertex = vertices.Count; 118 int iMaxVertex = vertices.Count;
119 for (iCurrentVertex = usedForSeed; iCurrentVertex < iMaxVertex; iCurrentVertex++) 119 for (iCurrentVertex = usedForSeed; iCurrentVertex < iMaxVertex; iCurrentVertex++)
120 { 120 {
121 // Background: A triangle mesh fulfills the delaunay condition if (iff!) 121 // Background: A triangle mesh fulfills the delaunay condition if (iff!)
122 // each circumlocutory circle (i.e. the circle that touches all three corners) 122 // each circumlocutory circle (i.e. the circle that touches all three corners)
123 // of each triangle is empty of other vertices. 123 // of each triangle is empty of other vertices.
124 // Obviously a single (seeding) triangle fulfills this condition. 124 // Obviously a single (seeding) triangle fulfills this condition.
125 // If we now add one vertex, we need to reconstruct all triangles, that 125 // If we now add one vertex, we need to reconstruct all triangles, that
126 // do not fulfill this condition with respect to the new triangle 126 // do not fulfill this condition with respect to the new triangle
127 127
128 // Find the triangles that are influenced by the new vertex 128 // Find the triangles that are influenced by the new vertex
129 Vertex v=vertices[iCurrentVertex]; 129 Vertex v=vertices[iCurrentVertex];
130 if (v == null) 130 if (v == null)
131 continue; // Null is polygon stop marker. Ignore it 131 continue; // Null is polygon stop marker. Ignore it
132 List<Triangle> influencedTriangles=FindInfluencedTriangles(triangles, v); 132 List<Triangle> influencedTriangles=FindInfluencedTriangles(triangles, v);
133 133
134 List<Simplex> simplices = new List<Simplex>(); 134 List<Simplex> simplices = new List<Simplex>();
135 135
136 // Reconstruction phase. First step, dissolve each triangle into it's simplices, 136 // Reconstruction phase. First step, dissolve each triangle into it's simplices,
137 // i.e. it's "border lines" 137 // i.e. it's "border lines"
138 // Goal is to find "inner" borders and delete them, while the hull gets conserved. 138 // Goal is to find "inner" borders and delete them, while the hull gets conserved.
139 // Inner borders are special in the way that they always come twice, which is how we detect them 139 // Inner borders are special in the way that they always come twice, which is how we detect them
140 foreach (Triangle t in influencedTriangles) 140 foreach (Triangle t in influencedTriangles)
141 { 141 {
142 List<Simplex> newSimplices = t.GetSimplices(); 142 List<Simplex> newSimplices = t.GetSimplices();
143 simplices.AddRange(newSimplices); 143 simplices.AddRange(newSimplices);
144 triangles.Remove(t); 144 triangles.Remove(t);
145 } 145 }
146 // Now sort the simplices. That will make identical ones reside side by side in the list 146 // Now sort the simplices. That will make identical ones reside side by side in the list
147 simplices.Sort(); 147 simplices.Sort();
148 148
149 // Look for duplicate simplices here. 149 // Look for duplicate simplices here.
150 // Remember, they are directly side by side in the list right now, 150 // Remember, they are directly side by side in the list right now,
151 // So we only check directly neighbours 151 // So we only check directly neighbours
152 int iSimplex; 152 int iSimplex;
153 List<Simplex> innerSimplices = new List<Simplex>(); 153 List<Simplex> innerSimplices = new List<Simplex>();
154 for (iSimplex = 1; iSimplex < simplices.Count; iSimplex++) // Startindex=1, so we can refer backwards 154 for (iSimplex = 1; iSimplex < simplices.Count; iSimplex++) // Startindex=1, so we can refer backwards
155 { 155 {
156 if (simplices[iSimplex - 1].CompareTo(simplices[iSimplex]) == 0) 156 if (simplices[iSimplex - 1].CompareTo(simplices[iSimplex]) == 0)
157 { 157 {
158 innerSimplices.Add(simplices[iSimplex - 1]); 158 innerSimplices.Add(simplices[iSimplex - 1]);
159 innerSimplices.Add(simplices[iSimplex]); 159 innerSimplices.Add(simplices[iSimplex]);
160 } 160 }
161 } 161 }
162 162
163 foreach (Simplex s in innerSimplices) 163 foreach (Simplex s in innerSimplices)
164 { 164 {
165 simplices.Remove(s); 165 simplices.Remove(s);
166 } 166 }
167 167
168 // each simplex still in the list belongs to the hull of the region in question 168 // each simplex still in the list belongs to the hull of the region in question
169 // The new vertex (yes, we still deal with verices here :-) ) forms a triangle 169 // The new vertex (yes, we still deal with verices here :-) ) forms a triangle
170 // with each of these simplices. Build the new triangles and add them to the list 170 // with each of these simplices. Build the new triangles and add them to the list
171 foreach (Simplex s in simplices) 171 foreach (Simplex s in simplices)
172 { 172 {
173 Triangle t = new Triangle(s.v1, s.v2, vertices[iCurrentVertex]); 173 Triangle t = new Triangle(s.v1, s.v2, vertices[iCurrentVertex]);
174 if (!t.isDegraded()) 174 if (!t.isDegraded())
175 { 175 {
176 triangles.Add(t); 176 triangles.Add(t);
177 } 177 }
178 } 178 }
179 } 179 }
180 180
181 } 181 }
182 182
183 183
184 static Mesh CreateBoxMesh(String primName, PrimitiveBaseShape primShape, PhysicsVector size) 184 static Mesh CreateBoxMesh(String primName, PrimitiveBaseShape primShape, PhysicsVector size)
185 // Builds the z (+ and -) surfaces of a box shaped prim 185 // Builds the z (+ and -) surfaces of a box shaped prim
186 { 186 {
187 UInt16 hollowFactor = primShape.ProfileHollow; 187 UInt16 hollowFactor = primShape.ProfileHollow;
188 UInt16 profileBegin = primShape.ProfileBegin; 188 UInt16 profileBegin = primShape.ProfileBegin;
189 UInt16 profileEnd = primShape.ProfileEnd; 189 UInt16 profileEnd = primShape.ProfileEnd;
190 190
191 // Procedure: This is based on the fact that the upper (plus) and lower (minus) Z-surface 191 // Procedure: This is based on the fact that the upper (plus) and lower (minus) Z-surface
192 // of a block are basically the same 192 // of a block are basically the same
193 // They may be warped differently but the shape is identical 193 // They may be warped differently but the shape is identical
194 // So we only create one surface as a model and derive both plus and minus surface of the block from it 194 // So we only create one surface as a model and derive both plus and minus surface of the block from it
195 // This is done in a model space where the block spans from -.5 to +.5 in X and Y 195 // This is done in a model space where the block spans from -.5 to +.5 in X and Y
196 // The mapping to Scene space is done later during the "extrusion" phase 196 // The mapping to Scene space is done later during the "extrusion" phase
197 197
198 // Base 198 // Base
199 Vertex MM = new Vertex(-0.5f, -0.5f, 0.0f); 199 Vertex MM = new Vertex(-0.5f, -0.5f, 0.0f);
200 Vertex PM = new Vertex(+0.5f, -0.5f, 0.0f); 200 Vertex PM = new Vertex(+0.5f, -0.5f, 0.0f);
201 Vertex MP = new Vertex(-0.5f, +0.5f, 0.0f); 201 Vertex MP = new Vertex(-0.5f, +0.5f, 0.0f);
202 Vertex PP = new Vertex(+0.5f, +0.5f, 0.0f); 202 Vertex PP = new Vertex(+0.5f, +0.5f, 0.0f);
203 203
204 Meshing.SimpleHull outerHull = new SimpleHull(); 204 Meshing.SimpleHull outerHull = new SimpleHull();
205 outerHull.AddVertex(MM); 205 outerHull.AddVertex(MM);
206 outerHull.AddVertex(PM); 206 outerHull.AddVertex(PM);
207 outerHull.AddVertex(PP); 207 outerHull.AddVertex(PP);
208 outerHull.AddVertex(MP); 208 outerHull.AddVertex(MP);
209 209
210 // Deal with cuts now 210 // Deal with cuts now
211 if ((profileBegin != 0) || (profileEnd != 0)) 211 if ((profileBegin != 0) || (profileEnd != 0))
212 { 212 {
213 double fProfileBeginAngle = profileBegin / 50000.0 * 360.0; // In degree, for easier debugging and understanding 213 double fProfileBeginAngle = profileBegin / 50000.0 * 360.0; // In degree, for easier debugging and understanding
214 fProfileBeginAngle -= (90.0 + 45.0); // for some reasons, the SL client counts from the corner -X/-Y 214 fProfileBeginAngle -= (90.0 + 45.0); // for some reasons, the SL client counts from the corner -X/-Y
215 double fProfileEndAngle = 360.0 - profileEnd / 50000.0 * 360.0; // Pathend comes as complement to 1.0 215 double fProfileEndAngle = 360.0 - profileEnd / 50000.0 * 360.0; // Pathend comes as complement to 1.0
216 fProfileEndAngle -= (90.0 + 45.0); 216 fProfileEndAngle -= (90.0 + 45.0);
217 if (fProfileBeginAngle < fProfileEndAngle) 217 if (fProfileBeginAngle < fProfileEndAngle)
218 fProfileEndAngle -= 360.0; 218 fProfileEndAngle -= 360.0;
219 219
220 // Note, that we don't want to cut out a triangle, even if this is a 220 // Note, that we don't want to cut out a triangle, even if this is a
221 // good approximation for small cuts. Indeed we want to cut out an arc 221 // good approximation for small cuts. Indeed we want to cut out an arc
222 // and we approximate this arc by a polygon chain 222 // and we approximate this arc by a polygon chain
223 // Also note, that these vectors are of length 1.0 and thus their endpoints lay outside the model space 223 // Also note, that these vectors are of length 1.0 and thus their endpoints lay outside the model space
224 // So it can easily be subtracted from the outer hull 224 // So it can easily be subtracted from the outer hull
225 int iSteps = (int)(((fProfileBeginAngle - fProfileEndAngle) / 45.0) + .5); // how many steps do we need with approximately 45 degree 225 int iSteps = (int)(((fProfileBeginAngle - fProfileEndAngle) / 45.0) + .5); // how many steps do we need with approximately 45 degree
226 double dStepWidth=(fProfileBeginAngle-fProfileEndAngle)/iSteps; 226 double dStepWidth=(fProfileBeginAngle-fProfileEndAngle)/iSteps;
227 227
228 Vertex origin = new Vertex(0.0f, 0.0f, 0.0f); 228 Vertex origin = new Vertex(0.0f, 0.0f, 0.0f);
229 229
230 // Note the sequence of vertices here. It's important to have the other rotational sense than in outerHull 230 // Note the sequence of vertices here. It's important to have the other rotational sense than in outerHull
231 SimpleHull cutHull = new SimpleHull(); 231 SimpleHull cutHull = new SimpleHull();
232 cutHull.AddVertex(origin); 232 cutHull.AddVertex(origin);
233 for (int i=0; i<iSteps; i++) { 233 for (int i=0; i<iSteps; i++) {
234 double angle=fProfileBeginAngle-i*dStepWidth; // we count against the angle orientation!!!! 234 double angle=fProfileBeginAngle-i*dStepWidth; // we count against the angle orientation!!!!
235 Vertex v = Vertex.FromAngle(angle * Math.PI / 180.0); 235 Vertex v = Vertex.FromAngle(angle * Math.PI / 180.0);
236 cutHull.AddVertex(v); 236 cutHull.AddVertex(v);
237 } 237 }
238 Vertex legEnd = Vertex.FromAngle(fProfileEndAngle * Math.PI / 180.0); // Calculated separately to avoid errors 238 Vertex legEnd = Vertex.FromAngle(fProfileEndAngle * Math.PI / 180.0); // Calculated separately to avoid errors
239 cutHull.AddVertex(legEnd); 239 cutHull.AddVertex(legEnd);
240 240
241 MainLog.Instance.Debug("Starting cutting of the hollow shape from the prim {1}", 0, primName); 241 MainLog.Instance.Debug("Starting cutting of the hollow shape from the prim {1}", 0, primName);
242 SimpleHull cuttedHull = SimpleHull.SubtractHull(outerHull, cutHull); 242 SimpleHull cuttedHull = SimpleHull.SubtractHull(outerHull, cutHull);
243 243
244 outerHull = cuttedHull; 244 outerHull = cuttedHull;
245 } 245 }
246 246
247 // Deal with the hole here 247 // Deal with the hole here
248 if (hollowFactor > 0) 248 if (hollowFactor > 0)
249 { 249 {
250 float hollowFactorF = (float) hollowFactor/(float) 50000; 250 float hollowFactorF = (float) hollowFactor/(float) 50000;
251 Vertex IMM = new Vertex(-0.5f * hollowFactorF, -0.5f * hollowFactorF, 0.0f); 251 Vertex IMM = new Vertex(-0.5f * hollowFactorF, -0.5f * hollowFactorF, 0.0f);
252 Vertex IPM = new Vertex(+0.5f * hollowFactorF, -0.5f * hollowFactorF, 0.0f); 252 Vertex IPM = new Vertex(+0.5f * hollowFactorF, -0.5f * hollowFactorF, 0.0f);
253 Vertex IMP = new Vertex(-0.5f * hollowFactorF, +0.5f * hollowFactorF, 0.0f); 253 Vertex IMP = new Vertex(-0.5f * hollowFactorF, +0.5f * hollowFactorF, 0.0f);
254 Vertex IPP = new Vertex(+0.5f * hollowFactorF, +0.5f * hollowFactorF, 0.0f); 254 Vertex IPP = new Vertex(+0.5f * hollowFactorF, +0.5f * hollowFactorF, 0.0f);
255 255
256 SimpleHull holeHull = new SimpleHull(); 256 SimpleHull holeHull = new SimpleHull();
257 257
258 holeHull.AddVertex(IMM); 258 holeHull.AddVertex(IMM);
259 holeHull.AddVertex(IMP); 259 holeHull.AddVertex(IMP);
260 holeHull.AddVertex(IPP); 260 holeHull.AddVertex(IPP);
261 holeHull.AddVertex(IPM); 261 holeHull.AddVertex(IPM);
262 262
263 SimpleHull hollowedHull = SimpleHull.SubtractHull(outerHull, holeHull); 263 SimpleHull hollowedHull = SimpleHull.SubtractHull(outerHull, holeHull);
264 264
265 outerHull = hollowedHull; 265 outerHull = hollowedHull;
266 266
267 } 267 }
268 268
269 Mesh m = new Mesh(); 269 Mesh m = new Mesh();
270 270
271 Vertex Seed1 = new Vertex(0.0f, -10.0f, 0.0f); 271 Vertex Seed1 = new Vertex(0.0f, -10.0f, 0.0f);
272 Vertex Seed2 = new Vertex(-10.0f, 10.0f, 0.0f); 272 Vertex Seed2 = new Vertex(-10.0f, 10.0f, 0.0f);
273 Vertex Seed3 = new Vertex(10.0f, 10.0f, 0.0f); 273 Vertex Seed3 = new Vertex(10.0f, 10.0f, 0.0f);
274 274
275 m.Add(Seed1); 275 m.Add(Seed1);
276 m.Add(Seed2); 276 m.Add(Seed2);
277 m.Add(Seed3); 277 m.Add(Seed3);
278 278
279 m.Add(new Triangle(Seed1, Seed2, Seed3)); 279 m.Add(new Triangle(Seed1, Seed2, Seed3));
280 m.Add(outerHull.getVertices()); 280 m.Add(outerHull.getVertices());
281 281
282 InsertVertices(m.vertices, 3, m.triangles); 282 InsertVertices(m.vertices, 3, m.triangles);
283 m.DumpRaw(baseDir, primName, "Proto first Mesh"); 283 m.DumpRaw(baseDir, primName, "Proto first Mesh");
284 284
285 m.Remove(Seed1); 285 m.Remove(Seed1);
286 m.Remove(Seed2); 286 m.Remove(Seed2);
287 m.Remove(Seed3); 287 m.Remove(Seed3);
288 m.DumpRaw(baseDir, primName, "Proto seeds removed"); 288 m.DumpRaw(baseDir, primName, "Proto seeds removed");
289 289
290 m.RemoveTrianglesOutside(outerHull); 290 m.RemoveTrianglesOutside(outerHull);
291 m.DumpRaw(baseDir, primName, "Proto outsides removed"); 291 m.DumpRaw(baseDir, primName, "Proto outsides removed");
292 292
293 foreach (Triangle t in m.triangles) 293 foreach (Triangle t in m.triangles)
294 { 294 {
295 PhysicsVector n = t.getNormal(); 295 PhysicsVector n = t.getNormal();
296 if (n.Z < 0.0) 296 if (n.Z < 0.0)
297 t.invertNormal(); 297 t.invertNormal();
298 } 298 }
299 299
300 Extruder extr = new Extruder(); 300 Extruder extr = new Extruder();
301 301
302 extr.size = size; 302 extr.size = size;
303 303
304 Mesh result = extr.Extrude(m); 304 Mesh result = extr.Extrude(m);
305 result.DumpRaw(baseDir, primName, "Z extruded"); 305 result.DumpRaw(baseDir, primName, "Z extruded");
306 return result; 306 return result;
307 } 307 }
308 308
309 public static void CalcNormals(Mesh mesh) 309 public static void CalcNormals(Mesh mesh)
310 { 310 {
311 int iTriangles = mesh.triangles.Count; 311 int iTriangles = mesh.triangles.Count;
312 312
313 mesh.normals = new float[iTriangles*3]; 313 mesh.normals = new float[iTriangles*3];
314 314
315 int i = 0; 315 int i = 0;
316 foreach (Triangle t in mesh.triangles) 316 foreach (Triangle t in mesh.triangles)
317 { 317 {
318 float ux, uy, uz; 318 float ux, uy, uz;
319 float vx, vy, vz; 319 float vx, vy, vz;
320 float wx, wy, wz; 320 float wx, wy, wz;
321 321
322 ux = t.v1.X; 322 ux = t.v1.X;
323 uy = t.v1.Y; 323 uy = t.v1.Y;
324 uz = t.v1.Z; 324 uz = t.v1.Z;
325 325
326 vx = t.v2.X; 326 vx = t.v2.X;
327 vy = t.v2.Y; 327 vy = t.v2.Y;
328 vz = t.v2.Z; 328 vz = t.v2.Z;
329 329
330 wx = t.v3.X; 330 wx = t.v3.X;
331 wy = t.v3.Y; 331 wy = t.v3.Y;
332 wz = t.v3.Z; 332 wz = t.v3.Z;
333 333
334 334
335 // Vectors for edges 335 // Vectors for edges
336 float e1x, e1y, e1z; 336 float e1x, e1y, e1z;
337 float e2x, e2y, e2z; 337 float e2x, e2y, e2z;
338 338
339 e1x = ux - vx; 339 e1x = ux - vx;
340 e1y = uy - vy; 340 e1y = uy - vy;
341 e1z = uz - vz; 341 e1z = uz - vz;
342 342
343 e2x = ux - wx; 343 e2x = ux - wx;
344 e2y = uy - wy; 344 e2y = uy - wy;
345 e2z = uz - wz; 345 e2z = uz - wz;
346 346
347 347
348 // Cross product for normal 348 // Cross product for normal
349 float nx, ny, nz; 349 float nx, ny, nz;
350 nx = e1y*e2z - e1z*e2y; 350 nx = e1y*e2z - e1z*e2y;
351 ny = e1z*e2x - e1x*e2z; 351 ny = e1z*e2x - e1x*e2z;
352 nz = e1x*e2y - e1y*e2x; 352 nz = e1x*e2y - e1y*e2x;
353 353
354 // Length 354 // Length
355 float l = (float) Math.Sqrt(nx*nx + ny*ny + nz*nz); 355 float l = (float) Math.Sqrt(nx*nx + ny*ny + nz*nz);
356 356
357 // Normalized "normal" 357 // Normalized "normal"
358 nx /= l; 358 nx /= l;
359 ny /= l; 359 ny /= l;
360 nz /= l; 360 nz /= l;
361 361
362 mesh.normals[i] = nx; 362 mesh.normals[i] = nx;
363 mesh.normals[i + 1] = ny; 363 mesh.normals[i + 1] = ny;
364 mesh.normals[i + 2] = nz; 364 mesh.normals[i + 2] = nz;
365 365
366 i += 3; 366 i += 3;
367 } 367 }
368 } 368 }
369 369
370 public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, PhysicsVector size) 370 public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, PhysicsVector size)
371 { 371 {
372 Mesh mesh = null; 372 Mesh mesh = null;
373 373
374 switch (primShape.ProfileShape) 374 switch (primShape.ProfileShape)
375 { 375 {
376 case ProfileShape.Square: 376 case ProfileShape.Square:
377 mesh=CreateBoxMesh(primName, primShape, size); 377 mesh=CreateBoxMesh(primName, primShape, size);
378 CalcNormals(mesh); 378 CalcNormals(mesh);
379 break; 379 break;
380 default: 380 default:
381 mesh = CreateBoxMesh(primName, primShape, size); 381 mesh = CreateBoxMesh(primName, primShape, size);
382 CalcNormals(mesh); 382 CalcNormals(mesh);
383 //Set default mesh to cube otherwise it'll return 383 //Set default mesh to cube otherwise it'll return
384 // null and crash on the 'setMesh' method in the physics plugins. 384 // null and crash on the 'setMesh' method in the physics plugins.
385 //mesh = null; 385 //mesh = null;
386 break; 386 break;
387 } 387 }
388 388
389 return mesh; 389 return mesh;
390 } 390 }
391 } 391 }
392 392
393} 393}
diff --git a/OpenSim/Region/Physics/Meshing/SimpleHull.cs b/OpenSim/Region/Physics/Meshing/SimpleHull.cs
index c199949..6de7e91 100644
--- a/OpenSim/Region/Physics/Meshing/SimpleHull.cs
+++ b/OpenSim/Region/Physics/Meshing/SimpleHull.cs
@@ -1,363 +1,363 @@
1using System; 1using System;
2using System.Collections.Generic; 2using System.Collections.Generic;
3using System.Text; 3using System.Text;
4 4
5using OpenSim.Framework.Console; 5using OpenSim.Framework.Console;
6 6
7namespace OpenSim.Region.Physics.Meshing 7namespace OpenSim.Region.Physics.Meshing
8{ 8{
9 // A simple hull is a set of vertices building up to simplices that border a region 9 // A simple hull is a set of vertices building up to simplices that border a region
10 // The word simple referes to the fact, that this class assumes, that all simplices 10 // The word simple referes to the fact, that this class assumes, that all simplices
11 // do not intersect 11 // do not intersect
12 // Simple hulls can be added and subtracted. 12 // Simple hulls can be added and subtracted.
13 // Vertices can be checked to lie inside a hull 13 // Vertices can be checked to lie inside a hull
14 // Also note, that the sequence of the vertices is important and defines if the region that 14 // Also note, that the sequence of the vertices is important and defines if the region that
15 // is defined by the hull lies inside or outside the simplex chain 15 // is defined by the hull lies inside or outside the simplex chain
16 public class SimpleHull 16 public class SimpleHull
17 { 17 {
18 List<Vertex> vertices = new List<Vertex>(); 18 List<Vertex> vertices = new List<Vertex>();
19 List<Vertex> holeVertices = new List<Vertex>(); // Only used, when the hull is hollow 19 List<Vertex> holeVertices = new List<Vertex>(); // Only used, when the hull is hollow
20 20
21 // Adds a vertex to the end of the list 21 // Adds a vertex to the end of the list
22 public void AddVertex(Vertex v) { 22 public void AddVertex(Vertex v) {
23 vertices.Add(v); 23 vertices.Add(v);
24 } 24 }
25 25
26 override public String ToString() 26 override public String ToString()
27 { 27 {
28 String result=""; 28 String result="";
29 foreach (Vertex v in vertices) 29 foreach (Vertex v in vertices)
30 { 30 {
31 result += "b:" + v.ToString() + "\n"; 31 result += "b:" + v.ToString() + "\n";
32 } 32 }
33 33
34 return result; 34 return result;
35 } 35 }
36 36
37 37
38 public List<Vertex> getVertices() { 38 public List<Vertex> getVertices() {
39 List<Vertex> newVertices = new List<Vertex>(); 39 List<Vertex> newVertices = new List<Vertex>();
40 40
41 newVertices.AddRange(vertices); 41 newVertices.AddRange(vertices);
42 newVertices.Add(null); 42 newVertices.Add(null);
43 newVertices.AddRange(holeVertices); 43 newVertices.AddRange(holeVertices);
44 44
45 return newVertices; 45 return newVertices;
46 } 46 }
47 47
48 public SimpleHull Clone() 48 public SimpleHull Clone()
49 { 49 {
50 SimpleHull result = new SimpleHull(); 50 SimpleHull result = new SimpleHull();
51 foreach (Vertex v in vertices) 51 foreach (Vertex v in vertices)
52 { 52 {
53 result.AddVertex(v.Clone()); 53 result.AddVertex(v.Clone());
54 } 54 }
55 55
56 foreach (Vertex v in this.holeVertices) 56 foreach (Vertex v in this.holeVertices)
57 { 57 {
58 result.holeVertices.Add(v.Clone()); 58 result.holeVertices.Add(v.Clone());
59 } 59 }
60 60
61 return result; 61 return result;
62 } 62 }
63 63
64 public bool IsPointIn(Vertex v1) 64 public bool IsPointIn(Vertex v1)
65 { 65 {
66 int iCounter=0; 66 int iCounter=0;
67 List<Simplex> simplices=buildSimplexList(); 67 List<Simplex> simplices=buildSimplexList();
68 foreach (Simplex s in simplices) 68 foreach (Simplex s in simplices)
69 { 69 {
70 // Send a ray along the positive X-Direction 70 // Send a ray along the positive X-Direction
71 // Note, that this direction must correlate with the "below" interpretation 71 // Note, that this direction must correlate with the "below" interpretation
72 // of handling for the special cases below 72 // of handling for the special cases below
73 Manager.PhysicsVector intersection = s.RayIntersect(v1, new Manager.PhysicsVector(1.0f, 0.0f, 0.0f), true); 73 Manager.PhysicsVector intersection = s.RayIntersect(v1, new Manager.PhysicsVector(1.0f, 0.0f, 0.0f), true);
74 74
75 if (intersection == null) 75 if (intersection == null)
76 continue; // No intersection. Done. More tests to follow otherwise 76 continue; // No intersection. Done. More tests to follow otherwise
77 77
78 // Did we hit the end of a simplex? 78 // Did we hit the end of a simplex?
79 // Then this can be one of two special cases: 79 // Then this can be one of two special cases:
80 // 1. we go through a border exactly at a joint 80 // 1. we go through a border exactly at a joint
81 // 2. we have just marginally touched a corner 81 // 2. we have just marginally touched a corner
82 // 3. we can slide along a border 82 // 3. we can slide along a border
83 // Solution: If the other vertex is "below" the ray, we don't count it 83 // Solution: If the other vertex is "below" the ray, we don't count it
84 // Thus corners pointing down are counted twice, corners pointing up are not counted 84 // Thus corners pointing down are counted twice, corners pointing up are not counted
85 // borders are counted once 85 // borders are counted once
86 if (intersection.IsIdentical(s.v1, 0.001f)) { 86 if (intersection.IsIdentical(s.v1, 0.001f)) {
87 if (s.v2.Y < v1.Y) 87 if (s.v2.Y < v1.Y)
88 continue; 88 continue;
89 } 89 }
90 // Do this for the other vertex two 90 // Do this for the other vertex two
91 if (intersection.IsIdentical(s.v2, 0.001f)) { 91 if (intersection.IsIdentical(s.v2, 0.001f)) {
92 if (s.v1.Y<v1.Y) 92 if (s.v1.Y<v1.Y)
93 continue; 93 continue;
94 } 94 }
95 iCounter++; 95 iCounter++;
96 } 96 }
97 97
98 return iCounter % 2 == 1; // Point is inside if the number of intersections is odd 98 return iCounter % 2 == 1; // Point is inside if the number of intersections is odd
99 } 99 }
100 100
101 public bool containsPointsFrom(SimpleHull otherHull) 101 public bool containsPointsFrom(SimpleHull otherHull)
102 { 102 {
103 foreach (Vertex v in otherHull.vertices) 103 foreach (Vertex v in otherHull.vertices)
104 { 104 {
105 if (IsPointIn(v)) 105 if (IsPointIn(v))
106 return true; 106 return true;
107 } 107 }
108 108
109 return false; 109 return false;
110 } 110 }
111 111
112 112
113 List<Simplex> buildSimplexList() { 113 List<Simplex> buildSimplexList() {
114 114
115 List<Simplex> result = new List<Simplex>(); 115 List<Simplex> result = new List<Simplex>();
116 116
117 // Not asserted but assumed: at least three vertices 117 // Not asserted but assumed: at least three vertices
118 for (int i=0; i<vertices.Count-1; i++) { 118 for (int i=0; i<vertices.Count-1; i++) {
119 Simplex s=new Simplex(vertices[i], vertices[i+1]); 119 Simplex s=new Simplex(vertices[i], vertices[i+1]);
120 result.Add(s); 120 result.Add(s);
121 } 121 }
122 Simplex s1=new Simplex(vertices[vertices.Count-1], vertices[0]); 122 Simplex s1=new Simplex(vertices[vertices.Count-1], vertices[0]);
123 result.Add(s1); 123 result.Add(s1);
124 124
125 if (holeVertices.Count==0) 125 if (holeVertices.Count==0)
126 return result; 126 return result;
127 127
128 // Same here. At least three vertices in hole assumed 128 // Same here. At least three vertices in hole assumed
129 for (int i = 0; i < holeVertices.Count - 1; i++) 129 for (int i = 0; i < holeVertices.Count - 1; i++)
130 { 130 {
131 Simplex s = new Simplex(holeVertices[i], holeVertices[i + 1]); 131 Simplex s = new Simplex(holeVertices[i], holeVertices[i + 1]);
132 result.Add(s); 132 result.Add(s);
133 } 133 }
134 134
135 s1 = new Simplex(holeVertices[holeVertices.Count - 1], holeVertices[0]); 135 s1 = new Simplex(holeVertices[holeVertices.Count - 1], holeVertices[0]);
136 result.Add(s1); 136 result.Add(s1);
137 return result; 137 return result;
138 } 138 }
139 139
140 bool InsertVertex(Vertex v, int iAfter) 140 bool InsertVertex(Vertex v, int iAfter)
141 { 141 {
142 vertices.Insert(iAfter + 1, v); 142 vertices.Insert(iAfter + 1, v);
143 return true; 143 return true;
144 } 144 }
145 145
146 Vertex getNextVertex(Vertex currentVertex) 146 Vertex getNextVertex(Vertex currentVertex)
147 { 147 {
148 int iCurrentIndex; 148 int iCurrentIndex;
149 iCurrentIndex = vertices.IndexOf(currentVertex); 149 iCurrentIndex = vertices.IndexOf(currentVertex);
150 150
151 // Error handling for iCurrentIndex==-1 should go here (and probably never will) 151 // Error handling for iCurrentIndex==-1 should go here (and probably never will)
152 152
153 iCurrentIndex++; 153 iCurrentIndex++;
154 if (iCurrentIndex == vertices.Count) 154 if (iCurrentIndex == vertices.Count)
155 iCurrentIndex = 0; 155 iCurrentIndex = 0;
156 156
157 return vertices[iCurrentIndex]; 157 return vertices[iCurrentIndex];
158 } 158 }
159 159
160 public Vertex FindVertex(Vertex vBase, float tolerance) { 160 public Vertex FindVertex(Vertex vBase, float tolerance) {
161 foreach (Vertex v in vertices) { 161 foreach (Vertex v in vertices) {
162 if (v.IsIdentical(vBase, tolerance)) 162 if (v.IsIdentical(vBase, tolerance))
163 return v; 163 return v;
164 } 164 }
165 165
166 return null; 166 return null;
167 } 167 }
168 168
169 public void FindIntersection(Simplex s, ref Vertex Intersection, ref Vertex nextVertex) 169 public void FindIntersection(Simplex s, ref Vertex Intersection, ref Vertex nextVertex)
170 { 170 {
171 Vertex bestIntersection=null; 171 Vertex bestIntersection=null;
172 float distToV1=Single.PositiveInfinity; 172 float distToV1=Single.PositiveInfinity;
173 Simplex bestIntersectingSimplex=null; 173 Simplex bestIntersectingSimplex=null;
174 174
175 List<Simplex> simple = buildSimplexList(); 175 List<Simplex> simple = buildSimplexList();
176 foreach (Simplex sTest in simple) 176 foreach (Simplex sTest in simple)
177 { 177 {
178 Manager.PhysicsVector vvTemp = Simplex.Intersect(sTest, s, -.001f, -.001f, 0.999f, .999f); 178 Manager.PhysicsVector vvTemp = Simplex.Intersect(sTest, s, -.001f, -.001f, 0.999f, .999f);
179 179
180 Vertex vTemp=null; 180 Vertex vTemp=null;
181 if (vvTemp != null) 181 if (vvTemp != null)
182 vTemp = new Vertex(vvTemp); 182 vTemp = new Vertex(vvTemp);
183 183
184 if (vTemp!=null) { 184 if (vTemp!=null) {
185 185
186 Manager.PhysicsVector diff=(s.v1-vTemp); 186 Manager.PhysicsVector diff=(s.v1-vTemp);
187 float distTemp=diff.length(); 187 float distTemp=diff.length();
188 188
189 if (bestIntersection==null || distTemp<distToV1) { 189 if (bestIntersection==null || distTemp<distToV1) {
190 bestIntersection=vTemp; 190 bestIntersection=vTemp;
191 distToV1=distTemp; 191 distToV1=distTemp;
192 bestIntersectingSimplex = sTest; 192 bestIntersectingSimplex = sTest;
193 } 193 }
194 194
195 } // end if vTemp 195 } // end if vTemp
196 196
197 } // end foreach 197 } // end foreach
198 198
199 Intersection = bestIntersection; 199 Intersection = bestIntersection;
200 if (bestIntersectingSimplex != null) 200 if (bestIntersectingSimplex != null)
201 nextVertex = bestIntersectingSimplex.v2; 201 nextVertex = bestIntersectingSimplex.v2;
202 else 202 else
203 nextVertex = null; 203 nextVertex = null;
204 } 204 }
205 205
206 206
207 public static SimpleHull SubtractHull(SimpleHull baseHull, SimpleHull otherHull) 207 public static SimpleHull SubtractHull(SimpleHull baseHull, SimpleHull otherHull)
208 { 208 {
209 209
210 SimpleHull baseHullClone = baseHull.Clone(); 210 SimpleHull baseHullClone = baseHull.Clone();
211 SimpleHull otherHullClone = otherHull.Clone(); 211 SimpleHull otherHullClone = otherHull.Clone();
212 bool intersects = false; 212 bool intersects = false;
213 213
214 MainLog.Instance.Debug("State before intersection detection"); 214 MainLog.Instance.Debug("State before intersection detection");
215 MainLog.Instance.Debug("The baseHull is:\n{1}", 0, baseHullClone.ToString()); 215 MainLog.Instance.Debug("The baseHull is:\n{1}", 0, baseHullClone.ToString());
216 MainLog.Instance.Debug("The otherHull is:\n{1}", 0, otherHullClone.ToString()); 216 MainLog.Instance.Debug("The otherHull is:\n{1}", 0, otherHullClone.ToString());
217 217
218 { 218 {
219 int iBase, iOther; 219 int iBase, iOther;
220 220
221 // Insert into baseHull 221 // Insert into baseHull
222 for (iBase = 0; iBase < baseHullClone.vertices.Count; iBase++) 222 for (iBase = 0; iBase < baseHullClone.vertices.Count; iBase++)
223 { 223 {
224 int iBaseNext = (iBase + 1) % baseHullClone.vertices.Count; 224 int iBaseNext = (iBase + 1) % baseHullClone.vertices.Count;
225 Simplex sBase = new Simplex(baseHullClone.vertices[iBase], baseHullClone.vertices[iBaseNext]); 225 Simplex sBase = new Simplex(baseHullClone.vertices[iBase], baseHullClone.vertices[iBaseNext]);
226 226
227 for (iOther = 0; iOther < otherHullClone.vertices.Count; iOther++) 227 for (iOther = 0; iOther < otherHullClone.vertices.Count; iOther++)
228 { 228 {
229 int iOtherNext = (iOther + 1) % otherHullClone.vertices.Count; 229 int iOtherNext = (iOther + 1) % otherHullClone.vertices.Count;
230 Simplex sOther = new Simplex(otherHullClone.vertices[iOther], otherHullClone.vertices[iOtherNext]); 230 Simplex sOther = new Simplex(otherHullClone.vertices[iOther], otherHullClone.vertices[iOtherNext]);
231 231
232 Manager.PhysicsVector intersect = Simplex.Intersect(sBase, sOther, 0.001f, -.001f, 0.999f, 1.001f); 232 Manager.PhysicsVector intersect = Simplex.Intersect(sBase, sOther, 0.001f, -.001f, 0.999f, 1.001f);
233 if (intersect != null) 233 if (intersect != null)
234 { 234 {
235 Vertex vIntersect = new Vertex(intersect); 235 Vertex vIntersect = new Vertex(intersect);
236 baseHullClone.vertices.Insert(iBase + 1, vIntersect); 236 baseHullClone.vertices.Insert(iBase + 1, vIntersect);
237 sBase.v2 = vIntersect; 237 sBase.v2 = vIntersect;
238 intersects = true; 238 intersects = true;
239 } 239 }
240 } 240 }
241 } 241 }
242 } 242 }
243 243
244 MainLog.Instance.Debug("State after intersection detection for the base hull"); 244 MainLog.Instance.Debug("State after intersection detection for the base hull");
245 MainLog.Instance.Debug("The baseHull is:\n{1}", 0, baseHullClone.ToString()); 245 MainLog.Instance.Debug("The baseHull is:\n{1}", 0, baseHullClone.ToString());
246 246
247 { 247 {
248 int iOther, iBase; 248 int iOther, iBase;
249 249
250 // Insert into otherHull 250 // Insert into otherHull
251 for (iOther = 0; iOther < otherHullClone.vertices.Count; iOther++) 251 for (iOther = 0; iOther < otherHullClone.vertices.Count; iOther++)
252 { 252 {
253 int iOtherNext = (iOther + 1) % otherHullClone.vertices.Count; 253 int iOtherNext = (iOther + 1) % otherHullClone.vertices.Count;
254 Simplex sOther = new Simplex(otherHullClone.vertices[iOther], otherHullClone.vertices[iOtherNext]); 254 Simplex sOther = new Simplex(otherHullClone.vertices[iOther], otherHullClone.vertices[iOtherNext]);
255 255
256 for (iBase = 0; iBase < baseHullClone.vertices.Count; iBase++) 256 for (iBase = 0; iBase < baseHullClone.vertices.Count; iBase++)
257 { 257 {
258 int iBaseNext = (iBase + 1) % baseHullClone.vertices.Count; 258 int iBaseNext = (iBase + 1) % baseHullClone.vertices.Count;
259 Simplex sBase = new Simplex(baseHullClone.vertices[iBase], baseHullClone.vertices[iBaseNext]); 259 Simplex sBase = new Simplex(baseHullClone.vertices[iBase], baseHullClone.vertices[iBaseNext]);
260 260
261 Manager.PhysicsVector intersect = Simplex.Intersect(sBase, sOther, -.001f, 0.001f, 1.001f, 0.999f); 261 Manager.PhysicsVector intersect = Simplex.Intersect(sBase, sOther, -.001f, 0.001f, 1.001f, 0.999f);
262 if (intersect != null) 262 if (intersect != null)
263 { 263 {
264 Vertex vIntersect = new Vertex(intersect); 264 Vertex vIntersect = new Vertex(intersect);
265 otherHullClone.vertices.Insert(iOther + 1, vIntersect); 265 otherHullClone.vertices.Insert(iOther + 1, vIntersect);
266 sOther.v2 = vIntersect; 266 sOther.v2 = vIntersect;
267 intersects = true; 267 intersects = true;
268 } 268 }
269 } 269 }
270 } 270 }
271 } 271 }
272 272
273 MainLog.Instance.Debug("State after intersection detection for the base hull"); 273 MainLog.Instance.Debug("State after intersection detection for the base hull");
274 MainLog.Instance.Debug("The otherHull is:\n{1}", 0, otherHullClone.ToString()); 274 MainLog.Instance.Debug("The otherHull is:\n{1}", 0, otherHullClone.ToString());
275 275
276 276
277 bool otherIsInBase = baseHullClone.containsPointsFrom(otherHullClone); 277 bool otherIsInBase = baseHullClone.containsPointsFrom(otherHullClone);
278 if (!intersects && otherIsInBase) 278 if (!intersects && otherIsInBase)
279 { 279 {
280 // We have a hole here 280 // We have a hole here
281 baseHullClone.holeVertices = otherHullClone.vertices; 281 baseHullClone.holeVertices = otherHullClone.vertices;
282 return baseHullClone; 282 return baseHullClone;
283 } 283 }
284 284
285 285
286 SimpleHull result = new SimpleHull(); 286 SimpleHull result = new SimpleHull();
287 287
288 // Find a good starting Simplex from baseHull 288 // Find a good starting Simplex from baseHull
289 // A good starting simplex is one that is outside otherHull 289 // A good starting simplex is one that is outside otherHull
290 // Such a simplex must exist, otherwise the result will be empty 290 // Such a simplex must exist, otherwise the result will be empty
291 Vertex baseStartVertex = null; 291 Vertex baseStartVertex = null;
292 { 292 {
293 int iBase; 293 int iBase;
294 for (iBase = 0; iBase < baseHullClone.vertices.Count; iBase++) 294 for (iBase = 0; iBase < baseHullClone.vertices.Count; iBase++)
295 { 295 {
296 int iBaseNext = (iBase + 1) % baseHullClone.vertices.Count; 296 int iBaseNext = (iBase + 1) % baseHullClone.vertices.Count;
297 Vertex center = new Vertex((baseHullClone.vertices[iBase] + baseHullClone.vertices[iBaseNext]) / 2.0f); 297 Vertex center = new Vertex((baseHullClone.vertices[iBase] + baseHullClone.vertices[iBaseNext]) / 2.0f);
298 bool isOutside = !otherHullClone.IsPointIn(center); 298 bool isOutside = !otherHullClone.IsPointIn(center);
299 if (isOutside) 299 if (isOutside)
300 { 300 {
301 baseStartVertex = baseHullClone.vertices[iBaseNext]; 301 baseStartVertex = baseHullClone.vertices[iBaseNext];
302 break; 302 break;
303 } 303 }
304 } 304 }
305 } 305 }
306 306
307 307
308 if (baseStartVertex == null) // i.e. no simplex fulfilled the "outside" condition. 308 if (baseStartVertex == null) // i.e. no simplex fulfilled the "outside" condition.
309 // In otherwords, subtractHull completely embraces baseHull 309 // In otherwords, subtractHull completely embraces baseHull
310 { 310 {
311 return result; 311 return result;
312 } 312 }
313 313
314 // The simplex that *starts* with baseStartVertex is outside the cutting hull, 314 // The simplex that *starts* with baseStartVertex is outside the cutting hull,
315 // so we can start our walk with the next vertex without loosing a branch 315 // so we can start our walk with the next vertex without loosing a branch
316 Vertex V1 = baseStartVertex; 316 Vertex V1 = baseStartVertex;
317 bool onBase = true; 317 bool onBase = true;
318 318
319 // And here is how we do the magic :-) 319 // And here is how we do the magic :-)
320 // Start on the base hull. 320 // Start on the base hull.
321 // Walk the vertices in the positive direction 321 // Walk the vertices in the positive direction
322 // For each vertex check, whether it is a vertex shared with the other hull 322 // For each vertex check, whether it is a vertex shared with the other hull
323 // if this is the case, switch over to walking the other vertex list. 323 // if this is the case, switch over to walking the other vertex list.
324 // Note: The other hull *must* go backwards to our starting point (via several orther vertices) 324 // Note: The other hull *must* go backwards to our starting point (via several orther vertices)
325 // Thus it is important that the cutting hull has the inverse directional sense than the 325 // Thus it is important that the cutting hull has the inverse directional sense than the
326 // base hull!!!!!!!!! (means if base goes CW around it's center cutting hull must go CCW) 326 // base hull!!!!!!!!! (means if base goes CW around it's center cutting hull must go CCW)
327 327
328 bool done = false; 328 bool done = false;
329 while (!done) 329 while (!done)
330 { 330 {
331 result.AddVertex(V1); 331 result.AddVertex(V1);
332 Vertex nextVertex = null; 332 Vertex nextVertex = null;
333 if (onBase) 333 if (onBase)
334 { 334 {
335 nextVertex = otherHullClone.FindVertex(V1, 0.001f); 335 nextVertex = otherHullClone.FindVertex(V1, 0.001f);
336 } 336 }
337 else 337 else
338 { 338 {
339 nextVertex = baseHullClone.FindVertex(V1, 0.001f); 339 nextVertex = baseHullClone.FindVertex(V1, 0.001f);
340 } 340 }
341 341
342 if (nextVertex != null) // A node that represents an intersection 342 if (nextVertex != null) // A node that represents an intersection
343 { 343 {
344 V1 = nextVertex; // Needed to find the next vertex on the other hull 344 V1 = nextVertex; // Needed to find the next vertex on the other hull
345 onBase = !onBase; 345 onBase = !onBase;
346 } 346 }
347 347
348 if (onBase) 348 if (onBase)
349 V1 = baseHullClone.getNextVertex(V1); 349 V1 = baseHullClone.getNextVertex(V1);
350 else 350 else
351 V1 = otherHullClone.getNextVertex(V1); 351 V1 = otherHullClone.getNextVertex(V1);
352 352
353 if (V1 == baseStartVertex) 353 if (V1 == baseStartVertex)
354 done = true; 354 done = true;
355 } 355 }
356 356
357 MainLog.Instance.Debug("The resulting Hull is:\n{1}", 0, result.ToString()); 357 MainLog.Instance.Debug("The resulting Hull is:\n{1}", 0, result.ToString());
358 358
359 return result; 359 return result;
360 360
361 } 361 }
362 } 362 }
363} 363}
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 @@
1using System; 1using System;
2using System.Collections.Generic; 2using System.Collections.Generic;
3using System.Text; 3using System.Text;
4using OpenSim.Region.Physics.Manager; 4using OpenSim.Region.Physics.Manager;
5 5
6namespace OpenSim.Region.Physics.Meshing 6namespace 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