From db174dfa2061ce35b657cd8f119f1176b53c6207 Mon Sep 17 00:00:00 2001
From: Jeff Ames
Date: Sun, 11 Nov 2007 09:19:21 +0000
Subject: set svn:eol-style
---
.../BulletXPlugin/TriangleIndexVertexArray.cs | 322 ++++-----
OpenSim/Region/Physics/Manager/IMesher.cs | 52 +-
OpenSim/Region/Physics/Meshing/Extruder.cs | 166 ++---
OpenSim/Region/Physics/Meshing/HelperTypes.cs | 610 ++++++++--------
OpenSim/Region/Physics/Meshing/Mesh.cs | 426 +++++------
OpenSim/Region/Physics/Meshing/Meshmerizer.cs | 786 ++++++++++-----------
OpenSim/Region/Physics/Meshing/SimpleHull.cs | 726 +++++++++----------
OpenSim/Region/Physics/Meshing/Simplex.cs | 394 +++++------
8 files changed, 1741 insertions(+), 1741 deletions(-)
(limited to 'OpenSim/Region/Physics')
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 @@
-/*
- Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
- Bullet original C++ version Copyright (c) 2003-2007 Erwin Coumans http://bulletphysics.com
-
- This software is provided 'as-is', without any express or implied
- warranty. In no event will the authors be held liable for any damages
- arising from the use of this software.
-
- Permission is granted to anyone to use this software for any purpose,
- including commercial applications, and to alter it and redistribute it
- freely, subject to the following restrictions:
-
- 1. The origin of this software must not be misrepresented; you must not
- claim that you wrote the original software. If you use this software
- in a product, an acknowledgment in the product documentation would be
- appreciated but is not required.
- 2. Altered source versions must be plainly marked as such, and must not be
- misrepresented as being the original software.
- 3. This notice may not be removed or altered from any source distribution.
-*/
-
-/*
-
- This file contains a class TriangleIndexVertexArray. I tried using the class with the same name
- from the BulletX implementation and found it unusable for the purpose of using triangle meshes
- within BulletX as the implementation was painfully incomplete.
- The attempt to derive from the original class failed as viable members were hidden.
- Fiddling around with BulletX itself was not my intention.
- So I copied the class to the BulletX-plugin and modified it.
- If you want to fiddle around with it it's up to you to move all this to BulletX.
- If someone someday implements the missing functionality in BulletX, feel free to remove this class.
- It's just an ugly hack.
-
- */
-using System;
-using System.Collections.Generic;
-using System.Text;
-using MonoXnaCompactMaths;
-
-namespace OpenSim.Region.Physics.BulletXPlugin
-{
- ///
- /// IndexedMesh indexes into existing vertex and index arrays, in a similar way OpenGL glDrawElements
- /// instead of the number of indices, we pass the number of triangles
- ///
- public struct IndexedMesh
- {
- private int _numTriangles;
- private int[] _triangleIndexBase;
- private int _triangleIndexStride;
- private int _numVertices;
- private Vector3[] _vertexBase;
- private int _vertexStride;
-
- public IndexedMesh(int numTriangleIndices, int[] triangleIndexBase, int triangleIndexStride, int numVertices, Vector3[] vertexBase, int vertexStride)
- {
- _numTriangles = numTriangleIndices;
- _triangleIndexBase = triangleIndexBase;
- _triangleIndexStride = triangleIndexStride;
- _vertexBase = vertexBase;
- _numVertices = numVertices;
- _vertexStride = vertexStride;
- }
-
- public IndexedMesh(int[] triangleIndexBase, Vector3[] vertexBase)
- {
- _numTriangles = triangleIndexBase.Length;
- _triangleIndexBase = triangleIndexBase;
- _triangleIndexStride = 32;
- _vertexBase = vertexBase;
- _numVertices = vertexBase.Length;
- _vertexStride = 24;
- }
-
- public int TriangleCount { get { return _numTriangles; } set { _numTriangles = value; } }
- public int[] TriangleIndexBase { get { return _triangleIndexBase; } set { _triangleIndexBase = value; } }
- public int TriangleIndexStride { get { return _triangleIndexStride; } set { _triangleIndexStride = value; } }
- public int VertexCount { get { return _numVertices; } set { _numVertices = value; } }
- public Vector3[] VertexBase { get { return _vertexBase; } set { _vertexBase = value; } }
- public int VertexStride { get { return _vertexStride; } set { _vertexStride = value; } }
- }
-
- ///
- /// TriangleIndexVertexArray allows to use multiple meshes, by indexing into existing triangle/index arrays.
- /// Additional meshes can be added using addIndexedMesh
- ///
- public class TriangleIndexVertexArray : XnaDevRu.BulletX.StridingMeshInterface
- {
- List _indexedMeshes = new List();
-
- public TriangleIndexVertexArray() { }
-
- public TriangleIndexVertexArray(int numTriangleIndices, int[] triangleIndexBase, int triangleIndexStride, int numVertices, Vector3[] vertexBase, int vertexStride)
- {
- IndexedMesh mesh = new IndexedMesh();
- mesh.TriangleCount = numTriangleIndices;
- mesh.TriangleIndexBase = triangleIndexBase;
- mesh.TriangleIndexStride = triangleIndexStride;
- mesh.VertexBase = vertexBase;
- mesh.VertexCount = numVertices;
- mesh.VertexStride = vertexStride;
-
- AddIndexedMesh(mesh);
- }
-
- public TriangleIndexVertexArray(int[] triangleIndexBase, Vector3[] vertexBase)
- : this(triangleIndexBase.Length, triangleIndexBase, 32, vertexBase.Length, vertexBase, 24) { }
-
- public void AddIndexedMesh(IndexedMesh indexedMesh)
- {
- _indexedMeshes.Add(indexedMesh);
- }
-
- public override void GetLockedVertexIndexBase(out List verts, out List indicies, out int numfaces, int subpart)
- {
- throw new Exception("The method or operation is not implemented.");
- }
-
- public override void GetLockedReadOnlyVertexIndexBase(out List verts, out List indicies, out int numfaces, int subpart)
- {
- IndexedMesh m = _indexedMeshes[0];
- Vector3[] vertexBase = m.VertexBase;
- verts = new List();
- foreach (Vector3 v in vertexBase)
- {
- verts.Add(v);
- }
- int[] indexBase = m.TriangleIndexBase;
- indicies = new List();
- foreach (int i in indexBase)
- {
- indicies.Add(i);
- }
- numfaces = vertexBase.GetLength(0);
- }
-
- public override void UnLockVertexBase(int subpart)
- {
- throw new Exception("The method or operation is not implemented.");
- }
-
- public override void UnLockReadOnlyVertexBase(int subpart)
- {
- }
-
- public override int SubPartsCount()
- {
- return _indexedMeshes.Count;
- }
-
- public override void PreallocateVertices(int numverts)
- {
- throw new Exception("The method or operation is not implemented.");
- }
-
- public override void PreallocateIndices(int numindices)
- {
- throw new Exception("The method or operation is not implemented.");
- }
- }
-}
+/*
+ Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
+ Bullet original C++ version Copyright (c) 2003-2007 Erwin Coumans http://bulletphysics.com
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+/*
+
+ This file contains a class TriangleIndexVertexArray. I tried using the class with the same name
+ from the BulletX implementation and found it unusable for the purpose of using triangle meshes
+ within BulletX as the implementation was painfully incomplete.
+ The attempt to derive from the original class failed as viable members were hidden.
+ Fiddling around with BulletX itself was not my intention.
+ So I copied the class to the BulletX-plugin and modified it.
+ If you want to fiddle around with it it's up to you to move all this to BulletX.
+ If someone someday implements the missing functionality in BulletX, feel free to remove this class.
+ It's just an ugly hack.
+
+ */
+using System;
+using System.Collections.Generic;
+using System.Text;
+using MonoXnaCompactMaths;
+
+namespace OpenSim.Region.Physics.BulletXPlugin
+{
+ ///
+ /// IndexedMesh indexes into existing vertex and index arrays, in a similar way OpenGL glDrawElements
+ /// instead of the number of indices, we pass the number of triangles
+ ///
+ public struct IndexedMesh
+ {
+ private int _numTriangles;
+ private int[] _triangleIndexBase;
+ private int _triangleIndexStride;
+ private int _numVertices;
+ private Vector3[] _vertexBase;
+ private int _vertexStride;
+
+ public IndexedMesh(int numTriangleIndices, int[] triangleIndexBase, int triangleIndexStride, int numVertices, Vector3[] vertexBase, int vertexStride)
+ {
+ _numTriangles = numTriangleIndices;
+ _triangleIndexBase = triangleIndexBase;
+ _triangleIndexStride = triangleIndexStride;
+ _vertexBase = vertexBase;
+ _numVertices = numVertices;
+ _vertexStride = vertexStride;
+ }
+
+ public IndexedMesh(int[] triangleIndexBase, Vector3[] vertexBase)
+ {
+ _numTriangles = triangleIndexBase.Length;
+ _triangleIndexBase = triangleIndexBase;
+ _triangleIndexStride = 32;
+ _vertexBase = vertexBase;
+ _numVertices = vertexBase.Length;
+ _vertexStride = 24;
+ }
+
+ public int TriangleCount { get { return _numTriangles; } set { _numTriangles = value; } }
+ public int[] TriangleIndexBase { get { return _triangleIndexBase; } set { _triangleIndexBase = value; } }
+ public int TriangleIndexStride { get { return _triangleIndexStride; } set { _triangleIndexStride = value; } }
+ public int VertexCount { get { return _numVertices; } set { _numVertices = value; } }
+ public Vector3[] VertexBase { get { return _vertexBase; } set { _vertexBase = value; } }
+ public int VertexStride { get { return _vertexStride; } set { _vertexStride = value; } }
+ }
+
+ ///
+ /// TriangleIndexVertexArray allows to use multiple meshes, by indexing into existing triangle/index arrays.
+ /// Additional meshes can be added using addIndexedMesh
+ ///
+ public class TriangleIndexVertexArray : XnaDevRu.BulletX.StridingMeshInterface
+ {
+ List _indexedMeshes = new List();
+
+ public TriangleIndexVertexArray() { }
+
+ public TriangleIndexVertexArray(int numTriangleIndices, int[] triangleIndexBase, int triangleIndexStride, int numVertices, Vector3[] vertexBase, int vertexStride)
+ {
+ IndexedMesh mesh = new IndexedMesh();
+ mesh.TriangleCount = numTriangleIndices;
+ mesh.TriangleIndexBase = triangleIndexBase;
+ mesh.TriangleIndexStride = triangleIndexStride;
+ mesh.VertexBase = vertexBase;
+ mesh.VertexCount = numVertices;
+ mesh.VertexStride = vertexStride;
+
+ AddIndexedMesh(mesh);
+ }
+
+ public TriangleIndexVertexArray(int[] triangleIndexBase, Vector3[] vertexBase)
+ : this(triangleIndexBase.Length, triangleIndexBase, 32, vertexBase.Length, vertexBase, 24) { }
+
+ public void AddIndexedMesh(IndexedMesh indexedMesh)
+ {
+ _indexedMeshes.Add(indexedMesh);
+ }
+
+ public override void GetLockedVertexIndexBase(out List verts, out List indicies, out int numfaces, int subpart)
+ {
+ throw new Exception("The method or operation is not implemented.");
+ }
+
+ public override void GetLockedReadOnlyVertexIndexBase(out List verts, out List indicies, out int numfaces, int subpart)
+ {
+ IndexedMesh m = _indexedMeshes[0];
+ Vector3[] vertexBase = m.VertexBase;
+ verts = new List();
+ foreach (Vector3 v in vertexBase)
+ {
+ verts.Add(v);
+ }
+ int[] indexBase = m.TriangleIndexBase;
+ indicies = new List();
+ foreach (int i in indexBase)
+ {
+ indicies.Add(i);
+ }
+ numfaces = vertexBase.GetLength(0);
+ }
+
+ public override void UnLockVertexBase(int subpart)
+ {
+ throw new Exception("The method or operation is not implemented.");
+ }
+
+ public override void UnLockReadOnlyVertexBase(int subpart)
+ {
+ }
+
+ public override int SubPartsCount()
+ {
+ return _indexedMeshes.Count;
+ }
+
+ public override void PreallocateVertices(int numverts)
+ {
+ throw new Exception("The method or operation is not implemented.");
+ }
+
+ public override void PreallocateIndices(int numindices)
+ {
+ throw new Exception("The method or operation is not implemented.");
+ }
+ }
+}
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 @@
-using System;
-using System.Collections.Generic;
-using System.Text;
-
-using OpenSim.Framework;
-
-namespace OpenSim.Region.Physics.Manager
-{
- public interface IMesher
- {
- IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, PhysicsVector size);
- }
-
- public interface IVertex {
- }
-
- public interface IMesh
- {
- List getVertexList();
- int[] getIndexListAsInt();
- int[] getIndexListAsIntLocked();
- float[] getVertexListAsFloatLocked();
-
-
- }
-}
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+using OpenSim.Framework;
+
+namespace OpenSim.Region.Physics.Manager
+{
+ public interface IMesher
+ {
+ IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, PhysicsVector size);
+ }
+
+ public interface IVertex {
+ }
+
+ public interface IMesh
+ {
+ List getVertexList();
+ int[] getIndexListAsInt();
+ int[] getIndexListAsIntLocked();
+ float[] getVertexListAsFloatLocked();
+
+
+ }
+}
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 @@
-using System;
-using System.Collections.Generic;
-using System.Text;
-
-namespace OpenSim.Region.Physics.Meshing
-{
- class Extruder
- {
- public float startParameter;
- public float stopParameter;
- public Manager.PhysicsVector size;
-
- public Mesh Extrude(Mesh m)
- {
- // Currently only works for iSteps=1;
- Mesh result = new Mesh();
-
- Mesh workingPlus = m.Clone();
- Mesh workingMinus = m.Clone();
-
- foreach (Vertex v in workingPlus.vertices)
- {
- if (v == null)
- continue;
-
- v.Z = +.5f;
- v.X *= size.X;
- v.Y *= size.Y;
- v.Z *= size.Z;
- }
-
- foreach (Vertex v in workingMinus.vertices)
- {
- if (v == null)
- continue;
-
- v.Z = -.5f;
- v.X *= size.X;
- v.Y *= size.Y;
- v.Z *= size.Z;
- }
-
- foreach (Triangle t in workingMinus.triangles)
- {
- t.invertNormal();
- }
-
- result.Append(workingMinus);
- result.Append(workingPlus);
-
- int iLastNull = 0;
- for (int i = 0; i < workingPlus.vertices.Count; i++)
- {
- int iNext = (i + 1);
-
- if (workingPlus.vertices[i] == null) // Can't make a simplex here
- {
- iLastNull = i+1;
- continue;
- }
-
- if (i == workingPlus.vertices.Count-1) // End of list
- {
- iNext = iLastNull;
- }
-
- if (workingPlus.vertices[iNext] == null) // Null means wrap to begin of last segment
- {
- iNext = iLastNull;
- }
-
- Triangle tSide;
- tSide = new Triangle(workingPlus.vertices[i], workingMinus.vertices[i], workingPlus.vertices[iNext]);
- result.Add(tSide);
-
- tSide = new Triangle(workingPlus.vertices[iNext], workingMinus.vertices[i], workingMinus.vertices[iNext]);
- result.Add(tSide);
- }
-
- return result;
- }
- }
-}
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace OpenSim.Region.Physics.Meshing
+{
+ class Extruder
+ {
+ public float startParameter;
+ public float stopParameter;
+ public Manager.PhysicsVector size;
+
+ public Mesh Extrude(Mesh m)
+ {
+ // Currently only works for iSteps=1;
+ Mesh result = new Mesh();
+
+ Mesh workingPlus = m.Clone();
+ Mesh workingMinus = m.Clone();
+
+ foreach (Vertex v in workingPlus.vertices)
+ {
+ if (v == null)
+ continue;
+
+ v.Z = +.5f;
+ v.X *= size.X;
+ v.Y *= size.Y;
+ v.Z *= size.Z;
+ }
+
+ foreach (Vertex v in workingMinus.vertices)
+ {
+ if (v == null)
+ continue;
+
+ v.Z = -.5f;
+ v.X *= size.X;
+ v.Y *= size.Y;
+ v.Z *= size.Z;
+ }
+
+ foreach (Triangle t in workingMinus.triangles)
+ {
+ t.invertNormal();
+ }
+
+ result.Append(workingMinus);
+ result.Append(workingPlus);
+
+ int iLastNull = 0;
+ for (int i = 0; i < workingPlus.vertices.Count; i++)
+ {
+ int iNext = (i + 1);
+
+ if (workingPlus.vertices[i] == null) // Can't make a simplex here
+ {
+ iLastNull = i+1;
+ continue;
+ }
+
+ if (i == workingPlus.vertices.Count-1) // End of list
+ {
+ iNext = iLastNull;
+ }
+
+ if (workingPlus.vertices[iNext] == null) // Null means wrap to begin of last segment
+ {
+ iNext = iLastNull;
+ }
+
+ Triangle tSide;
+ tSide = new Triangle(workingPlus.vertices[i], workingMinus.vertices[i], workingPlus.vertices[iNext]);
+ result.Add(tSide);
+
+ tSide = new Triangle(workingPlus.vertices[iNext], workingMinus.vertices[i], workingMinus.vertices[iNext]);
+ result.Add(tSide);
+ }
+
+ return result;
+ }
+ }
+}
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 @@
-/*
-* Copyright (c) Contributors, http://opensimulator.org/
-* See CONTRIBUTORS.TXT for a full list of copyright holders.
-*
-* Redistribution and use in source and binary forms, with or without
-* modification, are permitted provided that the following conditions are met:
-* * Redistributions of source code must retain the above copyright
-* notice, this list of conditions and the following disclaimer.
-* * Redistributions in binary form must reproduce the above copyright
-* notice, this list of conditions and the following disclaimer in the
-* documentation and/or other materials provided with the distribution.
-* * Neither the name of the OpenSim Project nor the
-* names of its contributors may be used to endorse or promote products
-* derived from this software without specific prior written permission.
-*
-* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS AS IS AND ANY
-* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
-* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*
-*/
-
-using System;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.Globalization;
-using OpenSim.Framework.Console;
-using OpenSim.Region.Physics.Manager;
-
-using OpenSim.Region.Physics.Meshing;
-
-public class Vertex : PhysicsVector, IComparable
-{
- public Vertex(float x, float y, float z)
- : base(x, y, z)
- {
- }
-
- public Vertex(PhysicsVector v)
- : base(v.X, v.Y, v.Z)
- {
- }
-
- public Vertex Clone()
- {
- return new Vertex(X, Y, Z);
- }
-
- public static Vertex FromAngle(double angle)
- {
- return new Vertex((float)Math.Cos(angle), (float)Math.Sin(angle), 0.0f);
- }
-
-
- public virtual bool Equals(Vertex v, float tolerance)
- {
- PhysicsVector diff = this - v;
- float d = diff.length();
- if (d < tolerance)
- return true;
-
- return false;
- }
-
-
- public int CompareTo(Vertex other)
- {
- if (X < other.X)
- return -1;
-
- if (X > other.X)
- return 1;
-
- if (Y < other.Y)
- return -1;
-
- if (Y > other.Y)
- return 1;
-
- if (Z < other.Z)
- return -1;
-
- if (Z > other.Z)
- return 1;
-
- return 0;
- }
-
- public static bool operator >(Vertex me, Vertex other)
- {
- return me.CompareTo(other) > 0;
- }
-
- public static bool operator <(Vertex me, Vertex other)
- {
- return me.CompareTo(other) < 0;
- }
- public String ToRaw()
- {
- // Why this stuff with the number formatter?
- // Well, the raw format uses the english/US notation of numbers
- // where the "," separates groups of 1000 while the "." marks the border between 1 and 10E-1.
- // The german notation uses these characters exactly vice versa!
- // The Float.ToString() routine is a localized one, giving different results depending on the country
- // settings your machine works with. Unusable for a machine readable file format :-(
- NumberFormatInfo nfi = new NumberFormatInfo();
- nfi.NumberDecimalSeparator = ".";
- nfi.NumberDecimalDigits = 3;
-
- String s1 = X.ToString("N2", nfi) + " " + Y.ToString("N2", nfi) + " " + Z.ToString("N2", nfi);
-
- return s1;
- }
-
-}
-
-public class Triangle
-{
- public Vertex v1;
- public Vertex v2;
- public Vertex v3;
-
- private float radius_square;
- private float cx;
- private float cy;
-
- public Triangle(Vertex _v1, Vertex _v2, Vertex _v3)
- {
- v1 = _v1;
- v2 = _v2;
- v3 = _v3;
-
- CalcCircle();
- }
-
- public bool isInCircle(float x, float y)
- {
- float dx, dy;
- float dd;
-
- dx = x - cx;
- dy = y - cy;
-
- dd = dx*dx + dy*dy;
- if (dd < radius_square)
- return true;
- else
- return false;
- }
-
- public bool isDegraded()
- {
- // This means, the vertices of this triangle are somewhat strange.
- // They either line up or at least two of them are identical
- return (radius_square == 0.0);
- }
-
- private void CalcCircle()
- {
- // Calculate the center and the radius of a circle given by three points p1, p2, p3
- // It is assumed, that the triangles vertices are already set correctly
- double p1x, p2x, p1y, p2y, p3x, p3y;
-
- // Deviation of this routine:
- // A circle has the general equation (M-p)^2=r^2, where M and p are vectors
- // this gives us three equations f(p)=r^2, each for one point p1, p2, p3
- // putting respectively two equations together gives two equations
- // f(p1)=f(p2) and f(p1)=f(p3)
- // bringing all constant terms to one side brings them to the form
- // M*v1=c1 resp.M*v2=c2 where v1=(p1-p2) and v2=(p1-p3) (still vectors)
- // and c1, c2 are scalars (Naming conventions like the variables below)
- // Now using the equations that are formed by the components of the vectors
- // and isolate Mx lets you make one equation that only holds My
- // The rest is straight forward and eaasy :-)
- //
-
- /* helping variables for temporary results */
- double c1, c2;
- double v1x, v1y, v2x, v2y;
-
- double z, n;
-
- double rx, ry;
-
- // Readout the three points, the triangle consists of
- p1x = v1.X;
- p1y = v1.Y;
-
- p2x = v2.X;
- p2y = v2.Y;
-
- p3x = v3.X;
- p3y = v3.Y;
-
- /* calc helping values first */
- c1 = (p1x*p1x + p1y*p1y - p2x*p2x - p2y*p2y)/2;
- c2 = (p1x*p1x + p1y*p1y - p3x*p3x - p3y*p3y)/2;
-
- v1x = p1x - p2x;
- v1y = p1y - p2y;
-
- v2x = p1x - p3x;
- v2y = p1y - p3y;
-
- z = (c1*v2x - c2*v1x);
- n = (v1y*v2x - v2y*v1x);
-
- if (n == 0.0) // This is no triangle, i.e there are (at least) two points at the same location
- {
- radius_square = 0.0f;
- return;
- }
-
- cy = (float) (z/n);
-
- if (v2x != 0.0)
- {
- cx = (float) ((c2 - v2y*cy)/v2x);
- }
- else if (v1x != 0.0)
- {
- cx = (float) ((c1 - v1y*cy)/v1x);
- }
- else
- {
- Debug.Assert(false, "Malformed triangle"); /* Both terms zero means nothing good */
- }
-
- rx = (p1x - cx);
- ry = (p1y - cy);
-
- radius_square = (float) (rx*rx + ry*ry);
- }
-
- public List GetSimplices()
- {
- List result = new List();
- Simplex s1 = new Simplex(v1, v2);
- Simplex s2 = new Simplex(v2, v3);
- Simplex s3 = new Simplex(v3, v1);
-
- result.Add(s1);
- result.Add(s2);
- result.Add(s3);
-
- return result;
- }
-
- public override String ToString()
- {
- NumberFormatInfo nfi = new NumberFormatInfo();
- nfi.CurrencyDecimalDigits = 2;
- nfi.CurrencyDecimalSeparator = ".";
-
- String s1 = "<" + v1.X.ToString(nfi) + "," + v1.Y.ToString(nfi) + "," + v1.Z.ToString(nfi) + ">";
- String s2 = "<" + v2.X.ToString(nfi) + "," + v2.Y.ToString(nfi) + "," + v2.Z.ToString(nfi) + ">";
- String s3 = "<" + v3.X.ToString(nfi) + "," + v3.Y.ToString(nfi) + "," + v3.Z.ToString(nfi) + ">";
-
- return s1 + ";" + s2 + ";" + s3;
- }
-
- public PhysicsVector getNormal()
- {
- // Vertices
-
- // Vectors for edges
- PhysicsVector e1;
- PhysicsVector e2;
-
- e1 = new PhysicsVector(v1.X - v2.X, v1.Y - v2.Y, v1.Z - v2.Z);
- e2 = new PhysicsVector(v1.X - v3.X, v1.Y - v3.Y, v1.Z - v3.Z);
-
- // Cross product for normal
- PhysicsVector n = PhysicsVector.cross(e1, e2);
-
- // Length
- float l = n.length();
-
- // Normalized "normal"
- n = n / l;
-
- return n;
- }
-
- public void invertNormal()
- {
- Vertex vt;
- vt = v1;
- v1 = v2;
- v2 = vt;
- }
-
- // Dumps a triangle in the "raw faces" format, blender can import. This is for visualisation and
- // debugging purposes
- public String ToStringRaw()
- {
- String output = v1.ToRaw() + " " + v2.ToRaw() + " " +v3.ToRaw();
- return output;
- }
+/*
+* Copyright (c) Contributors, http://opensimulator.org/
+* See CONTRIBUTORS.TXT for a full list of copyright holders.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are met:
+* * Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+* * Redistributions in binary form must reproduce the above copyright
+* notice, this list of conditions and the following disclaimer in the
+* documentation and/or other materials provided with the distribution.
+* * Neither the name of the OpenSim Project nor the
+* names of its contributors may be used to endorse or promote products
+* derived from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS AS IS AND ANY
+* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+*/
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Globalization;
+using OpenSim.Framework.Console;
+using OpenSim.Region.Physics.Manager;
+
+using OpenSim.Region.Physics.Meshing;
+
+public class Vertex : PhysicsVector, IComparable
+{
+ public Vertex(float x, float y, float z)
+ : base(x, y, z)
+ {
+ }
+
+ public Vertex(PhysicsVector v)
+ : base(v.X, v.Y, v.Z)
+ {
+ }
+
+ public Vertex Clone()
+ {
+ return new Vertex(X, Y, Z);
+ }
+
+ public static Vertex FromAngle(double angle)
+ {
+ return new Vertex((float)Math.Cos(angle), (float)Math.Sin(angle), 0.0f);
+ }
+
+
+ public virtual bool Equals(Vertex v, float tolerance)
+ {
+ PhysicsVector diff = this - v;
+ float d = diff.length();
+ if (d < tolerance)
+ return true;
+
+ return false;
+ }
+
+
+ public int CompareTo(Vertex other)
+ {
+ if (X < other.X)
+ return -1;
+
+ if (X > other.X)
+ return 1;
+
+ if (Y < other.Y)
+ return -1;
+
+ if (Y > other.Y)
+ return 1;
+
+ if (Z < other.Z)
+ return -1;
+
+ if (Z > other.Z)
+ return 1;
+
+ return 0;
+ }
+
+ public static bool operator >(Vertex me, Vertex other)
+ {
+ return me.CompareTo(other) > 0;
+ }
+
+ public static bool operator <(Vertex me, Vertex other)
+ {
+ return me.CompareTo(other) < 0;
+ }
+ public String ToRaw()
+ {
+ // Why this stuff with the number formatter?
+ // Well, the raw format uses the english/US notation of numbers
+ // where the "," separates groups of 1000 while the "." marks the border between 1 and 10E-1.
+ // The german notation uses these characters exactly vice versa!
+ // The Float.ToString() routine is a localized one, giving different results depending on the country
+ // settings your machine works with. Unusable for a machine readable file format :-(
+ NumberFormatInfo nfi = new NumberFormatInfo();
+ nfi.NumberDecimalSeparator = ".";
+ nfi.NumberDecimalDigits = 3;
+
+ String s1 = X.ToString("N2", nfi) + " " + Y.ToString("N2", nfi) + " " + Z.ToString("N2", nfi);
+
+ return s1;
+ }
+
+}
+
+public class Triangle
+{
+ public Vertex v1;
+ public Vertex v2;
+ public Vertex v3;
+
+ private float radius_square;
+ private float cx;
+ private float cy;
+
+ public Triangle(Vertex _v1, Vertex _v2, Vertex _v3)
+ {
+ v1 = _v1;
+ v2 = _v2;
+ v3 = _v3;
+
+ CalcCircle();
+ }
+
+ public bool isInCircle(float x, float y)
+ {
+ float dx, dy;
+ float dd;
+
+ dx = x - cx;
+ dy = y - cy;
+
+ dd = dx*dx + dy*dy;
+ if (dd < radius_square)
+ return true;
+ else
+ return false;
+ }
+
+ public bool isDegraded()
+ {
+ // This means, the vertices of this triangle are somewhat strange.
+ // They either line up or at least two of them are identical
+ return (radius_square == 0.0);
+ }
+
+ private void CalcCircle()
+ {
+ // Calculate the center and the radius of a circle given by three points p1, p2, p3
+ // It is assumed, that the triangles vertices are already set correctly
+ double p1x, p2x, p1y, p2y, p3x, p3y;
+
+ // Deviation of this routine:
+ // A circle has the general equation (M-p)^2=r^2, where M and p are vectors
+ // this gives us three equations f(p)=r^2, each for one point p1, p2, p3
+ // putting respectively two equations together gives two equations
+ // f(p1)=f(p2) and f(p1)=f(p3)
+ // bringing all constant terms to one side brings them to the form
+ // M*v1=c1 resp.M*v2=c2 where v1=(p1-p2) and v2=(p1-p3) (still vectors)
+ // and c1, c2 are scalars (Naming conventions like the variables below)
+ // Now using the equations that are formed by the components of the vectors
+ // and isolate Mx lets you make one equation that only holds My
+ // The rest is straight forward and eaasy :-)
+ //
+
+ /* helping variables for temporary results */
+ double c1, c2;
+ double v1x, v1y, v2x, v2y;
+
+ double z, n;
+
+ double rx, ry;
+
+ // Readout the three points, the triangle consists of
+ p1x = v1.X;
+ p1y = v1.Y;
+
+ p2x = v2.X;
+ p2y = v2.Y;
+
+ p3x = v3.X;
+ p3y = v3.Y;
+
+ /* calc helping values first */
+ c1 = (p1x*p1x + p1y*p1y - p2x*p2x - p2y*p2y)/2;
+ c2 = (p1x*p1x + p1y*p1y - p3x*p3x - p3y*p3y)/2;
+
+ v1x = p1x - p2x;
+ v1y = p1y - p2y;
+
+ v2x = p1x - p3x;
+ v2y = p1y - p3y;
+
+ z = (c1*v2x - c2*v1x);
+ n = (v1y*v2x - v2y*v1x);
+
+ if (n == 0.0) // This is no triangle, i.e there are (at least) two points at the same location
+ {
+ radius_square = 0.0f;
+ return;
+ }
+
+ cy = (float) (z/n);
+
+ if (v2x != 0.0)
+ {
+ cx = (float) ((c2 - v2y*cy)/v2x);
+ }
+ else if (v1x != 0.0)
+ {
+ cx = (float) ((c1 - v1y*cy)/v1x);
+ }
+ else
+ {
+ Debug.Assert(false, "Malformed triangle"); /* Both terms zero means nothing good */
+ }
+
+ rx = (p1x - cx);
+ ry = (p1y - cy);
+
+ radius_square = (float) (rx*rx + ry*ry);
+ }
+
+ public List GetSimplices()
+ {
+ List result = new List();
+ Simplex s1 = new Simplex(v1, v2);
+ Simplex s2 = new Simplex(v2, v3);
+ Simplex s3 = new Simplex(v3, v1);
+
+ result.Add(s1);
+ result.Add(s2);
+ result.Add(s3);
+
+ return result;
+ }
+
+ public override String ToString()
+ {
+ NumberFormatInfo nfi = new NumberFormatInfo();
+ nfi.CurrencyDecimalDigits = 2;
+ nfi.CurrencyDecimalSeparator = ".";
+
+ String s1 = "<" + v1.X.ToString(nfi) + "," + v1.Y.ToString(nfi) + "," + v1.Z.ToString(nfi) + ">";
+ String s2 = "<" + v2.X.ToString(nfi) + "," + v2.Y.ToString(nfi) + "," + v2.Z.ToString(nfi) + ">";
+ String s3 = "<" + v3.X.ToString(nfi) + "," + v3.Y.ToString(nfi) + "," + v3.Z.ToString(nfi) + ">";
+
+ return s1 + ";" + s2 + ";" + s3;
+ }
+
+ public PhysicsVector getNormal()
+ {
+ // Vertices
+
+ // Vectors for edges
+ PhysicsVector e1;
+ PhysicsVector e2;
+
+ e1 = new PhysicsVector(v1.X - v2.X, v1.Y - v2.Y, v1.Z - v2.Z);
+ e2 = new PhysicsVector(v1.X - v3.X, v1.Y - v3.Y, v1.Z - v3.Z);
+
+ // Cross product for normal
+ PhysicsVector n = PhysicsVector.cross(e1, e2);
+
+ // Length
+ float l = n.length();
+
+ // Normalized "normal"
+ n = n / l;
+
+ return n;
+ }
+
+ public void invertNormal()
+ {
+ Vertex vt;
+ vt = v1;
+ v1 = v2;
+ v2 = vt;
+ }
+
+ // Dumps a triangle in the "raw faces" format, blender can import. This is for visualisation and
+ // debugging purposes
+ public String ToStringRaw()
+ {
+ String output = v1.ToRaw() + " " + v2.ToRaw() + " " +v3.ToRaw();
+ return output;
+ }
}
\ 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 @@
-using System;
-using System.IO;
-using System.Collections.Generic;
-using System.Text;
-
-using System.Runtime.InteropServices;
-
-
-using OpenSim.Region.Physics.Manager;
-
-namespace OpenSim.Region.Physics.Meshing
-{
- public class Mesh : IMesh
- {
- public List vertices;
- public List triangles;
-
- public float[] normals;
-
- public Mesh()
- {
- vertices = new List();
- triangles = new List();
- }
-
- public Mesh Clone()
- {
- Mesh result = new Mesh();
-
- foreach (Vertex v in vertices)
- {
- if (v == null)
- result.vertices.Add(null);
- else
- result.vertices.Add(v.Clone());
- }
-
- foreach (Triangle t in triangles)
- {
- int iV1, iV2, iV3;
- iV1 = this.vertices.IndexOf(t.v1);
- iV2 = this.vertices.IndexOf(t.v2);
- iV3 = this.vertices.IndexOf(t.v3);
-
- Triangle newT = new Triangle(result.vertices[iV1], result.vertices[iV2], result.vertices[iV3]);
- result.Add(newT);
- }
-
- return result;
- }
-
-
-
- public void Add(Triangle triangle)
- {
- int i;
- i = vertices.IndexOf(triangle.v1);
- if (i < 0)
- throw new ArgumentException("Vertex v1 not known to mesh");
- i = vertices.IndexOf(triangle.v2);
- if (i < 0)
- throw new ArgumentException("Vertex v2 not known to mesh");
- i = vertices.IndexOf(triangle.v3);
- if (i < 0)
- throw new ArgumentException("Vertex v3 not known to mesh");
-
- triangles.Add(triangle);
- }
-
- public void Add(Vertex v)
- {
- vertices.Add(v);
- }
-
- public void Remove(Vertex v)
- {
- int i;
-
- // First, remove all triangles that are build on v
- for (i = 0; i < triangles.Count; i++)
- {
- Triangle t = triangles[i];
- if (t.v1 == v || t.v2 == v || t.v3 == v)
- {
- triangles.RemoveAt(i);
- i--;
- }
- }
-
- // Second remove v itself
- vertices.Remove(v);
- }
-
- public void RemoveTrianglesOutside(SimpleHull hull)
- {
- int i;
-
- for (i = 0; i < triangles.Count; i++)
- {
- Triangle t = triangles[i];
- Vertex v1 = t.v1;
- Vertex v2 = t.v2;
- Vertex v3 = t.v3;
- PhysicsVector m = v1 + v2 + v3;
- m /= 3.0f;
- if (!hull.IsPointIn(new Vertex(m)))
- {
- triangles.RemoveAt(i);
- i--;
- }
- }
- }
-
-
- public void Add(List lv)
- {
- foreach (Vertex v in lv)
- {
- vertices.Add(v);
- }
- }
-
- public List getVertexList()
- {
- List result = new List();
- foreach (Vertex v in vertices)
- {
- result.Add(v);
- }
- return result;
- }
-
- public float[] getVertexListAsFloatLocked()
- {
- float[] result = new float[vertices.Count * 3];
- for (int i = 0; i < vertices.Count; i++)
- {
- Vertex v = vertices[i];
- if (v == null)
- continue;
- result[3 * i + 0] = v.X;
- result[3 * i + 1] = v.Y;
- result[3 * i + 2] = v.Z;
- }
- GCHandle.Alloc(result, GCHandleType.Pinned);
- return result;
- }
-
- public int[] getIndexListAsInt()
- {
- int[] result = new int[triangles.Count * 3];
- for (int i = 0; i < triangles.Count; i++)
- {
- Triangle t = triangles[i];
- result[3 * i + 0] = vertices.IndexOf(t.v1);
- result[3 * i + 1] = vertices.IndexOf(t.v2);
- result[3 * i + 2] = vertices.IndexOf(t.v3);
- }
- return result;
- }
-
- public int[] getIndexListAsIntLocked()
- {
- int[] result = getIndexListAsInt();
- GCHandle.Alloc(result, GCHandleType.Pinned);
- return result;
- }
-
-
- public void Append(Mesh newMesh)
- {
- foreach (Vertex v in newMesh.vertices)
- vertices.Add(v);
-
- foreach (Triangle t in newMesh.triangles)
- Add(t);
-
- }
-
- // Do a linear transformation of mesh.
- public void TransformLinear(float[,] matrix, float[] offset)
- {
- foreach (Vertex v in vertices)
- {
- if (v == null)
- continue;
- float x, y, z;
- x = v.X * matrix[0, 0] + v.Y * matrix[1, 0] + v.Z * matrix[2, 0];
- y = v.X * matrix[0, 1] + v.Y * matrix[1, 1] + v.Z * matrix[2, 1];
- z = v.X * matrix[0, 2] + v.Y * matrix[1, 2] + v.Z * matrix[2, 2];
- v.X = x + offset[0];
- v.Y = y + offset[1];
- v.Z = z + offset[2];
- }
- }
-
- public void DumpRaw(String path, String name, String title)
- {
- if (path == null)
- return;
- String fileName = name + "_" + title + ".raw";
- String completePath = Path.Combine(path, fileName);
- StreamWriter sw = new StreamWriter(completePath);
- foreach (Triangle t in triangles)
- {
- String s = t.ToStringRaw();
- sw.WriteLine(s);
- }
- sw.Close();
- }
- }
-
-}
+using System;
+using System.IO;
+using System.Collections.Generic;
+using System.Text;
+
+using System.Runtime.InteropServices;
+
+
+using OpenSim.Region.Physics.Manager;
+
+namespace OpenSim.Region.Physics.Meshing
+{
+ public class Mesh : IMesh
+ {
+ public List vertices;
+ public List triangles;
+
+ public float[] normals;
+
+ public Mesh()
+ {
+ vertices = new List();
+ triangles = new List();
+ }
+
+ public Mesh Clone()
+ {
+ Mesh result = new Mesh();
+
+ foreach (Vertex v in vertices)
+ {
+ if (v == null)
+ result.vertices.Add(null);
+ else
+ result.vertices.Add(v.Clone());
+ }
+
+ foreach (Triangle t in triangles)
+ {
+ int iV1, iV2, iV3;
+ iV1 = this.vertices.IndexOf(t.v1);
+ iV2 = this.vertices.IndexOf(t.v2);
+ iV3 = this.vertices.IndexOf(t.v3);
+
+ Triangle newT = new Triangle(result.vertices[iV1], result.vertices[iV2], result.vertices[iV3]);
+ result.Add(newT);
+ }
+
+ return result;
+ }
+
+
+
+ public void Add(Triangle triangle)
+ {
+ int i;
+ i = vertices.IndexOf(triangle.v1);
+ if (i < 0)
+ throw new ArgumentException("Vertex v1 not known to mesh");
+ i = vertices.IndexOf(triangle.v2);
+ if (i < 0)
+ throw new ArgumentException("Vertex v2 not known to mesh");
+ i = vertices.IndexOf(triangle.v3);
+ if (i < 0)
+ throw new ArgumentException("Vertex v3 not known to mesh");
+
+ triangles.Add(triangle);
+ }
+
+ public void Add(Vertex v)
+ {
+ vertices.Add(v);
+ }
+
+ public void Remove(Vertex v)
+ {
+ int i;
+
+ // First, remove all triangles that are build on v
+ for (i = 0; i < triangles.Count; i++)
+ {
+ Triangle t = triangles[i];
+ if (t.v1 == v || t.v2 == v || t.v3 == v)
+ {
+ triangles.RemoveAt(i);
+ i--;
+ }
+ }
+
+ // Second remove v itself
+ vertices.Remove(v);
+ }
+
+ public void RemoveTrianglesOutside(SimpleHull hull)
+ {
+ int i;
+
+ for (i = 0; i < triangles.Count; i++)
+ {
+ Triangle t = triangles[i];
+ Vertex v1 = t.v1;
+ Vertex v2 = t.v2;
+ Vertex v3 = t.v3;
+ PhysicsVector m = v1 + v2 + v3;
+ m /= 3.0f;
+ if (!hull.IsPointIn(new Vertex(m)))
+ {
+ triangles.RemoveAt(i);
+ i--;
+ }
+ }
+ }
+
+
+ public void Add(List lv)
+ {
+ foreach (Vertex v in lv)
+ {
+ vertices.Add(v);
+ }
+ }
+
+ public List getVertexList()
+ {
+ List result = new List();
+ foreach (Vertex v in vertices)
+ {
+ result.Add(v);
+ }
+ return result;
+ }
+
+ public float[] getVertexListAsFloatLocked()
+ {
+ float[] result = new float[vertices.Count * 3];
+ for (int i = 0; i < vertices.Count; i++)
+ {
+ Vertex v = vertices[i];
+ if (v == null)
+ continue;
+ result[3 * i + 0] = v.X;
+ result[3 * i + 1] = v.Y;
+ result[3 * i + 2] = v.Z;
+ }
+ GCHandle.Alloc(result, GCHandleType.Pinned);
+ return result;
+ }
+
+ public int[] getIndexListAsInt()
+ {
+ int[] result = new int[triangles.Count * 3];
+ for (int i = 0; i < triangles.Count; i++)
+ {
+ Triangle t = triangles[i];
+ result[3 * i + 0] = vertices.IndexOf(t.v1);
+ result[3 * i + 1] = vertices.IndexOf(t.v2);
+ result[3 * i + 2] = vertices.IndexOf(t.v3);
+ }
+ return result;
+ }
+
+ public int[] getIndexListAsIntLocked()
+ {
+ int[] result = getIndexListAsInt();
+ GCHandle.Alloc(result, GCHandleType.Pinned);
+ return result;
+ }
+
+
+ public void Append(Mesh newMesh)
+ {
+ foreach (Vertex v in newMesh.vertices)
+ vertices.Add(v);
+
+ foreach (Triangle t in newMesh.triangles)
+ Add(t);
+
+ }
+
+ // Do a linear transformation of mesh.
+ public void TransformLinear(float[,] matrix, float[] offset)
+ {
+ foreach (Vertex v in vertices)
+ {
+ if (v == null)
+ continue;
+ float x, y, z;
+ x = v.X * matrix[0, 0] + v.Y * matrix[1, 0] + v.Z * matrix[2, 0];
+ y = v.X * matrix[0, 1] + v.Y * matrix[1, 1] + v.Z * matrix[2, 1];
+ z = v.X * matrix[0, 2] + v.Y * matrix[1, 2] + v.Z * matrix[2, 2];
+ v.X = x + offset[0];
+ v.Y = y + offset[1];
+ v.Z = z + offset[2];
+ }
+ }
+
+ public void DumpRaw(String path, String name, String title)
+ {
+ if (path == null)
+ return;
+ String fileName = name + "_" + title + ".raw";
+ String completePath = Path.Combine(path, fileName);
+ StreamWriter sw = new StreamWriter(completePath);
+ foreach (Triangle t in triangles)
+ {
+ String s = t.ToStringRaw();
+ sw.WriteLine(s);
+ }
+ sw.Close();
+ }
+ }
+
+}
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 @@
-/*
-* Copyright (c) Contributors, http://opensimulator.org/
-* See CONTRIBUTORS.TXT for a full list of copyright holders.
-*
-* Redistribution and use in source and binary forms, with or without
-* modification, are permitted provided that the following conditions are met:
-* * Redistributions of source code must retain the above copyright
-* notice, this list of conditions and the following disclaimer.
-* * Redistributions in binary form must reproduce the above copyright
-* notice, this list of conditions and the following disclaimer in the
-* documentation and/or other materials provided with the distribution.
-* * Neither the name of the OpenSim Project nor the
-* names of its contributors may be used to endorse or promote products
-* derived from this software without specific prior written permission.
-*
-* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS AS IS AND ANY
-* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
-* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*
-*/
-
-using System;
-using System.IO;
-using System.Globalization;
-using System.Diagnostics;
-using System.Collections.Generic;
-using System.Runtime.InteropServices;
-using OpenSim.Framework;
-using OpenSim.Framework.Console;
-using OpenSim.Region.Physics.Manager;
-
-namespace OpenSim.Region.Physics.Meshing
-{
-
- public class MeshmerizerPlugin : IMeshingPlugin
- {
- public MeshmerizerPlugin()
- {
- }
-
- public string GetName()
- {
- return "Meshmerizer";
- }
-
- public IMesher GetMesher()
- {
- return new Meshmerizer();
- }
- }
-
- public class Meshmerizer : IMesher
- {
- // Setting baseDir to a path will enable the dumping of raw files
- // raw files can be imported by blender so a visual inspection of the results can be done
- // const string baseDir = "rawFiles";
- const string baseDir = null;
-
- static void IntersectionParameterPD(PhysicsVector p1, PhysicsVector r1, PhysicsVector p2, PhysicsVector r2, ref float lambda, ref float mu)
- {
- // p1, p2, points on the straight
- // r1, r2, directional vectors of the straight. Not necessarily of length 1!
- // note, that l, m can be scaled such, that the range 0..1 is mapped to the area between two points,
- // thus allowing to decide whether an intersection is between two points
-
- float r1x = r1.X;
- float r1y = r1.Y;
- float r2x = r2.X;
- float r2y = r2.Y;
-
- float denom = r1y*r2x - r1x*r2y;
-
- if (denom == 0.0)
- {
- lambda = Single.NaN;
- mu = Single.NaN;
- return;
- }
-
- float p1x = p1.X;
- float p1y = p1.Y;
- float p2x = p2.X;
- float p2y = p2.Y;
- lambda = (-p2x * r2y + p1x * r2y + (p2y - p1y) * r2x) / denom;
- mu = (-p2x * r1y + p1x * r1y + (p2y - p1y) * r1x) / denom;
-
- }
-
- private static List FindInfluencedTriangles(List triangles, Vertex v)
- {
- List influenced = new List();
- foreach (Triangle t in triangles)
- {
- if (t.isInCircle(v.X, v.Y))
- {
- influenced.Add(t);
- }
- }
- return influenced;
- }
-
-
- private static void InsertVertices(List vertices, int usedForSeed, List triangles)
- {
- // This is a variant of the delaunay algorithm
- // each time a new vertex is inserted, all triangles that are influenced by it are deleted
- // and replaced by new ones including the new vertex
- // It is not very time efficient but easy to implement.
-
- int iCurrentVertex;
- int iMaxVertex = vertices.Count;
- for (iCurrentVertex = usedForSeed; iCurrentVertex < iMaxVertex; iCurrentVertex++)
- {
- // Background: A triangle mesh fulfills the delaunay condition if (iff!)
- // each circumlocutory circle (i.e. the circle that touches all three corners)
- // of each triangle is empty of other vertices.
- // Obviously a single (seeding) triangle fulfills this condition.
- // If we now add one vertex, we need to reconstruct all triangles, that
- // do not fulfill this condition with respect to the new triangle
-
- // Find the triangles that are influenced by the new vertex
- Vertex v=vertices[iCurrentVertex];
- if (v == null)
- continue; // Null is polygon stop marker. Ignore it
- List influencedTriangles=FindInfluencedTriangles(triangles, v);
-
- List simplices = new List();
-
- // Reconstruction phase. First step, dissolve each triangle into it's simplices,
- // i.e. it's "border lines"
- // Goal is to find "inner" borders and delete them, while the hull gets conserved.
- // Inner borders are special in the way that they always come twice, which is how we detect them
- foreach (Triangle t in influencedTriangles)
- {
- List newSimplices = t.GetSimplices();
- simplices.AddRange(newSimplices);
- triangles.Remove(t);
- }
- // Now sort the simplices. That will make identical ones reside side by side in the list
- simplices.Sort();
-
- // Look for duplicate simplices here.
- // Remember, they are directly side by side in the list right now,
- // So we only check directly neighbours
- int iSimplex;
- List innerSimplices = new List();
- for (iSimplex = 1; iSimplex < simplices.Count; iSimplex++) // Startindex=1, so we can refer backwards
- {
- if (simplices[iSimplex - 1].CompareTo(simplices[iSimplex]) == 0)
- {
- innerSimplices.Add(simplices[iSimplex - 1]);
- innerSimplices.Add(simplices[iSimplex]);
- }
- }
-
- foreach (Simplex s in innerSimplices)
- {
- simplices.Remove(s);
- }
-
- // each simplex still in the list belongs to the hull of the region in question
- // The new vertex (yes, we still deal with verices here :-) ) forms a triangle
- // with each of these simplices. Build the new triangles and add them to the list
- foreach (Simplex s in simplices)
- {
- Triangle t = new Triangle(s.v1, s.v2, vertices[iCurrentVertex]);
- if (!t.isDegraded())
- {
- triangles.Add(t);
- }
- }
- }
-
- }
-
-
- static Mesh CreateBoxMesh(String primName, PrimitiveBaseShape primShape, PhysicsVector size)
- // Builds the z (+ and -) surfaces of a box shaped prim
- {
- UInt16 hollowFactor = primShape.ProfileHollow;
- UInt16 profileBegin = primShape.ProfileBegin;
- UInt16 profileEnd = primShape.ProfileEnd;
-
- // Procedure: This is based on the fact that the upper (plus) and lower (minus) Z-surface
- // of a block are basically the same
- // They may be warped differently but the shape is identical
- // So we only create one surface as a model and derive both plus and minus surface of the block from it
- // This is done in a model space where the block spans from -.5 to +.5 in X and Y
- // The mapping to Scene space is done later during the "extrusion" phase
-
- // Base
- Vertex MM = new Vertex(-0.5f, -0.5f, 0.0f);
- Vertex PM = new Vertex(+0.5f, -0.5f, 0.0f);
- Vertex MP = new Vertex(-0.5f, +0.5f, 0.0f);
- Vertex PP = new Vertex(+0.5f, +0.5f, 0.0f);
-
- Meshing.SimpleHull outerHull = new SimpleHull();
- outerHull.AddVertex(MM);
- outerHull.AddVertex(PM);
- outerHull.AddVertex(PP);
- outerHull.AddVertex(MP);
-
- // Deal with cuts now
- if ((profileBegin != 0) || (profileEnd != 0))
- {
- double fProfileBeginAngle = profileBegin / 50000.0 * 360.0; // In degree, for easier debugging and understanding
- fProfileBeginAngle -= (90.0 + 45.0); // for some reasons, the SL client counts from the corner -X/-Y
- double fProfileEndAngle = 360.0 - profileEnd / 50000.0 * 360.0; // Pathend comes as complement to 1.0
- fProfileEndAngle -= (90.0 + 45.0);
- if (fProfileBeginAngle < fProfileEndAngle)
- fProfileEndAngle -= 360.0;
-
- // Note, that we don't want to cut out a triangle, even if this is a
- // good approximation for small cuts. Indeed we want to cut out an arc
- // and we approximate this arc by a polygon chain
- // Also note, that these vectors are of length 1.0 and thus their endpoints lay outside the model space
- // So it can easily be subtracted from the outer hull
- int iSteps = (int)(((fProfileBeginAngle - fProfileEndAngle) / 45.0) + .5); // how many steps do we need with approximately 45 degree
- double dStepWidth=(fProfileBeginAngle-fProfileEndAngle)/iSteps;
-
- Vertex origin = new Vertex(0.0f, 0.0f, 0.0f);
-
- // Note the sequence of vertices here. It's important to have the other rotational sense than in outerHull
- SimpleHull cutHull = new SimpleHull();
- cutHull.AddVertex(origin);
- for (int i=0; i 0)
- {
- float hollowFactorF = (float) hollowFactor/(float) 50000;
- Vertex IMM = new Vertex(-0.5f * hollowFactorF, -0.5f * hollowFactorF, 0.0f);
- Vertex IPM = new Vertex(+0.5f * hollowFactorF, -0.5f * hollowFactorF, 0.0f);
- Vertex IMP = new Vertex(-0.5f * hollowFactorF, +0.5f * hollowFactorF, 0.0f);
- Vertex IPP = new Vertex(+0.5f * hollowFactorF, +0.5f * hollowFactorF, 0.0f);
-
- SimpleHull holeHull = new SimpleHull();
-
- holeHull.AddVertex(IMM);
- holeHull.AddVertex(IMP);
- holeHull.AddVertex(IPP);
- holeHull.AddVertex(IPM);
-
- SimpleHull hollowedHull = SimpleHull.SubtractHull(outerHull, holeHull);
-
- outerHull = hollowedHull;
-
- }
-
- Mesh m = new Mesh();
-
- Vertex Seed1 = new Vertex(0.0f, -10.0f, 0.0f);
- Vertex Seed2 = new Vertex(-10.0f, 10.0f, 0.0f);
- Vertex Seed3 = new Vertex(10.0f, 10.0f, 0.0f);
-
- m.Add(Seed1);
- m.Add(Seed2);
- m.Add(Seed3);
-
- m.Add(new Triangle(Seed1, Seed2, Seed3));
- m.Add(outerHull.getVertices());
-
- InsertVertices(m.vertices, 3, m.triangles);
- m.DumpRaw(baseDir, primName, "Proto first Mesh");
-
- m.Remove(Seed1);
- m.Remove(Seed2);
- m.Remove(Seed3);
- m.DumpRaw(baseDir, primName, "Proto seeds removed");
-
- m.RemoveTrianglesOutside(outerHull);
- m.DumpRaw(baseDir, primName, "Proto outsides removed");
-
- foreach (Triangle t in m.triangles)
- {
- PhysicsVector n = t.getNormal();
- if (n.Z < 0.0)
- t.invertNormal();
- }
-
- Extruder extr = new Extruder();
-
- extr.size = size;
-
- Mesh result = extr.Extrude(m);
- result.DumpRaw(baseDir, primName, "Z extruded");
- return result;
- }
-
- public static void CalcNormals(Mesh mesh)
- {
- int iTriangles = mesh.triangles.Count;
-
- mesh.normals = new float[iTriangles*3];
-
- int i = 0;
- foreach (Triangle t in mesh.triangles)
- {
- float ux, uy, uz;
- float vx, vy, vz;
- float wx, wy, wz;
-
- ux = t.v1.X;
- uy = t.v1.Y;
- uz = t.v1.Z;
-
- vx = t.v2.X;
- vy = t.v2.Y;
- vz = t.v2.Z;
-
- wx = t.v3.X;
- wy = t.v3.Y;
- wz = t.v3.Z;
-
-
- // Vectors for edges
- float e1x, e1y, e1z;
- float e2x, e2y, e2z;
-
- e1x = ux - vx;
- e1y = uy - vy;
- e1z = uz - vz;
-
- e2x = ux - wx;
- e2y = uy - wy;
- e2z = uz - wz;
-
-
- // Cross product for normal
- float nx, ny, nz;
- nx = e1y*e2z - e1z*e2y;
- ny = e1z*e2x - e1x*e2z;
- nz = e1x*e2y - e1y*e2x;
-
- // Length
- float l = (float) Math.Sqrt(nx*nx + ny*ny + nz*nz);
-
- // Normalized "normal"
- nx /= l;
- ny /= l;
- nz /= l;
-
- mesh.normals[i] = nx;
- mesh.normals[i + 1] = ny;
- mesh.normals[i + 2] = nz;
-
- i += 3;
- }
- }
-
- public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, PhysicsVector size)
- {
- Mesh mesh = null;
-
- switch (primShape.ProfileShape)
- {
- case ProfileShape.Square:
- mesh=CreateBoxMesh(primName, primShape, size);
- CalcNormals(mesh);
- break;
- default:
- mesh = CreateBoxMesh(primName, primShape, size);
- CalcNormals(mesh);
- //Set default mesh to cube otherwise it'll return
- // null and crash on the 'setMesh' method in the physics plugins.
- //mesh = null;
- break;
- }
-
- return mesh;
- }
- }
-
-}
+/*
+* Copyright (c) Contributors, http://opensimulator.org/
+* See CONTRIBUTORS.TXT for a full list of copyright holders.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are met:
+* * Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+* * Redistributions in binary form must reproduce the above copyright
+* notice, this list of conditions and the following disclaimer in the
+* documentation and/or other materials provided with the distribution.
+* * Neither the name of the OpenSim Project nor the
+* names of its contributors may be used to endorse or promote products
+* derived from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS AS IS AND ANY
+* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+*/
+
+using System;
+using System.IO;
+using System.Globalization;
+using System.Diagnostics;
+using System.Collections.Generic;
+using System.Runtime.InteropServices;
+using OpenSim.Framework;
+using OpenSim.Framework.Console;
+using OpenSim.Region.Physics.Manager;
+
+namespace OpenSim.Region.Physics.Meshing
+{
+
+ public class MeshmerizerPlugin : IMeshingPlugin
+ {
+ public MeshmerizerPlugin()
+ {
+ }
+
+ public string GetName()
+ {
+ return "Meshmerizer";
+ }
+
+ public IMesher GetMesher()
+ {
+ return new Meshmerizer();
+ }
+ }
+
+ public class Meshmerizer : IMesher
+ {
+ // Setting baseDir to a path will enable the dumping of raw files
+ // raw files can be imported by blender so a visual inspection of the results can be done
+ // const string baseDir = "rawFiles";
+ const string baseDir = null;
+
+ static void IntersectionParameterPD(PhysicsVector p1, PhysicsVector r1, PhysicsVector p2, PhysicsVector r2, ref float lambda, ref float mu)
+ {
+ // p1, p2, points on the straight
+ // r1, r2, directional vectors of the straight. Not necessarily of length 1!
+ // note, that l, m can be scaled such, that the range 0..1 is mapped to the area between two points,
+ // thus allowing to decide whether an intersection is between two points
+
+ float r1x = r1.X;
+ float r1y = r1.Y;
+ float r2x = r2.X;
+ float r2y = r2.Y;
+
+ float denom = r1y*r2x - r1x*r2y;
+
+ if (denom == 0.0)
+ {
+ lambda = Single.NaN;
+ mu = Single.NaN;
+ return;
+ }
+
+ float p1x = p1.X;
+ float p1y = p1.Y;
+ float p2x = p2.X;
+ float p2y = p2.Y;
+ lambda = (-p2x * r2y + p1x * r2y + (p2y - p1y) * r2x) / denom;
+ mu = (-p2x * r1y + p1x * r1y + (p2y - p1y) * r1x) / denom;
+
+ }
+
+ private static List FindInfluencedTriangles(List triangles, Vertex v)
+ {
+ List influenced = new List();
+ foreach (Triangle t in triangles)
+ {
+ if (t.isInCircle(v.X, v.Y))
+ {
+ influenced.Add(t);
+ }
+ }
+ return influenced;
+ }
+
+
+ private static void InsertVertices(List vertices, int usedForSeed, List triangles)
+ {
+ // This is a variant of the delaunay algorithm
+ // each time a new vertex is inserted, all triangles that are influenced by it are deleted
+ // and replaced by new ones including the new vertex
+ // It is not very time efficient but easy to implement.
+
+ int iCurrentVertex;
+ int iMaxVertex = vertices.Count;
+ for (iCurrentVertex = usedForSeed; iCurrentVertex < iMaxVertex; iCurrentVertex++)
+ {
+ // Background: A triangle mesh fulfills the delaunay condition if (iff!)
+ // each circumlocutory circle (i.e. the circle that touches all three corners)
+ // of each triangle is empty of other vertices.
+ // Obviously a single (seeding) triangle fulfills this condition.
+ // If we now add one vertex, we need to reconstruct all triangles, that
+ // do not fulfill this condition with respect to the new triangle
+
+ // Find the triangles that are influenced by the new vertex
+ Vertex v=vertices[iCurrentVertex];
+ if (v == null)
+ continue; // Null is polygon stop marker. Ignore it
+ List influencedTriangles=FindInfluencedTriangles(triangles, v);
+
+ List simplices = new List();
+
+ // Reconstruction phase. First step, dissolve each triangle into it's simplices,
+ // i.e. it's "border lines"
+ // Goal is to find "inner" borders and delete them, while the hull gets conserved.
+ // Inner borders are special in the way that they always come twice, which is how we detect them
+ foreach (Triangle t in influencedTriangles)
+ {
+ List newSimplices = t.GetSimplices();
+ simplices.AddRange(newSimplices);
+ triangles.Remove(t);
+ }
+ // Now sort the simplices. That will make identical ones reside side by side in the list
+ simplices.Sort();
+
+ // Look for duplicate simplices here.
+ // Remember, they are directly side by side in the list right now,
+ // So we only check directly neighbours
+ int iSimplex;
+ List innerSimplices = new List();
+ for (iSimplex = 1; iSimplex < simplices.Count; iSimplex++) // Startindex=1, so we can refer backwards
+ {
+ if (simplices[iSimplex - 1].CompareTo(simplices[iSimplex]) == 0)
+ {
+ innerSimplices.Add(simplices[iSimplex - 1]);
+ innerSimplices.Add(simplices[iSimplex]);
+ }
+ }
+
+ foreach (Simplex s in innerSimplices)
+ {
+ simplices.Remove(s);
+ }
+
+ // each simplex still in the list belongs to the hull of the region in question
+ // The new vertex (yes, we still deal with verices here :-) ) forms a triangle
+ // with each of these simplices. Build the new triangles and add them to the list
+ foreach (Simplex s in simplices)
+ {
+ Triangle t = new Triangle(s.v1, s.v2, vertices[iCurrentVertex]);
+ if (!t.isDegraded())
+ {
+ triangles.Add(t);
+ }
+ }
+ }
+
+ }
+
+
+ static Mesh CreateBoxMesh(String primName, PrimitiveBaseShape primShape, PhysicsVector size)
+ // Builds the z (+ and -) surfaces of a box shaped prim
+ {
+ UInt16 hollowFactor = primShape.ProfileHollow;
+ UInt16 profileBegin = primShape.ProfileBegin;
+ UInt16 profileEnd = primShape.ProfileEnd;
+
+ // Procedure: This is based on the fact that the upper (plus) and lower (minus) Z-surface
+ // of a block are basically the same
+ // They may be warped differently but the shape is identical
+ // So we only create one surface as a model and derive both plus and minus surface of the block from it
+ // This is done in a model space where the block spans from -.5 to +.5 in X and Y
+ // The mapping to Scene space is done later during the "extrusion" phase
+
+ // Base
+ Vertex MM = new Vertex(-0.5f, -0.5f, 0.0f);
+ Vertex PM = new Vertex(+0.5f, -0.5f, 0.0f);
+ Vertex MP = new Vertex(-0.5f, +0.5f, 0.0f);
+ Vertex PP = new Vertex(+0.5f, +0.5f, 0.0f);
+
+ Meshing.SimpleHull outerHull = new SimpleHull();
+ outerHull.AddVertex(MM);
+ outerHull.AddVertex(PM);
+ outerHull.AddVertex(PP);
+ outerHull.AddVertex(MP);
+
+ // Deal with cuts now
+ if ((profileBegin != 0) || (profileEnd != 0))
+ {
+ double fProfileBeginAngle = profileBegin / 50000.0 * 360.0; // In degree, for easier debugging and understanding
+ fProfileBeginAngle -= (90.0 + 45.0); // for some reasons, the SL client counts from the corner -X/-Y
+ double fProfileEndAngle = 360.0 - profileEnd / 50000.0 * 360.0; // Pathend comes as complement to 1.0
+ fProfileEndAngle -= (90.0 + 45.0);
+ if (fProfileBeginAngle < fProfileEndAngle)
+ fProfileEndAngle -= 360.0;
+
+ // Note, that we don't want to cut out a triangle, even if this is a
+ // good approximation for small cuts. Indeed we want to cut out an arc
+ // and we approximate this arc by a polygon chain
+ // Also note, that these vectors are of length 1.0 and thus their endpoints lay outside the model space
+ // So it can easily be subtracted from the outer hull
+ int iSteps = (int)(((fProfileBeginAngle - fProfileEndAngle) / 45.0) + .5); // how many steps do we need with approximately 45 degree
+ double dStepWidth=(fProfileBeginAngle-fProfileEndAngle)/iSteps;
+
+ Vertex origin = new Vertex(0.0f, 0.0f, 0.0f);
+
+ // Note the sequence of vertices here. It's important to have the other rotational sense than in outerHull
+ SimpleHull cutHull = new SimpleHull();
+ cutHull.AddVertex(origin);
+ for (int i=0; i 0)
+ {
+ float hollowFactorF = (float) hollowFactor/(float) 50000;
+ Vertex IMM = new Vertex(-0.5f * hollowFactorF, -0.5f * hollowFactorF, 0.0f);
+ Vertex IPM = new Vertex(+0.5f * hollowFactorF, -0.5f * hollowFactorF, 0.0f);
+ Vertex IMP = new Vertex(-0.5f * hollowFactorF, +0.5f * hollowFactorF, 0.0f);
+ Vertex IPP = new Vertex(+0.5f * hollowFactorF, +0.5f * hollowFactorF, 0.0f);
+
+ SimpleHull holeHull = new SimpleHull();
+
+ holeHull.AddVertex(IMM);
+ holeHull.AddVertex(IMP);
+ holeHull.AddVertex(IPP);
+ holeHull.AddVertex(IPM);
+
+ SimpleHull hollowedHull = SimpleHull.SubtractHull(outerHull, holeHull);
+
+ outerHull = hollowedHull;
+
+ }
+
+ Mesh m = new Mesh();
+
+ Vertex Seed1 = new Vertex(0.0f, -10.0f, 0.0f);
+ Vertex Seed2 = new Vertex(-10.0f, 10.0f, 0.0f);
+ Vertex Seed3 = new Vertex(10.0f, 10.0f, 0.0f);
+
+ m.Add(Seed1);
+ m.Add(Seed2);
+ m.Add(Seed3);
+
+ m.Add(new Triangle(Seed1, Seed2, Seed3));
+ m.Add(outerHull.getVertices());
+
+ InsertVertices(m.vertices, 3, m.triangles);
+ m.DumpRaw(baseDir, primName, "Proto first Mesh");
+
+ m.Remove(Seed1);
+ m.Remove(Seed2);
+ m.Remove(Seed3);
+ m.DumpRaw(baseDir, primName, "Proto seeds removed");
+
+ m.RemoveTrianglesOutside(outerHull);
+ m.DumpRaw(baseDir, primName, "Proto outsides removed");
+
+ foreach (Triangle t in m.triangles)
+ {
+ PhysicsVector n = t.getNormal();
+ if (n.Z < 0.0)
+ t.invertNormal();
+ }
+
+ Extruder extr = new Extruder();
+
+ extr.size = size;
+
+ Mesh result = extr.Extrude(m);
+ result.DumpRaw(baseDir, primName, "Z extruded");
+ return result;
+ }
+
+ public static void CalcNormals(Mesh mesh)
+ {
+ int iTriangles = mesh.triangles.Count;
+
+ mesh.normals = new float[iTriangles*3];
+
+ int i = 0;
+ foreach (Triangle t in mesh.triangles)
+ {
+ float ux, uy, uz;
+ float vx, vy, vz;
+ float wx, wy, wz;
+
+ ux = t.v1.X;
+ uy = t.v1.Y;
+ uz = t.v1.Z;
+
+ vx = t.v2.X;
+ vy = t.v2.Y;
+ vz = t.v2.Z;
+
+ wx = t.v3.X;
+ wy = t.v3.Y;
+ wz = t.v3.Z;
+
+
+ // Vectors for edges
+ float e1x, e1y, e1z;
+ float e2x, e2y, e2z;
+
+ e1x = ux - vx;
+ e1y = uy - vy;
+ e1z = uz - vz;
+
+ e2x = ux - wx;
+ e2y = uy - wy;
+ e2z = uz - wz;
+
+
+ // Cross product for normal
+ float nx, ny, nz;
+ nx = e1y*e2z - e1z*e2y;
+ ny = e1z*e2x - e1x*e2z;
+ nz = e1x*e2y - e1y*e2x;
+
+ // Length
+ float l = (float) Math.Sqrt(nx*nx + ny*ny + nz*nz);
+
+ // Normalized "normal"
+ nx /= l;
+ ny /= l;
+ nz /= l;
+
+ mesh.normals[i] = nx;
+ mesh.normals[i + 1] = ny;
+ mesh.normals[i + 2] = nz;
+
+ i += 3;
+ }
+ }
+
+ public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, PhysicsVector size)
+ {
+ Mesh mesh = null;
+
+ switch (primShape.ProfileShape)
+ {
+ case ProfileShape.Square:
+ mesh=CreateBoxMesh(primName, primShape, size);
+ CalcNormals(mesh);
+ break;
+ default:
+ mesh = CreateBoxMesh(primName, primShape, size);
+ CalcNormals(mesh);
+ //Set default mesh to cube otherwise it'll return
+ // null and crash on the 'setMesh' method in the physics plugins.
+ //mesh = null;
+ break;
+ }
+
+ return mesh;
+ }
+ }
+
+}
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 @@
-using System;
-using System.Collections.Generic;
-using System.Text;
-
-using OpenSim.Framework.Console;
-
-namespace OpenSim.Region.Physics.Meshing
-{
- // A simple hull is a set of vertices building up to simplices that border a region
- // The word simple referes to the fact, that this class assumes, that all simplices
- // do not intersect
- // Simple hulls can be added and subtracted.
- // Vertices can be checked to lie inside a hull
- // Also note, that the sequence of the vertices is important and defines if the region that
- // is defined by the hull lies inside or outside the simplex chain
- public class SimpleHull
- {
- List vertices = new List();
- List holeVertices = new List(); // Only used, when the hull is hollow
-
- // Adds a vertex to the end of the list
- public void AddVertex(Vertex v) {
- vertices.Add(v);
- }
-
- override public String ToString()
- {
- String result="";
- foreach (Vertex v in vertices)
- {
- result += "b:" + v.ToString() + "\n";
- }
-
- return result;
- }
-
-
- public List getVertices() {
- List newVertices = new List();
-
- newVertices.AddRange(vertices);
- newVertices.Add(null);
- newVertices.AddRange(holeVertices);
-
- return newVertices;
- }
-
- public SimpleHull Clone()
- {
- SimpleHull result = new SimpleHull();
- foreach (Vertex v in vertices)
- {
- result.AddVertex(v.Clone());
- }
-
- foreach (Vertex v in this.holeVertices)
- {
- result.holeVertices.Add(v.Clone());
- }
-
- return result;
- }
-
- public bool IsPointIn(Vertex v1)
- {
- int iCounter=0;
- List simplices=buildSimplexList();
- foreach (Simplex s in simplices)
- {
- // Send a ray along the positive X-Direction
- // Note, that this direction must correlate with the "below" interpretation
- // of handling for the special cases below
- Manager.PhysicsVector intersection = s.RayIntersect(v1, new Manager.PhysicsVector(1.0f, 0.0f, 0.0f), true);
-
- if (intersection == null)
- continue; // No intersection. Done. More tests to follow otherwise
-
- // Did we hit the end of a simplex?
- // Then this can be one of two special cases:
- // 1. we go through a border exactly at a joint
- // 2. we have just marginally touched a corner
- // 3. we can slide along a border
- // Solution: If the other vertex is "below" the ray, we don't count it
- // Thus corners pointing down are counted twice, corners pointing up are not counted
- // borders are counted once
- if (intersection.IsIdentical(s.v1, 0.001f)) {
- if (s.v2.Y < v1.Y)
- continue;
- }
- // Do this for the other vertex two
- if (intersection.IsIdentical(s.v2, 0.001f)) {
- if (s.v1.Y buildSimplexList() {
-
- List result = new List();
-
- // Not asserted but assumed: at least three vertices
- for (int i=0; i simple = buildSimplexList();
- foreach (Simplex sTest in simple)
- {
- Manager.PhysicsVector vvTemp = Simplex.Intersect(sTest, s, -.001f, -.001f, 0.999f, .999f);
-
- Vertex vTemp=null;
- if (vvTemp != null)
- vTemp = new Vertex(vvTemp);
-
- if (vTemp!=null) {
-
- Manager.PhysicsVector diff=(s.v1-vTemp);
- float distTemp=diff.length();
-
- if (bestIntersection==null || distTemp vertices = new List();
+ List holeVertices = new List(); // Only used, when the hull is hollow
+
+ // Adds a vertex to the end of the list
+ public void AddVertex(Vertex v) {
+ vertices.Add(v);
+ }
+
+ override public String ToString()
+ {
+ String result="";
+ foreach (Vertex v in vertices)
+ {
+ result += "b:" + v.ToString() + "\n";
+ }
+
+ return result;
+ }
+
+
+ public List getVertices() {
+ List newVertices = new List();
+
+ newVertices.AddRange(vertices);
+ newVertices.Add(null);
+ newVertices.AddRange(holeVertices);
+
+ return newVertices;
+ }
+
+ public SimpleHull Clone()
+ {
+ SimpleHull result = new SimpleHull();
+ foreach (Vertex v in vertices)
+ {
+ result.AddVertex(v.Clone());
+ }
+
+ foreach (Vertex v in this.holeVertices)
+ {
+ result.holeVertices.Add(v.Clone());
+ }
+
+ return result;
+ }
+
+ public bool IsPointIn(Vertex v1)
+ {
+ int iCounter=0;
+ List simplices=buildSimplexList();
+ foreach (Simplex s in simplices)
+ {
+ // Send a ray along the positive X-Direction
+ // Note, that this direction must correlate with the "below" interpretation
+ // of handling for the special cases below
+ Manager.PhysicsVector intersection = s.RayIntersect(v1, new Manager.PhysicsVector(1.0f, 0.0f, 0.0f), true);
+
+ if (intersection == null)
+ continue; // No intersection. Done. More tests to follow otherwise
+
+ // Did we hit the end of a simplex?
+ // Then this can be one of two special cases:
+ // 1. we go through a border exactly at a joint
+ // 2. we have just marginally touched a corner
+ // 3. we can slide along a border
+ // Solution: If the other vertex is "below" the ray, we don't count it
+ // Thus corners pointing down are counted twice, corners pointing up are not counted
+ // borders are counted once
+ if (intersection.IsIdentical(s.v1, 0.001f)) {
+ if (s.v2.Y < v1.Y)
+ continue;
+ }
+ // Do this for the other vertex two
+ if (intersection.IsIdentical(s.v2, 0.001f)) {
+ if (s.v1.Y buildSimplexList() {
+
+ List result = new List();
+
+ // Not asserted but assumed: at least three vertices
+ for (int i=0; i simple = buildSimplexList();
+ foreach (Simplex sTest in simple)
+ {
+ Manager.PhysicsVector vvTemp = Simplex.Intersect(sTest, s, -.001f, -.001f, 0.999f, .999f);
+
+ Vertex vTemp=null;
+ if (vvTemp != null)
+ vTemp = new Vertex(vvTemp);
+
+ if (vTemp!=null) {
+
+ Manager.PhysicsVector diff=(s.v1-vTemp);
+ float distTemp=diff.length();
+
+ if (bestIntersection==null || distTemp
- {
- public Vertex v1;
- public Vertex v2;
-
- public Simplex(Vertex _v1, Vertex _v2)
- {
- v1 = _v1;
- v2 = _v2;
- }
-
- public int CompareTo(Simplex other)
- {
-
- Vertex lv1, lv2, ov1, ov2, temp;
-
- lv1 = v1;
- lv2 = v2;
- ov1 = other.v1;
- ov2 = other.v2;
-
- if (lv1 > lv2)
- {
- temp = lv1;
- lv1 = lv2;
- lv2 = temp;
- }
-
- if (ov1 > ov2)
- {
- temp = ov1;
- ov1 = ov2;
- ov2 = temp;
- }
-
- if (lv1 > ov1)
- {
- return 1;
- }
- if (lv1 < ov1)
- {
- return -1;
- }
-
- if (lv2 > ov2)
- {
- return 1;
- }
- if (lv2 < ov2)
- {
- return -1;
- }
-
- return 0;
- }
-
- private static void intersectParameter(PhysicsVector p1, PhysicsVector r1, PhysicsVector p2, PhysicsVector r2, ref float lambda, ref float mu)
- {
- // Intersects two straights
- // p1, p2, points on the straight
- // r1, r2, directional vectors of the straight. Not necessarily of length 1!
- // note, that l, m can be scaled such, that the range 0..1 is mapped to the area between two points,
- // thus allowing to decide whether an intersection is between two points
-
- float r1x = r1.X;
- float r1y = r1.Y;
- float r2x = r2.X;
- float r2y = r2.Y;
-
- float denom = r1y*r2x - r1x*r2y;
-
- float p1x = p1.X;
- float p1y = p1.Y;
- float p2x = p2.X;
- float p2y = p2.Y;
-
- float z1=-p2x * r2y + p1x * r2y + (p2y - p1y) * r2x;
- float z2=-p2x * r1y + p1x * r1y + (p2y - p1y) * r1x;
-
- if (denom == 0.0f) // Means the straights are parallel. Either no intersection or an infinite number of them
- {
- if (z1==0.0f) {// Means they are identical -> many, many intersections
- lambda = Single.NaN;
- mu = Single.NaN;
- } else {
- lambda = Single.PositiveInfinity;
- mu = Single.PositiveInfinity;
- }
- return;
-
- }
-
-
-
- lambda = z1 / denom;
- mu = z2 / denom;
-
- }
-
-
- // Intersects the simplex with another one.
- // the borders are used to deal with float inaccuracies
- // As a rule of thumb, the borders are
- // lowerBorder1 : 0.0
- // lowerBorder2 : 0.0
- // upperBorder1 : 1.0
- // upperBorder2 : 1.0
- // Set these to values near the given parameters (e.g. 0.001 instead of 1 to exclude simplex starts safely, or to -0.001 to include them safely)
- public static PhysicsVector Intersect(
- Simplex s1,
- Simplex s2,
- float lowerBorder1,
- float lowerBorder2,
- float upperBorder1,
- float upperBorder2)
- {
- PhysicsVector firstSimplexDirection = s1.v2 - s1.v1;
- PhysicsVector secondSimplexDirection = s2.v2 - s2.v1;
-
- float lambda = 0.0f;
- float mu = 0.0f;
-
- // Give us the parameters of an intersection. This subroutine does *not* take the constraints
- // (intersection must be between v1 and v2 and it must be in the positive direction of the ray)
- // into account. We do that afterwards.
- intersectParameter(s1.v1, firstSimplexDirection, s2.v1, secondSimplexDirection, ref lambda, ref mu);
-
- if (Single.IsInfinity(lambda)) // Special case. No intersection at all. directions parallel.
- return null;
-
- if (Single.IsNaN(lambda)) // Special case. many, many intersections.
- return null;
-
- if (lambda > upperBorder1) // We're behind v2
- return null;
-
- if (lambda < lowerBorder1)
- return null;
-
- if (mu < lowerBorder2) // outside simplex 2
- return null;
-
- if (mu > upperBorder2) // outside simplex 2
- return null;
-
- return s1.v1 + lambda * firstSimplexDirection;
-
- }
-
- // Intersects the simplex with a ray. The ray is defined as all p=origin + lambda*direction
- // where lambda >= 0
- public PhysicsVector RayIntersect(Vertex origin, PhysicsVector direction, bool bEndsIncluded)
- {
- PhysicsVector simplexDirection = v2 - v1;
-
- float lambda = 0.0f;
- float mu = 0.0f;
-
- // Give us the parameters of an intersection. This subroutine does *not* take the constraints
- // (intersection must be between v1 and v2 and it must be in the positive direction of the ray)
- // into account. We do that afterwards.
- intersectParameter(v1, simplexDirection, origin, direction, ref lambda, ref mu);
-
- if (Single.IsInfinity(lambda)) // Special case. No intersection at all. directions parallel.
- return null;
-
- if (Single.IsNaN(lambda)) // Special case. many, many intersections.
- return null;
-
- if (mu < 0.0) // We're on the wrong side of the ray
- return null;
-
- if (lambda > 1.0) // We're behind v2
- return null;
-
- if (lambda == 1.0 && !bEndsIncluded)
- return null; // The end of the simplices are not included
-
- if (lambda < 0.0f) // we're before v1;
- return null;
-
- return this.v1 + lambda * simplexDirection;
-
- }
-
-
- }
+using System;
+using System.Collections.Generic;
+using System.Text;
+using OpenSim.Region.Physics.Manager;
+
+namespace OpenSim.Region.Physics.Meshing
+{
+ // A simplex is a section of a straight line.
+ // It is defined by its endpoints, i.e. by two vertices
+ // Operation on vertices are
+ public class Simplex : IComparable
+ {
+ public Vertex v1;
+ public Vertex v2;
+
+ public Simplex(Vertex _v1, Vertex _v2)
+ {
+ v1 = _v1;
+ v2 = _v2;
+ }
+
+ public int CompareTo(Simplex other)
+ {
+
+ Vertex lv1, lv2, ov1, ov2, temp;
+
+ lv1 = v1;
+ lv2 = v2;
+ ov1 = other.v1;
+ ov2 = other.v2;
+
+ if (lv1 > lv2)
+ {
+ temp = lv1;
+ lv1 = lv2;
+ lv2 = temp;
+ }
+
+ if (ov1 > ov2)
+ {
+ temp = ov1;
+ ov1 = ov2;
+ ov2 = temp;
+ }
+
+ if (lv1 > ov1)
+ {
+ return 1;
+ }
+ if (lv1 < ov1)
+ {
+ return -1;
+ }
+
+ if (lv2 > ov2)
+ {
+ return 1;
+ }
+ if (lv2 < ov2)
+ {
+ return -1;
+ }
+
+ return 0;
+ }
+
+ private static void intersectParameter(PhysicsVector p1, PhysicsVector r1, PhysicsVector p2, PhysicsVector r2, ref float lambda, ref float mu)
+ {
+ // Intersects two straights
+ // p1, p2, points on the straight
+ // r1, r2, directional vectors of the straight. Not necessarily of length 1!
+ // note, that l, m can be scaled such, that the range 0..1 is mapped to the area between two points,
+ // thus allowing to decide whether an intersection is between two points
+
+ float r1x = r1.X;
+ float r1y = r1.Y;
+ float r2x = r2.X;
+ float r2y = r2.Y;
+
+ float denom = r1y*r2x - r1x*r2y;
+
+ float p1x = p1.X;
+ float p1y = p1.Y;
+ float p2x = p2.X;
+ float p2y = p2.Y;
+
+ float z1=-p2x * r2y + p1x * r2y + (p2y - p1y) * r2x;
+ float z2=-p2x * r1y + p1x * r1y + (p2y - p1y) * r1x;
+
+ if (denom == 0.0f) // Means the straights are parallel. Either no intersection or an infinite number of them
+ {
+ if (z1==0.0f) {// Means they are identical -> many, many intersections
+ lambda = Single.NaN;
+ mu = Single.NaN;
+ } else {
+ lambda = Single.PositiveInfinity;
+ mu = Single.PositiveInfinity;
+ }
+ return;
+
+ }
+
+
+
+ lambda = z1 / denom;
+ mu = z2 / denom;
+
+ }
+
+
+ // Intersects the simplex with another one.
+ // the borders are used to deal with float inaccuracies
+ // As a rule of thumb, the borders are
+ // lowerBorder1 : 0.0
+ // lowerBorder2 : 0.0
+ // upperBorder1 : 1.0
+ // upperBorder2 : 1.0
+ // Set these to values near the given parameters (e.g. 0.001 instead of 1 to exclude simplex starts safely, or to -0.001 to include them safely)
+ public static PhysicsVector Intersect(
+ Simplex s1,
+ Simplex s2,
+ float lowerBorder1,
+ float lowerBorder2,
+ float upperBorder1,
+ float upperBorder2)
+ {
+ PhysicsVector firstSimplexDirection = s1.v2 - s1.v1;
+ PhysicsVector secondSimplexDirection = s2.v2 - s2.v1;
+
+ float lambda = 0.0f;
+ float mu = 0.0f;
+
+ // Give us the parameters of an intersection. This subroutine does *not* take the constraints
+ // (intersection must be between v1 and v2 and it must be in the positive direction of the ray)
+ // into account. We do that afterwards.
+ intersectParameter(s1.v1, firstSimplexDirection, s2.v1, secondSimplexDirection, ref lambda, ref mu);
+
+ if (Single.IsInfinity(lambda)) // Special case. No intersection at all. directions parallel.
+ return null;
+
+ if (Single.IsNaN(lambda)) // Special case. many, many intersections.
+ return null;
+
+ if (lambda > upperBorder1) // We're behind v2
+ return null;
+
+ if (lambda < lowerBorder1)
+ return null;
+
+ if (mu < lowerBorder2) // outside simplex 2
+ return null;
+
+ if (mu > upperBorder2) // outside simplex 2
+ return null;
+
+ return s1.v1 + lambda * firstSimplexDirection;
+
+ }
+
+ // Intersects the simplex with a ray. The ray is defined as all p=origin + lambda*direction
+ // where lambda >= 0
+ public PhysicsVector RayIntersect(Vertex origin, PhysicsVector direction, bool bEndsIncluded)
+ {
+ PhysicsVector simplexDirection = v2 - v1;
+
+ float lambda = 0.0f;
+ float mu = 0.0f;
+
+ // Give us the parameters of an intersection. This subroutine does *not* take the constraints
+ // (intersection must be between v1 and v2 and it must be in the positive direction of the ray)
+ // into account. We do that afterwards.
+ intersectParameter(v1, simplexDirection, origin, direction, ref lambda, ref mu);
+
+ if (Single.IsInfinity(lambda)) // Special case. No intersection at all. directions parallel.
+ return null;
+
+ if (Single.IsNaN(lambda)) // Special case. many, many intersections.
+ return null;
+
+ if (mu < 0.0) // We're on the wrong side of the ray
+ return null;
+
+ if (lambda > 1.0) // We're behind v2
+ return null;
+
+ if (lambda == 1.0 && !bEndsIncluded)
+ return null; // The end of the simplices are not included
+
+ if (lambda < 0.0f) // we're before v1;
+ return null;
+
+ return this.v1 + lambda * simplexDirection;
+
+ }
+
+
+ }
}
\ No newline at end of file
--
cgit v1.1