diff --git a/OpenSim/Region/Physics/Meshing/Extruder.cs b/OpenSim/Region/Physics/Meshing/Extruder.cs
deleted file mode 100644
index 1fc65e3fd6..0000000000
--- a/OpenSim/Region/Physics/Meshing/Extruder.cs
+++ /dev/null
@@ -1,472 +0,0 @@
-/*
- * 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.
- */
-//#define SPAM
-
-using OpenMetaverse;
-using OpenSim.Region.Physics.Manager;
-
-namespace OpenSim.Region.Physics.Meshing
-{
- internal class Extruder
- {
- //public float startParameter;
- //public float stopParameter;
- public PhysicsVector size;
-
- public float taperTopFactorX = 1f;
- public float taperTopFactorY = 1f;
- public float taperBotFactorX = 1f;
- public float taperBotFactorY = 1f;
-
- public float pushX = 0f;
- public float pushY = 0f;
-
- // twist amount in radians. NOT DEGREES.
- public float twistTop = 0;
- public float twistBot = 0;
- public float twistMid = 0;
- public float pathScaleX = 1.0f;
- public float pathScaleY = 0.5f;
- public float skew = 0.0f;
- public float radius = 0.0f;
- public float revolutions = 1.0f;
-
- public float pathCutBegin = 0.0f;
- public float pathCutEnd = 1.0f;
-
- public ushort pathBegin = 0;
- public ushort pathEnd = 0;
-
- public float pathTaperX = 0.0f;
- public float pathTaperY = 0.0f;
-
- ///
- /// Creates an extrusion of a profile along a linear path. Used to create prim types box, cylinder, and prism.
- ///
- ///
- /// A mesh of the extruded shape
- public Mesh ExtrudeLinearPath(Mesh m)
- {
- Mesh result = new Mesh();
-
- Mesh newLayer;
- Mesh lastLayer = null;
-
- int step = 0;
- int steps = 1;
-
- float twistTotal = twistTop - twistBot;
- // if the profile has a lot of twist, add more layers otherwise the layers may overlap
- // and the resulting mesh may be quite inaccurate. This method is arbitrary and may not
- // accurately match the viewer
- float twistTotalAbs = System.Math.Abs(twistTotal);
- if (twistTotalAbs > 0.01)
- steps += (int)(twistTotalAbs * 3.66f); // dahlia's magic number ;)
-
-#if SPAM
- System.Console.WriteLine("ExtrudeLinearPath: twistTotalAbs: " + twistTotalAbs.ToString() + " steps: " + steps.ToString());
-#endif
-
- double percentOfPathMultiplier = 1.0 / steps;
-
- float start = -0.5f;
-
- float stepSize = 1.0f / (float)steps;
-
- float xProfileScale = 1.0f;
- float yProfileScale = 1.0f;
-
- float xOffset = 0.0f;
- float yOffset = 0.0f;
- float zOffset = start;
-
- float xOffsetStepIncrement = pushX / steps;
- float yOffsetStepIncrement = pushY / steps;
-
-#if SPAM
- System.Console.WriteLine("Extruder: twistTop: " + twistTop.ToString() + " twistbot: " + twistBot.ToString() + " twisttotal: " + twistTotal.ToString());
- System.Console.WriteLine("Extruder: taperBotFactorX: " + taperBotFactorX.ToString() + " taperBotFactorY: " + taperBotFactorY.ToString()
- + " taperTopFactorX: " + taperTopFactorX.ToString() + " taperTopFactorY: " + taperTopFactorY.ToString());
- System.Console.WriteLine("Extruder: PathScaleX: " + pathScaleX.ToString() + " pathScaleY: " + pathScaleY.ToString());
-#endif
-
- //float percentOfPath = 0.0f;
- float percentOfPath = (float)pathBegin * 2.0e-5f;
- zOffset += percentOfPath;
- bool done = false;
- do // loop through the length of the path and add the layers
- {
- newLayer = m.Clone();
-
- if (taperBotFactorX < 1.0f)
- xProfileScale = 1.0f - (1.0f - percentOfPath) * (1.0f - taperBotFactorX);
- else if (taperTopFactorX < 1.0f)
- xProfileScale = 1.0f - percentOfPath * (1.0f - taperTopFactorX);
- else xProfileScale = 1.0f;
-
- if (taperBotFactorY < 1.0f)
- yProfileScale = 1.0f - (1.0f - percentOfPath) * (1.0f - taperBotFactorY);
- else if (taperTopFactorY < 1.0f)
- yProfileScale = 1.0f - percentOfPath * (1.0f - taperTopFactorY);
- else yProfileScale = 1.0f;
-
-#if SPAM
- //System.Console.WriteLine("xProfileScale: " + xProfileScale.ToString() + " yProfileScale: " + yProfileScale.ToString());
-#endif
- Vertex vTemp = new Vertex(0.0f, 0.0f, 0.0f);
-
- // apply the taper to the profile before any rotations
- if (xProfileScale != 1.0f || yProfileScale != 1.0f)
- {
- foreach (Vertex v in newLayer.vertices)
- {
- if (v != null)
- {
- v.X *= xProfileScale;
- v.Y *= yProfileScale;
- }
- }
- }
-
-
- float twist = twistBot + (twistTotal * (float)percentOfPath);
-#if SPAM
- System.Console.WriteLine("Extruder: percentOfPath: " + percentOfPath.ToString() + " zOffset: " + zOffset.ToString()
- + " xProfileScale: " + xProfileScale.ToString() + " yProfileScale: " + yProfileScale.ToString());
-#endif
-
- // apply twist rotation to the profile layer and position the layer in the prim
-
- Quaternion profileRot = Quaternion.CreateFromAxisAngle(new Vector3(0.0f, 0.0f, 1.0f), twist);
- foreach (Vertex v in newLayer.vertices)
- {
- if (v != null)
- {
- vTemp = v * profileRot;
- v.X = vTemp.X + xOffset;
- v.Y = vTemp.Y + yOffset;
- v.Z = vTemp.Z + zOffset;
- }
- }
-
- if (step == 0) // the first layer, invert normals
- {
- foreach (Triangle t in newLayer.triangles)
- {
- t.invertNormal();
- }
- }
-
- result.Append(newLayer);
-
- int iLastNull = 0;
-
- if (lastLayer != null)
- {
- int i, count = newLayer.vertices.Count;
-
- for (i = 0; i < count; i++)
- {
- int iNext = (i + 1);
-
- if (lastLayer.vertices[i] == null) // cant make a simplex here
- {
- iLastNull = i + 1;
- }
- else
- {
- if (i == count - 1) // End of list
- iNext = iLastNull;
-
- if (lastLayer.vertices[iNext] == null) // Null means wrap to begin of last segment
- iNext = iLastNull;
-
- result.Add(new Triangle(newLayer.vertices[i], lastLayer.vertices[i], newLayer.vertices[iNext]));
- result.Add(new Triangle(newLayer.vertices[iNext], lastLayer.vertices[i], lastLayer.vertices[iNext]));
- }
- }
- }
- lastLayer = newLayer;
-
- // calc the step for the next interation of the loop
-
- if (step < steps)
- {
- step++;
- percentOfPath += (float)percentOfPathMultiplier;
-
- xOffset += xOffsetStepIncrement;
- yOffset += yOffsetStepIncrement;
- zOffset += stepSize;
-
- if (percentOfPath > 1.0f - (float)pathEnd * 2.0e-5f)
- done = true;
- }
- else done = true;
-
- } while (!done); // loop until all the layers in the path are completed
-
- // scale the mesh to the desired size
- float xScale = size.X;
- float yScale = size.Y;
- float zScale = size.Z;
-
- foreach (Vertex v in result.vertices)
- {
- if (v != null)
- {
- v.X *= xScale;
- v.Y *= yScale;
- v.Z *= zScale;
- }
- }
-
- return result;
- }
-
- ///
- /// Extrudes a shape around a circular path. Used to create prim types torus, ring, and tube.
- ///
- ///
- /// a mesh of the extruded shape
- public Mesh ExtrudeCircularPath(Mesh m)
- {
- Mesh result = new Mesh();
-
- Mesh newLayer;
- Mesh lastLayer = null;
-
- int step;
- int steps = 24;
-
- float twistTotal = twistTop - twistBot;
- // if the profile has a lot of twist, add more layers otherwise the layers may overlap
- // and the resulting mesh may be quite inaccurate. This method is arbitrary and doesn't
- // accurately match the viewer
- if (System.Math.Abs(twistTotal) > (float)System.Math.PI * 1.5f) steps *= 2;
- if (System.Math.Abs(twistTotal) > (float)System.Math.PI * 3.0f) steps *= 2;
-
- // double percentOfPathMultiplier = 1.0 / steps;
- // double angleStepMultiplier = System.Math.PI * 2.0 / steps;
-
- float yPathScale = pathScaleY * 0.5f;
- float pathLength = pathCutEnd - pathCutBegin;
- float totalSkew = skew * 2.0f * pathLength;
- float skewStart = (-skew) + pathCutBegin * 2.0f * skew;
-
- // It's not quite clear what pushY (Y top shear) does, but subtracting it from the start and end
- // angles appears to approximate it's effects on path cut. Likewise, adding it to the angle used
- // to calculate the sine for generating the path radius appears to approximate it's effects there
- // too, but there are some subtle differences in the radius which are noticeable as the prim size
- // increases and it may affect megaprims quite a bit. The effect of the Y top shear parameter on
- // the meshes generated with this technique appear nearly identical in shape to the same prims when
- // displayed by the viewer.
-
-
- float startAngle = (float)(System.Math.PI * 2.0 * pathCutBegin * revolutions) - pushY * 0.9f;
- float endAngle = (float)(System.Math.PI * 2.0 * pathCutEnd * revolutions) - pushY * 0.9f;
- float stepSize = (float)0.2617993878; // 2*PI / 24 segments per revolution
-
- step = (int)(startAngle / stepSize);
- float angle = startAngle;
-
- float xProfileScale = 1.0f;
- float yProfileScale = 1.0f;
-
-
-#if SPAM
- System.Console.WriteLine("Extruder: twistTop: " + twistTop.ToString() + " twistbot: " + twistBot.ToString() + " twisttotal: " + twistTotal.ToString());
- System.Console.WriteLine("Extruder: startAngle: " + startAngle.ToString() + " endAngle: " + endAngle.ToString() + " step: " + step.ToString());
- System.Console.WriteLine("Extruder: taperBotFactorX: " + taperBotFactorX.ToString() + " taperBotFactorY: " + taperBotFactorY.ToString()
- + " taperTopFactorX: " + taperTopFactorX.ToString() + " taperTopFactorY: " + taperTopFactorY.ToString());
- System.Console.WriteLine("Extruder: PathScaleX: " + pathScaleX.ToString() + " pathScaleY: " + pathScaleY.ToString());
-#endif
-
- bool done = false;
- do // loop through the length of the path and add the layers
- {
- newLayer = m.Clone();
-
- float percentOfPath = (angle - startAngle) / (endAngle - startAngle); // endAngle should always be larger than startAngle
-
- if (pathTaperX > 0.001f) // can't really compare to 0.0f as the value passed is never exactly zero
- xProfileScale = 1.0f - percentOfPath * pathTaperX;
- else if (pathTaperX < -0.001f)
- xProfileScale = 1.0f + (1.0f - percentOfPath) * pathTaperX;
- else xProfileScale = 1.0f;
-
- if (pathTaperY > 0.001f)
- yProfileScale = 1.0f - percentOfPath * pathTaperY;
- else if (pathTaperY < -0.001f)
- yProfileScale = 1.0f + (1.0f - percentOfPath) * pathTaperY;
- else yProfileScale = 1.0f;
-
-#if SPAM
- //System.Console.WriteLine("xProfileScale: " + xProfileScale.ToString() + " yProfileScale: " + yProfileScale.ToString());
-#endif
- Vertex vTemp = new Vertex(0.0f, 0.0f, 0.0f);
-
- // apply the taper to the profile before any rotations
- if (xProfileScale != 1.0f || yProfileScale != 1.0f)
- {
- foreach (Vertex v in newLayer.vertices)
- {
- if (v != null)
- {
- v.X *= xProfileScale;
- v.Y *= yProfileScale;
- }
- }
- }
-
- float radiusScale;
-
- if (radius > 0.001f)
- radiusScale = 1.0f - radius * percentOfPath;
- else if (radius < 0.001f)
- radiusScale = 1.0f + radius * (1.0f - percentOfPath);
- else
- radiusScale = 1.0f;
-
-#if SPAM
- System.Console.WriteLine("Extruder: angle: " + angle.ToString() + " percentOfPath: " + percentOfPath.ToString()
- + " radius: " + radius.ToString() + " radiusScale: " + radiusScale.ToString()
- + " xProfileScale: " + xProfileScale.ToString() + " yProfileScale: " + yProfileScale.ToString());
-#endif
-
- float twist = twistBot + (twistTotal * (float)percentOfPath);
-
- float xOffset;
- float yOffset;
- float zOffset;
-
- xOffset = 0.5f * (skewStart + totalSkew * (float)percentOfPath);
- xOffset += (float) System.Math.Sin(angle) * pushX * 0.45f;
- yOffset = (float)(System.Math.Cos(angle) * (0.5f - yPathScale)) * radiusScale;
- zOffset = (float)(System.Math.Sin(angle + pushY * 0.9f) * (0.5f - yPathScale)) * radiusScale;
-
- // next apply twist rotation to the profile layer
- if (twistTotal != 0.0f || twistBot != 0.0f)
- {
- Quaternion profileRot = new Quaternion(new Vector3(0.0f, 0.0f, 1.0f), twist);
- foreach (Vertex v in newLayer.vertices)
- {
- if (v != null)
- {
- vTemp = v * profileRot;
- v.X = vTemp.X;
- v.Y = vTemp.Y;
- v.Z = vTemp.Z;
- }
- }
- }
-
- // now orient the rotation of the profile layer relative to it's position on the path
- // adding pushY to the angle used to generate the quat appears to approximate the viewer
- Quaternion layerRot = Quaternion.CreateFromAxisAngle(new Vector3(1.0f, 0.0f, 0.0f), (float)angle + pushY * 0.9f);
- foreach (Vertex v in newLayer.vertices)
- {
- if (v != null)
- {
- vTemp = v * layerRot;
- v.X = vTemp.X + xOffset;
- v.Y = vTemp.Y + yOffset;
- v.Z = vTemp.Z + zOffset;
- }
- }
-
- if (angle == startAngle) // the first layer, invert normals
- {
- foreach (Triangle t in newLayer.triangles)
- {
- t.invertNormal();
- }
- }
-
- result.Append(newLayer);
-
- int iLastNull = 0;
-
- if (lastLayer != null)
- {
- int i, count = newLayer.vertices.Count;
-
- for (i = 0; i < count; i++)
- {
- int iNext = (i + 1);
-
- if (lastLayer.vertices[i] == null) // cant make a simplex here
- {
- iLastNull = i + 1;
- }
- else
- {
- if (i == count - 1) // End of list
- iNext = iLastNull;
-
- if (lastLayer.vertices[iNext] == null) // Null means wrap to begin of last segment
- iNext = iLastNull;
-
- result.Add(new Triangle(newLayer.vertices[i], lastLayer.vertices[i], newLayer.vertices[iNext]));
- result.Add(new Triangle(newLayer.vertices[iNext], lastLayer.vertices[i], lastLayer.vertices[iNext]));
- }
- }
- }
- lastLayer = newLayer;
-
- // calc the angle for the next interation of the loop
- if (angle >= endAngle)
- {
- done = true;
- }
- else
- {
- angle = stepSize * ++step;
- if (angle > endAngle)
- angle = endAngle;
- }
- } while (!done); // loop until all the layers in the path are completed
-
- // scale the mesh to the desired size
- float xScale = size.X;
- float yScale = size.Y;
- float zScale = size.Z;
-
- foreach (Vertex v in result.vertices)
- {
- if (v != null)
- {
- v.X *= xScale;
- v.Y *= yScale;
- v.Z *= zScale;
- }
- }
-
- return result;
- }
- }
-}
diff --git a/OpenSim/Region/Physics/Meshing/HelperTypes.cs b/OpenSim/Region/Physics/Meshing/HelperTypes.cs
index 7491782293..7198cae5d3 100644
--- a/OpenSim/Region/Physics/Meshing/HelperTypes.cs
+++ b/OpenSim/Region/Physics/Meshing/HelperTypes.cs
@@ -356,20 +356,6 @@ public class Triangle
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();
diff --git a/OpenSim/Region/Physics/Meshing/Mesh.cs b/OpenSim/Region/Physics/Meshing/Mesh.cs
index 583b485995..5a565ffcc8 100644
--- a/OpenSim/Region/Physics/Meshing/Mesh.cs
+++ b/OpenSim/Region/Physics/Meshing/Mesh.cs
@@ -115,26 +115,6 @@ namespace OpenSim.Region.Physics.Meshing
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)
diff --git a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs
index 6955aa0ff6..a65d0f457e 100644
--- a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs
+++ b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs
@@ -31,6 +31,9 @@ using System.Collections.Generic;
using OpenSim.Framework;
using OpenSim.Region.Physics.Manager;
using OpenMetaverse;
+using OpenMetaverse.Imaging;
+using System.Drawing;
+using System.Drawing.Imaging;
using PrimMesher;
namespace OpenSim.Region.Physics.Meshing
@@ -54,8 +57,6 @@ namespace OpenSim.Region.Physics.Meshing
public class Meshmerizer : IMesher
{
- private bool usePrimMesher = true;
-
//private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
// Setting baseDir to a path will enable the dumping of raw files
@@ -65,277 +66,9 @@ namespace OpenSim.Region.Physics.Meshing
#else
private const string baseDir = null; //"rawFiles";
#endif
- private const float DEG_TO_RAD = 0.01745329238f;
private float minSizeForComplexMesh = 0.2f; // prims with all dimensions smaller than this will have a bounding box mesh
-// private 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);
- }
- }
- }
- }
-
- private static SimpleHull BuildHoleHull(PrimitiveBaseShape pbs, ProfileShape pshape, HollowShape hshape, UInt16 hollowFactor)
- {
- // Tackle HollowShape.Same
- float fhollowFactor = (float)hollowFactor;
-
- switch (pshape)
- {
- case ProfileShape.Square:
- if (hshape == HollowShape.Same)
- hshape= HollowShape.Square;
- break;
- case ProfileShape.EquilateralTriangle:
- fhollowFactor = ((float)hollowFactor / 1.9f);
- if (hshape == HollowShape.Same)
- {
- hshape = HollowShape.Triangle;
- }
-
- break;
-
- case ProfileShape.HalfCircle:
- case ProfileShape.Circle:
- if (pbs.PathCurve == (byte)Extrusion.Straight)
- {
- if (hshape == HollowShape.Same)
- {
- hshape = HollowShape.Circle;
- }
- }
- break;
-
-
- default:
- if (hshape == HollowShape.Same)
- hshape= HollowShape.Square;
- break;
- }
-
-
- SimpleHull holeHull = null;
-
- if (hshape == HollowShape.Square)
- {
- float hollowFactorF = (float)fhollowFactor / (float)50000;
- Vertex IMM;
- Vertex IPM;
- Vertex IPP;
- Vertex IMP;
-
- if (pshape == ProfileShape.Circle)
- { // square cutout in cylinder is 45 degress rotated
- IMM = new Vertex(0.0f, -0.707f * hollowFactorF, 0.0f);
- IPM = new Vertex(0.707f * hollowFactorF, 0.0f, 0.0f);
- IPP = new Vertex(0.0f, 0.707f * hollowFactorF, 0.0f);
- IMP = new Vertex(-0.707f * hollowFactorF, 0.0f, 0.0f);
- }
- else if (pshape == ProfileShape.EquilateralTriangle)
- {
- IMM = new Vertex(0.0f, -0.667f * hollowFactorF, 0.0f);
- IPM = new Vertex(0.667f * hollowFactorF, 0.0f, 0.0f);
- IPP = new Vertex(0.0f, 0.667f * hollowFactorF, 0.0f);
- IMP = new Vertex(-0.667f * hollowFactorF, 0.0f, 0.0f);
- }
- else
- {
- IMM = new Vertex(-0.5f * hollowFactorF, -0.5f * hollowFactorF, 0.0f);
- IPM = new Vertex(+0.5f * hollowFactorF, -0.5f * hollowFactorF, 0.0f);
- IPP = new Vertex(+0.5f * hollowFactorF, +0.5f * hollowFactorF, 0.0f);
- IMP = new Vertex(-0.5f * hollowFactorF, +0.5f * hollowFactorF, 0.0f);
- }
-
- holeHull = new SimpleHull();
-
- holeHull.AddVertex(IMM);
- holeHull.AddVertex(IMP);
- holeHull.AddVertex(IPP);
- holeHull.AddVertex(IPM);
- }
- //if (hshape == HollowShape.Circle && pbs.PathCurve == (byte)Extrusion.Straight)
- if (hshape == HollowShape.Circle)
- {
- float hollowFactorF = (float)fhollowFactor / (float)50000;
-
- //Counter clockwise around the quadrants
- holeHull = new SimpleHull();
-
- holeHull.AddVertex(new Vertex(0.353553f * hollowFactorF, 0.353553f * hollowFactorF, 0.0f)); // 45 degrees
- holeHull.AddVertex(new Vertex(0.433013f * hollowFactorF, 0.250000f * hollowFactorF, 0.0f)); // 30 degrees
- holeHull.AddVertex(new Vertex(0.482963f * hollowFactorF, 0.129410f * hollowFactorF, 0.0f)); // 15 degrees
- holeHull.AddVertex(new Vertex(0.500000f * hollowFactorF, 0.000000f * hollowFactorF, 0.0f)); // 0 degrees
- holeHull.AddVertex(new Vertex(0.482963f * hollowFactorF, -0.129410f * hollowFactorF, 0.0f)); // 345 degrees
- holeHull.AddVertex(new Vertex(0.433013f * hollowFactorF, -0.250000f * hollowFactorF, 0.0f)); // 330 degrees
- holeHull.AddVertex(new Vertex(0.353553f * hollowFactorF, -0.353553f * hollowFactorF, 0.0f)); // 315 degrees
- holeHull.AddVertex(new Vertex(0.250000f * hollowFactorF, -0.433013f * hollowFactorF, 0.0f)); // 300 degrees
- holeHull.AddVertex(new Vertex(0.129410f * hollowFactorF, -0.482963f * hollowFactorF, 0.0f)); // 285 degrees
- holeHull.AddVertex(new Vertex(0.000000f * hollowFactorF, -0.500000f * hollowFactorF, 0.0f)); // 270 degrees
- holeHull.AddVertex(new Vertex(-0.129410f * hollowFactorF, -0.482963f * hollowFactorF, 0.0f)); // 255 degrees
- holeHull.AddVertex(new Vertex(-0.250000f * hollowFactorF, -0.433013f * hollowFactorF, 0.0f)); // 240 degrees
- holeHull.AddVertex(new Vertex(-0.353553f * hollowFactorF, -0.353553f * hollowFactorF, 0.0f)); // 225 degrees
- holeHull.AddVertex(new Vertex(-0.433013f * hollowFactorF, -0.250000f * hollowFactorF, 0.0f)); // 210 degrees
- holeHull.AddVertex(new Vertex(-0.482963f * hollowFactorF, -0.129410f * hollowFactorF, 0.0f)); // 195 degrees
- holeHull.AddVertex(new Vertex(-0.500000f * hollowFactorF, 0.000000f * hollowFactorF, 0.0f)); // 180 degrees
- holeHull.AddVertex(new Vertex(-0.482963f * hollowFactorF, 0.129410f * hollowFactorF, 0.0f)); // 165 degrees
- holeHull.AddVertex(new Vertex(-0.433013f * hollowFactorF, 0.250000f * hollowFactorF, 0.0f)); // 150 degrees
- holeHull.AddVertex(new Vertex(-0.353553f * hollowFactorF, 0.353553f * hollowFactorF, 0.0f)); // 135 degrees
- holeHull.AddVertex(new Vertex(-0.250000f * hollowFactorF, 0.433013f * hollowFactorF, 0.0f)); // 120 degrees
- holeHull.AddVertex(new Vertex(-0.129410f * hollowFactorF, 0.482963f * hollowFactorF, 0.0f)); // 105 degrees
- holeHull.AddVertex(new Vertex(0.000000f * hollowFactorF, 0.500000f * hollowFactorF, 0.0f)); // 90 degrees
- holeHull.AddVertex(new Vertex(0.129410f * hollowFactorF, 0.482963f * hollowFactorF, 0.0f)); // 75 degrees
- holeHull.AddVertex(new Vertex(0.250000f * hollowFactorF, 0.433013f * hollowFactorF, 0.0f)); // 60 degrees
- holeHull.AddVertex(new Vertex(0.353553f * hollowFactorF, 0.353553f * hollowFactorF, 0.0f)); // 45 degrees
-
- }
- if (hshape == HollowShape.Triangle)
- {
- float hollowFactorF = (float)fhollowFactor / (float)50000;
- Vertex IMM;
- Vertex IPM;
- Vertex IPP;
-
- if (pshape == ProfileShape.Square)
- {
- // corner points are at 345, 105, and 225 degrees for the triangle within a box
-
- //IMM = new Vertex(((float)Math.Cos(345.0 * DEG_TO_RAD) * 0.5f) * hollowFactorF, ((float)Math.Sin(345.0 * DEG_TO_RAD) * 0.5f) * hollowFactorF, 0.0f);
- //IPM = new Vertex(((float)Math.Cos(105.0 * DEG_TO_RAD) * 0.5f) * hollowFactorF, ((float)Math.Sin(105.0 * DEG_TO_RAD) * 0.5f) * hollowFactorF, 0.0f);
- //IPP = new Vertex(((float)Math.Cos(225.0 * DEG_TO_RAD) * 0.5f) * hollowFactorF, ((float)Math.Sin(225.0 * DEG_TO_RAD) * 0.5f) * hollowFactorF, 0.0f);
-
- // hard coded here for speed, the equations are in the commented out lines above
- IMM = new Vertex(0.48296f * hollowFactorF, -0.12941f * hollowFactorF, 0.0f);
- IPM = new Vertex(-0.12941f * hollowFactorF, 0.48296f * hollowFactorF, 0.0f);
- IPP = new Vertex(-0.35355f * hollowFactorF, -0.35355f * hollowFactorF, 0.0f);
- }
- else
- {
- IMM = new Vertex(-0.25f * hollowFactorF, -0.45f * hollowFactorF, 0.0f);
- IPM = new Vertex(+0.5f * hollowFactorF, +0f * hollowFactorF, 0.0f);
- IPP = new Vertex(-0.25f * hollowFactorF, +0.45f * hollowFactorF, 0.0f);
- }
-
- holeHull = new SimpleHull();
-
- holeHull.AddVertex(IMM);
- holeHull.AddVertex(IPP);
- holeHull.AddVertex(IPM);
-
- }
-
- return holeHull;
-
-
- }
///
/// creates a simple box mesh of the specified size
@@ -420,1364 +153,197 @@ namespace OpenSim.Region.Physics.Meshing
return CreateSimpleBoxMesh(minX, maxX, minY, maxY, minZ, maxZ);
}
-
- private 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;
- UInt16 taperX = primShape.PathScaleX;
- UInt16 taperY = primShape.PathScaleY;
- UInt16 pathShearX = primShape.PathShearX;
- UInt16 pathShearY = primShape.PathShearY;
-
-#if SPAM
- reportPrimParams("[BOX] " + primName, primShape);
-#endif
-
- // 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 PP = new Vertex(+0.5f, +0.5f, 0.0f);
- Vertex MP = new Vertex(-0.5f, +0.5f, 0.0f);
-
- SimpleHull outerHull = new SimpleHull();
-
- outerHull.AddVertex(PP);
- outerHull.AddVertex(MP);
- outerHull.AddVertex(MM);
- outerHull.AddVertex(PM);
-
- // 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);
-
- // avoid some problem angles until the hull subtraction routine is fixed
- if ((fProfileBeginAngle + 45.0f) % 90.0f == 0.0f)
- fProfileBeginAngle += 5.0f;
- if ((fProfileEndAngle + 45.0f) % 90.0f == 0.0f)
- fProfileEndAngle -= 5.0f;
- if (fProfileBeginAngle % 90.0f == 0.0f)
- fProfileBeginAngle += 1.0f;
- if (fProfileEndAngle % 90.0f == 0.0f)
- fProfileEndAngle -= 1.0f;
-
- if (fProfileBeginAngle < fProfileEndAngle)
- fProfileEndAngle -= 360.0;
-
-#if SPAM
- Console.WriteLine("Meshmerizer: fProfileBeginAngle: " + fProfileBeginAngle.ToString() + " fProfileEndAngle: " + fProfileEndAngle.ToString());
-#endif
-
- // 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 < iSteps; i++)
- {
- double angle = fProfileBeginAngle - i*dStepWidth; // we count against the angle orientation!!!!
- Vertex v = Vertex.FromAngle(angle*Math.PI/180.0);
- cutHull.AddVertex(v);
- }
- Vertex legEnd = Vertex.FromAngle(fProfileEndAngle*Math.PI/180.0);
- // Calculated separately to avoid errors
- cutHull.AddVertex(legEnd);
-
- //m_log.DebugFormat("Starting cutting of the hollow shape from the prim {1}", 0, primName);
- SimpleHull cuttedHull = SimpleHull.SubtractHull(outerHull, cutHull);
-
- outerHull = cuttedHull;
- }
-
- // Deal with the hole here
- if (hollowFactor > 0)
- {
- if (hollowFactor < 1000)
- hollowFactor = 1000; // some sane minimum for our beloved SimpleHull routines
-
- SimpleHull holeHull = BuildHoleHull(primShape, primShape.ProfileShape, primShape.HollowShape, hollowFactor);
- if (holeHull != null)
- {
- 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;
-
- if (taperX != 100)
- {
- if (taperX > 100)
- {
- extr.taperTopFactorX = 1.0f - ((float)(taperX - 100) / 100);
- }
- else
- {
- extr.taperBotFactorX = 1.0f - ((100 - (float)taperX) / 100);
- }
-
- }
-
- if (taperY != 100)
- {
- if (taperY > 100)
- {
- extr.taperTopFactorY = 1.0f - ((float)(taperY - 100) / 100);
- }
- else
- {
- extr.taperBotFactorY = 1.0f - ((100 - (float)taperY) / 100);
- }
- }
-
- if (pathShearX != 0)
- {
- if (pathShearX > 50)
- {
- // Complimentary byte. Negative values wrap around the byte. Positive values go up to 50
- extr.pushX = (((float)(256 - pathShearX) / 100) * -1f);
- }
- else
- {
- extr.pushX = (float)pathShearX / 100;
- }
- }
-
- if (pathShearY != 0)
- {
- if (pathShearY > 50)
- {
- // Complimentary byte. Negative values wrap around the byte. Positive values go up to 50
- extr.pushY = (((float)(256 - pathShearY) / 100) * -1f);
- }
- else
- {
- extr.pushY = (float)pathShearY / 100;
- }
- }
-
- extr.twistTop = (float)primShape.PathTwist * (float)Math.PI * 0.01f;
- extr.twistBot = (float)primShape.PathTwistBegin * (float)Math.PI * 0.01f;
- extr.pathBegin = primShape.PathBegin;
- extr.pathEnd = primShape.PathEnd;
-
- Mesh result = extr.ExtrudeLinearPath(m);
- result.DumpRaw(baseDir, primName, "Z extruded");
-#if SPAM
- int vCount = 0;
-
- foreach (Vertex v in result.vertices)
- if (v != null)
- vCount++;
- System.Console.WriteLine("Mesh vertex count: " + vCount.ToString());
-#endif
- return result;
- }
-
- private static Mesh CreateCylinderMesh(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;
- UInt16 taperX = primShape.PathScaleX;
- UInt16 taperY = primShape.PathScaleY;
- UInt16 pathShearX = primShape.PathShearX;
- UInt16 pathShearY = primShape.PathShearY;
-
-#if SPAM
- reportPrimParams("[CYLINDER] " + primName, primShape);
-#endif
-
-
- // 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
-
- SimpleHull outerHull = new SimpleHull();
-
- // counter-clockwise around the quadrants, start at 45 degrees
-
- outerHull.AddVertex(new Vertex(0.353553f, 0.353553f, 0.0f)); // 45 degrees
- outerHull.AddVertex(new Vertex(0.250000f, 0.433013f, 0.0f)); // 60 degrees
- outerHull.AddVertex(new Vertex(0.129410f, 0.482963f, 0.0f)); // 75 degrees
- outerHull.AddVertex(new Vertex(0.000000f, 0.500000f, 0.0f)); // 90 degrees
- outerHull.AddVertex(new Vertex(-0.129410f, 0.482963f, 0.0f)); // 105 degrees
- outerHull.AddVertex(new Vertex(-0.250000f, 0.433013f, 0.0f)); // 120 degrees
- outerHull.AddVertex(new Vertex(-0.353553f, 0.353553f, 0.0f)); // 135 degrees
- outerHull.AddVertex(new Vertex(-0.433013f, 0.250000f, 0.0f)); // 150 degrees
- outerHull.AddVertex(new Vertex(-0.482963f, 0.129410f, 0.0f)); // 165 degrees
- outerHull.AddVertex(new Vertex(-0.500000f, 0.000000f, 0.0f)); // 180 degrees
- outerHull.AddVertex(new Vertex(-0.482963f, -0.129410f, 0.0f)); // 195 degrees
- outerHull.AddVertex(new Vertex(-0.433013f, -0.250000f, 0.0f)); // 210 degrees
- outerHull.AddVertex(new Vertex(-0.353553f, -0.353553f, 0.0f)); // 225 degrees
- outerHull.AddVertex(new Vertex(-0.250000f, -0.433013f, 0.0f)); // 240 degrees
- outerHull.AddVertex(new Vertex(-0.129410f, -0.482963f, 0.0f)); // 255 degrees
- outerHull.AddVertex(new Vertex(0.000000f, -0.500000f, 0.0f)); // 270 degrees
- outerHull.AddVertex(new Vertex(0.129410f, -0.482963f, 0.0f)); // 285 degrees
- outerHull.AddVertex(new Vertex(0.250000f, -0.433013f, 0.0f)); // 300 degrees
- outerHull.AddVertex(new Vertex(0.353553f, -0.353553f, 0.0f)); // 315 degrees
- outerHull.AddVertex(new Vertex(0.433013f, -0.250000f, 0.0f)); // 330 degrees
- outerHull.AddVertex(new Vertex(0.482963f, -0.129410f, 0.0f)); // 345 degrees
- outerHull.AddVertex(new Vertex(0.500000f, 0.000000f, 0.0f)); // 0 degrees
- outerHull.AddVertex(new Vertex(0.482963f, 0.129410f, 0.0f)); // 15 degrees
- outerHull.AddVertex(new Vertex(0.433013f, 0.250000f, 0.0f)); // 30 degrees
-
-
-
- // Deal with cuts now
- if ((profileBegin != 0) || (profileEnd != 0))
- {
- double fProfileBeginAngle = profileBegin / 50000.0 * 360.0;
- // In degree, for easier debugging and understanding
- double fProfileEndAngle = 360.0 - profileEnd / 50000.0 * 360.0; // Pathend comes as complement to 1.0
-
-#if SPAM
- Console.WriteLine("Extruder: Cylinder fProfileBeginAngle: " + fProfileBeginAngle.ToString() + " fProfileEndAngle: " + fProfileEndAngle.ToString());
-#endif
- if (fProfileBeginAngle > 270.0f && fProfileBeginAngle < 271.8f) // a problem angle for the hull subtract routine :(
- fProfileBeginAngle = 271.8f; // workaround - use the smaller slice
-
- if (fProfileBeginAngle < fProfileEndAngle)
- fProfileEndAngle -= 360.0;
-#if SPAM
- Console.WriteLine("Extruder: Cylinder fProfileBeginAngle: " + fProfileBeginAngle.ToString() + " fProfileEndAngle: " + fProfileEndAngle.ToString());
-#endif
-
- // 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 < iSteps; i++)
- {
- double angle = fProfileBeginAngle - i * dStepWidth; // we count against the angle orientation!!!!
- Vertex v = Vertex.FromAngle(angle * Math.PI / 180.0);
- cutHull.AddVertex(v);
- }
- Vertex legEnd = Vertex.FromAngle(fProfileEndAngle * Math.PI / 180.0);
- // Calculated separately to avoid errors
- cutHull.AddVertex(legEnd);
-
- SimpleHull cuttedHull = SimpleHull.SubtractHull(outerHull, cutHull);
-
- outerHull = cuttedHull;
- }
-
- // Deal with the hole here
- if (hollowFactor > 0)
- {
- if (hollowFactor < 1000)
- hollowFactor = 1000; // some sane minimum for our beloved SimpleHull routines
-
- SimpleHull holeHull = BuildHoleHull(primShape, primShape.ProfileShape, primShape.HollowShape, hollowFactor);
- if (holeHull != null)
- {
- 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;
-
- if (taperX != 100)
- {
- if (taperX > 100)
- {
- extr.taperTopFactorX = 1.0f - ((float)(taperX - 100) / 100); }
- else
- {
- extr.taperBotFactorX = 1.0f - ((100 - (float)taperX) / 100);
- }
-
- }
-
- if (taperY != 100)
- {
- if (taperY > 100)
- {
- extr.taperTopFactorY = 1.0f - ((float)(taperY - 100) / 100);
- }
- else
- {
- extr.taperBotFactorY = 1.0f - ((100 - (float)taperY) / 100);
- }
- }
-
- if (pathShearX != 0)
- {
- if (pathShearX > 50)
- {
- // Complimentary byte. Negative values wrap around the byte. Positive values go up to 50
- extr.pushX = (((float)(256 - pathShearX) / 100) * -1f);
- }
- else
- {
- extr.pushX = (float)pathShearX / 100;
- }
- }
-
- if (pathShearY != 0)
- {
- if (pathShearY > 50)
- {
- // Complimentary byte. Negative values wrap around the byte. Positive values go up to 50
- extr.pushY = (((float)(256 - pathShearY) / 100) * -1f);
- }
- else
- {
- extr.pushY = (float)pathShearY / 100;
- }
-
- }
-
- extr.twistTop = (float)primShape.PathTwist * (float)Math.PI * 0.01f;
- extr.twistBot = (float)primShape.PathTwistBegin * (float)Math.PI * 0.01f;
- extr.pathBegin = primShape.PathBegin;
- extr.pathEnd = primShape.PathEnd;
-
- Mesh result = extr.ExtrudeLinearPath(m);
- result.DumpRaw(baseDir, primName, "Z extruded");
-#if SPAM
- int vCount = 0;
-
- foreach (Vertex v in result.vertices)
- if (v != null)
- vCount++;
- System.Console.WriteLine("Mesh vertex count: " + vCount.ToString());
-#endif
- return result;
- }
-
- private static Mesh CreatePrismMesh(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;
- UInt16 taperX = primShape.PathScaleX;
- UInt16 taperY = primShape.PathScaleY;
- UInt16 pathShearX = primShape.PathShearX;
- UInt16 pathShearY = primShape.PathShearY;
-
-
-#if SPAM
- reportPrimParams("[PRISM] " + primName, primShape);
-#endif
- // 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.25f, -0.45f, 0.0f);
- Vertex PM = new Vertex(+0.5f, 0f, 0.0f);
- Vertex PP = new Vertex(-0.25f, +0.45f, 0.0f);
-
-
- SimpleHull outerHull = new SimpleHull();
-
- outerHull.AddVertex(PP);
- outerHull.AddVertex(MM);
- outerHull.AddVertex(PM);
-
- // Deal with cuts now
- if ((profileBegin != 0) || (profileEnd != 0))
- {
- double fProfileBeginAngle = profileBegin / 50000.0 * 360.0;
- // In degree, for easier debugging and understanding
- double fProfileEndAngle = 360.0 - profileEnd / 50000.0 * 360.0; // Pathend comes as complement to 1.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 < iSteps; i++)
- {
- double angle = fProfileBeginAngle - i * dStepWidth; // we count against the angle orientation!!!!
- Vertex v = Vertex.FromAngle(angle * Math.PI / 180.0);
- cutHull.AddVertex(v);
- }
- Vertex legEnd = Vertex.FromAngle(fProfileEndAngle * Math.PI / 180.0);
- // Calculated separately to avoid errors
- cutHull.AddVertex(legEnd);
-
- SimpleHull cuttedHull = SimpleHull.SubtractHull(outerHull, cutHull);
-
- outerHull = cuttedHull;
- }
-
- // Deal with the hole here
- if (hollowFactor > 0)
- {
- if (hollowFactor < 1000)
- hollowFactor = 1000; // some sane minimum for our beloved SimpleHull routines
-
- SimpleHull holeHull = BuildHoleHull(primShape, primShape.ProfileShape, primShape.HollowShape, hollowFactor);
- if (holeHull != null)
- {
- 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;
-
- if (taperX != 100)
- {
- if (taperX > 100)
- {
- extr.taperTopFactorX = 1.0f - ((float)(taperX - 100) / 100);
- }
- else
- {
- extr.taperBotFactorX = 1.0f - ((100 - (float)taperX) / 100);
- }
-
- }
-
- if (taperY != 100)
- {
- if (taperY > 100)
- {
- extr.taperTopFactorY = 1.0f - ((float)(taperY - 100) / 100);
- }
- else
- {
- extr.taperBotFactorY = 1.0f - ((100 - (float)taperY) / 100);
- }
- }
-
- if (pathShearX != 0)
- {
- if (pathShearX > 50)
- {
- // Complimentary byte. Negative values wrap around the byte. Positive values go up to 50
- extr.pushX = (((float)(256 - pathShearX) / 100) * -1f);
- }
- else
- {
- extr.pushX = (float)pathShearX / 100;
- }
- }
-
- if (pathShearY != 0)
- {
- if (pathShearY > 50)
- {
- // Complimentary byte. Negative values wrap around the byte. Positive values go up to 50
- extr.pushY = (((float)(256 - pathShearY) / 100) * -1f);
- }
- else
- {
- extr.pushY = (float)pathShearY / 100;
- }
- }
-
- extr.twistTop = (float)primShape.PathTwist * (float)Math.PI * 0.01f;
- extr.twistBot = (float)primShape.PathTwistBegin * (float)Math.PI * 0.01f;
- extr.pathBegin = primShape.PathBegin;
- extr.pathEnd = primShape.PathEnd;
-
- Mesh result = extr.ExtrudeLinearPath(m);
- result.DumpRaw(baseDir, primName, "Z extruded");
-#if SPAM
- int vCount = 0;
-
- foreach (Vertex v in result.vertices)
- if (v != null)
- vCount++;
- System.Console.WriteLine("Mesh vertex count: " + vCount.ToString());
-#endif
- return result;
- }
-
- ///
- /// builds an icosahedral geodesic sphere - used as default in place of problem meshes
- ///
- ///
- ///
- ///
- ///
- private static Mesh CreateSphereMesh(String primName, PrimitiveBaseShape primShape, PhysicsVector size)
- {
- // Builds an icosahedral geodesic sphere
- // based on an article by Paul Bourke
- // http://local.wasp.uwa.edu.au/~pbourke/
- // articles:
- // http://local.wasp.uwa.edu.au/~pbourke/geometry/polygonmesh/
- // and
- // http://local.wasp.uwa.edu.au/~pbourke/geometry/polyhedra/index.html
-
- // Still have more to do here.
-
- Mesh m = new Mesh();
-
-#if SPAM
- reportPrimParams("[SPHERE] " + primName, primShape);
-#endif
-
- float LOD = 0.2f;
- float diameter = 0.5f;// Our object will result in -0.5 to 0.5
- float sq5 = (float) Math.Sqrt(5.0);
- float phi = (1 + sq5) * 0.5f;
- float rat = (float) Math.Sqrt(10f + (2f * sq5)) / (4f * phi);
- float a = (diameter / rat) * 0.5f;
- float b = (diameter / rat) / (2.0f * phi);
-
-
- // 12 Icosahedron vertexes
- Vertex v1 = new Vertex(0f, b, -a);
- Vertex v2 = new Vertex(b, a, 0f);
- Vertex v3 = new Vertex(-b, a, 0f);
- Vertex v4 = new Vertex(0f, b, a);
- Vertex v5 = new Vertex(0f, -b, a);
- Vertex v6 = new Vertex(-a, 0f, b);
- Vertex v7 = new Vertex(0f, -b, -a);
- Vertex v8 = new Vertex(a, 0f, -b);
- Vertex v9 = new Vertex(a, 0f, b);
- Vertex v10 = new Vertex(-a, 0f, -b);
- Vertex v11 = new Vertex(b, -a, 0);
- Vertex v12 = new Vertex(-b, -a, 0);
-
-
-
- // Base Faces of the Icosahedron (20)
- SphereLODTriangle(v1, v2, v3, diameter, LOD, m);
- SphereLODTriangle(v4, v3, v2, diameter, LOD, m);
- SphereLODTriangle(v4, v5, v6, diameter, LOD, m);
- SphereLODTriangle(v4, v9, v5, diameter, LOD, m);
- SphereLODTriangle(v1, v7, v8, diameter, LOD, m);
- SphereLODTriangle(v1, v10, v7, diameter, LOD, m);
- SphereLODTriangle(v5, v11, v12, diameter, LOD, m);
- SphereLODTriangle(v7, v12, v11, diameter, LOD, m);
- SphereLODTriangle(v3, v6, v10, diameter, LOD, m);
- SphereLODTriangle(v12, v10, v6, diameter, LOD, m);
- SphereLODTriangle(v2, v8, v9, diameter, LOD, m);
- SphereLODTriangle(v11, v9, v8, diameter, LOD, m);
- SphereLODTriangle(v4, v6, v3, diameter, LOD, m);
- SphereLODTriangle(v4, v2, v9, diameter, LOD, m);
- SphereLODTriangle(v1, v3, v10, diameter, LOD, m);
- SphereLODTriangle(v1, v8, v2, diameter, LOD, m);
- SphereLODTriangle(v7, v10, v12, diameter, LOD, m);
- SphereLODTriangle(v7, v11, v8, diameter, LOD, m);
- SphereLODTriangle(v5, v12, v6, diameter, LOD, m);
- SphereLODTriangle(v5, v9, v11, diameter, LOD, m);
-
- // Scale the mesh based on our prim scale
- foreach (Vertex v in m.vertices)
- {
- v.X *= size.X;
- v.Y *= size.Y;
- v.Z *= size.Z;
- }
-
- // This was built with the normals pointing inside..
- // therefore we have to invert the normals
- foreach (Triangle t in m.triangles)
- {
- t.invertNormal();
- }
- // Dump the faces for visualization in blender.
- m.DumpRaw(baseDir, primName, "Icosahedron");
-#if SPAM
- int vCount = 0;
-
- foreach (Vertex v in m.vertices)
- if (v != null)
- vCount++;
- System.Console.WriteLine("Mesh vertex count: " + vCount.ToString());
-#endif
-
- return m;
- }
- private SculptMesh CreateSculptMesh(string primName, PrimitiveBaseShape primShape, PhysicsVector size, float lod)
- {
-
-#if SPAM
- reportPrimParams("[SCULPT] " + primName, primShape);
-#endif
-
- SculptMesh sm = new SculptMesh(primShape.SculptData, lod);
- // Scale the mesh based on our prim scale
- foreach (Vertex v in sm.vertices)
- {
- v.X *= 0.5f;
- v.Y *= 0.5f;
- v.Z *= 0.5f;
- v.X *= size.X;
- v.Y *= size.Y;
- v.Z *= size.Z;
- }
- // This was built with the normals pointing inside..
- // therefore we have to invert the normals
- foreach (Triangle t in sm.triangles)
- {
- t.invertNormal();
- }
- sm.DumpRaw(baseDir, primName, "Sculpt");
- return sm;
-
- }
-
- ///
- /// Creates a mesh for prim types torus, ring, tube, and sphere
- ///
- ///
- ///
- ///
- ///
- private static Mesh CreateCircularPathMesh(String primName, PrimitiveBaseShape primShape, PhysicsVector size)
- {
-
- UInt16 hollowFactor = primShape.ProfileHollow;
- UInt16 profileBegin = primShape.ProfileBegin;
- UInt16 profileEnd = primShape.ProfileEnd;
- UInt16 pathShearX = primShape.PathShearX;
- UInt16 pathShearY = primShape.PathShearY;
- HollowShape hollowShape = primShape.HollowShape;
-
-#if SPAM
- reportPrimParams("[CIRCULAR PATH PRIM] " + primName, primShape);
- Console.WriteLine("pathTwist: " + primShape.PathTwist.ToString() + " pathTwistBegin: " + primShape.PathTwistBegin.ToString());
- Console.WriteLine("primShape.ProfileCurve & 0x07: " + Convert.ToString(primShape.ProfileCurve & 0x07));
-
-#endif
-
- SimpleHull outerHull = new SimpleHull();
-
- if ((primShape.ProfileCurve & 0x07) == (byte)ProfileShape.Circle)
- {
-#if SPAM
- Console.WriteLine("Meshmerizer thinks " + primName + " is a TORUS");
-#endif
- if (hollowShape == HollowShape.Same)
- hollowShape = HollowShape.Circle;
-
- // build the profile shape
- // counter-clockwise around the quadrants, start at 45 degrees
-
- outerHull.AddVertex(new Vertex(0.353553f, 0.353553f, 0.0f)); // 45 degrees
- outerHull.AddVertex(new Vertex(0.250000f, 0.433013f, 0.0f)); // 60 degrees
- outerHull.AddVertex(new Vertex(0.129410f, 0.482963f, 0.0f)); // 75 degrees
- outerHull.AddVertex(new Vertex(0.000000f, 0.500000f, 0.0f)); // 90 degrees
- outerHull.AddVertex(new Vertex(-0.129410f, 0.482963f, 0.0f)); // 105 degrees
- outerHull.AddVertex(new Vertex(-0.250000f, 0.433013f, 0.0f)); // 120 degrees
- outerHull.AddVertex(new Vertex(-0.353553f, 0.353553f, 0.0f)); // 135 degrees
- outerHull.AddVertex(new Vertex(-0.433013f, 0.250000f, 0.0f)); // 150 degrees
- outerHull.AddVertex(new Vertex(-0.482963f, 0.129410f, 0.0f)); // 165 degrees
- outerHull.AddVertex(new Vertex(-0.500000f, 0.000000f, 0.0f)); // 180 degrees
- outerHull.AddVertex(new Vertex(-0.482963f, -0.129410f, 0.0f)); // 195 degrees
- outerHull.AddVertex(new Vertex(-0.433013f, -0.250000f, 0.0f)); // 210 degrees
- outerHull.AddVertex(new Vertex(-0.353553f, -0.353553f, 0.0f)); // 225 degrees
- outerHull.AddVertex(new Vertex(-0.250000f, -0.433013f, 0.0f)); // 240 degrees
- outerHull.AddVertex(new Vertex(-0.129410f, -0.482963f, 0.0f)); // 255 degrees
- outerHull.AddVertex(new Vertex(0.000000f, -0.500000f, 0.0f)); // 270 degrees
- outerHull.AddVertex(new Vertex(0.129410f, -0.482963f, 0.0f)); // 285 degrees
- outerHull.AddVertex(new Vertex(0.250000f, -0.433013f, 0.0f)); // 300 degrees
- outerHull.AddVertex(new Vertex(0.353553f, -0.353553f, 0.0f)); // 315 degrees
- outerHull.AddVertex(new Vertex(0.433013f, -0.250000f, 0.0f)); // 330 degrees
- outerHull.AddVertex(new Vertex(0.482963f, -0.129410f, 0.0f)); // 345 degrees
- outerHull.AddVertex(new Vertex(0.500000f, 0.000000f, 0.0f)); // 0 degrees
- outerHull.AddVertex(new Vertex(0.482963f, 0.129410f, 0.0f)); // 15 degrees
- outerHull.AddVertex(new Vertex(0.433013f, 0.250000f, 0.0f)); // 30 degrees
- }
-
- else if ((primShape.ProfileCurve & 0x07) == (byte)ProfileShape.Square) // a ring
- {
-#if SPAM
- Console.WriteLine("Meshmerizer thinks " + primName + " is a TUBE");
-#endif
- if (hollowShape == HollowShape.Same)
- hollowShape = HollowShape.Square;
-
- outerHull.AddVertex(new Vertex(+0.5f, +0.5f, 0.0f));
- outerHull.AddVertex(new Vertex(-0.5f, +0.5f, 0.0f));
- outerHull.AddVertex(new Vertex(-0.5f, -0.5f, 0.0f));
- outerHull.AddVertex(new Vertex(+0.5f, -0.5f, 0.0f));
- }
-
- else if ((primShape.ProfileCurve & 0x07) == (byte)ProfileShape.EquilateralTriangle)
- {
-#if SPAM
- Console.WriteLine("Meshmerizer thinks " + primName + " is a RING");
-#endif
- if (hollowShape == HollowShape.Same)
- hollowShape = HollowShape.Triangle;
-
- outerHull.AddVertex(new Vertex(+0.255f, -0.375f, 0.0f));
- outerHull.AddVertex(new Vertex(+0.25f, +0.375f, 0.0f));
- outerHull.AddVertex(new Vertex(-0.5f, +0.0f, 0.0f));
-
- }
-
- else if ((primShape.ProfileCurve & 0x07) == (byte)ProfileShape.HalfCircle)
- {
-#if SPAM
- Console.WriteLine("Meshmerizer thinks " + primName + " is a SPHERE");
-#endif
-
- // sanity check here... some spheres have inverted normals which can trap avatars
- // so for now if the shape parameters are such that this may happen, revert to the
- // geodesic sphere mesh.. the threshold is arbitrary as it seems any twist on a sphere
- // will create some inverted normals
- if (
- (System.Math.Abs(primShape.PathTwist - primShape.PathTwistBegin) > 65)
- || (primShape.PathBegin == 0
- && primShape.PathEnd == 0
- && primShape.PathTwist == 0
- && primShape.PathTwistBegin == 0
- && primShape.ProfileBegin == 0
- && primShape.ProfileEnd == 0
- && hollowFactor == 0
- ) // simple sphere, revert to geodesic shape
-
- )
- {
-#if SPAM
- System.Console.WriteLine("reverting to geodesic sphere for prim: " + primName);
-#endif
- return CreateSphereMesh(primName, primShape, size);
- }
-
- if (hollowFactor == 0)
- {
- // the hull triangulator is happier with a minimal hollow
- hollowFactor = 2000;
- }
-
- if (hollowShape == HollowShape.Same)
- hollowShape = HollowShape.Circle;
-
- outerHull.AddVertex(new Vertex(0.250000f, 0.433013f, 0.0f)); // 60 degrees
- outerHull.AddVertex(new Vertex(0.129410f, 0.482963f, 0.0f)); // 75 degrees
- outerHull.AddVertex(new Vertex(0.000000f, 0.500000f, 0.0f)); // 90 degrees
- outerHull.AddVertex(new Vertex(-0.129410f, 0.482963f, 0.0f)); // 105 degrees
- outerHull.AddVertex(new Vertex(-0.250000f, 0.433013f, 0.0f)); // 120 degrees
- outerHull.AddVertex(new Vertex(-0.353553f, 0.353553f, 0.0f)); // 135 degrees
- outerHull.AddVertex(new Vertex(-0.433013f, 0.250000f, 0.0f)); // 150 degrees
- outerHull.AddVertex(new Vertex(-0.482963f, 0.129410f, 0.0f)); // 165 degrees
- outerHull.AddVertex(new Vertex(-0.500000f, 0.000000f, 0.0f)); // 180 degrees
-
- outerHull.AddVertex(new Vertex(0.500000f, 0.000000f, 0.0f)); // 0 degrees
- outerHull.AddVertex(new Vertex(0.482963f, 0.129410f, 0.0f)); // 15 degrees
- outerHull.AddVertex(new Vertex(0.433013f, 0.250000f, 0.0f)); // 30 degrees
- outerHull.AddVertex(new Vertex(0.353553f, 0.353553f, 0.0f)); // 45 degrees
- }
-
- // Deal with cuts now
- if ((profileBegin != 0) || (profileEnd != 0))
- {
- double fProfileBeginAngle = profileBegin / 50000.0 * 360.0;
- // In degree, for easier debugging and understanding
- double fProfileEndAngle = 360.0 - profileEnd / 50000.0 * 360.0; // Pathend comes as complement to 1.0
-
- if (fProfileBeginAngle < fProfileEndAngle)
- fProfileEndAngle -= 360.0;
-
- if ((primShape.ProfileCurve & 0x07) == (byte)ProfileShape.HalfCircle)
- { // dimpled sphere uses profile cut but since it's a half circle the angles are smaller
- fProfileBeginAngle = 0.0036f * (float)primShape.ProfileBegin;
- fProfileEndAngle = 180.0f - 0.0036f * (float)primShape.ProfileEnd;
- if (fProfileBeginAngle < fProfileEndAngle)
- fProfileEndAngle -= 360.0f;
- // a cut starting at 0 degrees with a hollow causes an infinite loop so move the start angle
- // past it into the empty part of the circle to avoid this condition
- if (fProfileBeginAngle == 0.0f) fProfileBeginAngle = -10.0f;
-
-#if SPAM
- Console.WriteLine("Sphere dimple: fProfileBeginAngle: " + fProfileBeginAngle.ToString() + " fProfileEndAngle: " + fProfileEndAngle.ToString());
-#endif
- }
- else if ((primShape.ProfileCurve & 0x07) == (byte)ProfileShape.Square)
- { // tube profile cut is offset 45 degrees from other prim types
- fProfileBeginAngle += 45.0f;
- fProfileEndAngle += 45.0f;
- if (fProfileBeginAngle < fProfileEndAngle)
- fProfileEndAngle -= 360.0;
- }
- else if ((primShape.ProfileCurve & 0x07) == (byte)ProfileShape.EquilateralTriangle)
- { // ring profile cut is offset 180 degrees from other prim types
- fProfileBeginAngle += 180.0f;
- fProfileEndAngle += 180.0f;
- 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 < iSteps; i++)
- {
- double angle = fProfileBeginAngle - i * dStepWidth; // we count against the angle orientation!!!!
- Vertex v = Vertex.FromAngle(angle * Math.PI / 180.0);
- cutHull.AddVertex(v);
- }
- Vertex legEnd = Vertex.FromAngle(fProfileEndAngle * Math.PI / 180.0);
- // Calculated separately to avoid errors
- cutHull.AddVertex(legEnd);
-
- // m_log.DebugFormat("Starting cutting of the hollow shape from the prim {1}", 0, primName);
- SimpleHull cuttedHull = SimpleHull.SubtractHull(outerHull, cutHull);
-
- if ((primShape.ProfileCurve & 0x07) == (byte)ProfileShape.Circle)
- {
- Quaternion zFlip = Quaternion.CreateFromAxisAngle(new Vector3(0.0f, 0.0f, 1.0f), (float)Math.PI);
- Vertex vTmp = new Vertex(0.0f, 0.0f, 0.0f);
- foreach (Vertex v in cuttedHull.getVertices())
- if (v != null)
- {
- vTmp = v * zFlip;
- v.X = vTmp.X;
- v.Y = vTmp.Y;
- v.Z = vTmp.Z;
- }
- }
-
- outerHull = cuttedHull;
- }
-
- // Deal with the hole here
- if (hollowFactor > 0)
- {
- SimpleHull holeHull;
-
- if (hollowShape == HollowShape.Triangle)
- {
- holeHull = new SimpleHull();
-
- float hollowFactorF = (float)hollowFactor * 2.0e-5f;
-
- if ((primShape.ProfileCurve & 0x07) == (byte)ProfileShape.EquilateralTriangle)
- {
- holeHull.AddVertex(new Vertex(+0.125f * hollowFactorF, -0.1875f * hollowFactorF, 0.0f));
- holeHull.AddVertex(new Vertex(-0.25f * hollowFactorF, -0f * hollowFactorF, 0.0f));
- holeHull.AddVertex(new Vertex(+0.125f * hollowFactorF, +0.1875f * hollowFactorF, 0.0f));
- }
- else if ((primShape.ProfileCurve & 0x07) == (byte)ProfileShape.HalfCircle)
- {
- holeHull.AddVertex(new Vertex(-0.500000f * hollowFactorF, 0.000000f * hollowFactorF, 0.0f)); // 180 degrees
- holeHull.AddVertex(new Vertex(-0.250000f * hollowFactorF, 0.433013f * hollowFactorF, 0.0f)); // 120 degrees
- holeHull.AddVertex(new Vertex(0.250000f * hollowFactorF, 0.433013f * hollowFactorF, 0.0f)); // 60 degrees
- holeHull.AddVertex(new Vertex(0.500000f * hollowFactorF, 0.000000f * hollowFactorF, 0.0f)); // 0 degrees
- }
- else
- {
- holeHull.AddVertex(new Vertex(+0.25f * hollowFactorF, -0.45f * hollowFactorF, 0.0f));
- holeHull.AddVertex(new Vertex(-0.5f * hollowFactorF, -0f * hollowFactorF, 0.0f));
- holeHull.AddVertex(new Vertex(+0.25f * hollowFactorF, +0.45f * hollowFactorF, 0.0f));
- }
- }
- else if (hollowShape == HollowShape.Square && (primShape.ProfileCurve & 0x07) == (byte)ProfileShape.HalfCircle)
- {
- holeHull = new SimpleHull();
-
- float hollowFactorF = (float)hollowFactor * 2.0e-5f;
-
- holeHull.AddVertex(new Vertex(-0.707f * hollowFactorF, 0.0f, 0.0f)); // 180 degrees
- holeHull.AddVertex(new Vertex(0.0f, 0.707f * hollowFactorF, 0.0f)); // 120 degrees
- holeHull.AddVertex(new Vertex(0.707f * hollowFactorF, 0.0f, 0.0f)); // 60 degrees
- }
- else
- {
- holeHull = BuildHoleHull(primShape, primShape.ProfileShape, hollowShape, hollowFactor);
- }
-
- if (holeHull != null)
- {
- 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)
- t.invertNormal();
-
-
- float skew = primShape.PathSkew * 0.01f;
- float pathScaleX = (float)(200 - primShape.PathScaleX) * 0.01f;
- float pathScaleY = (float)(200 - primShape.PathScaleY) * 0.01f;
- float profileXComp = pathScaleX * (1.0f - Math.Abs(skew));
-
-#if SPAM
- //Console.WriteLine("primShape.PathScaleX: " + primShape.PathScaleX.ToString() + " primShape.PathScaleY: " + primShape.PathScaleY.ToString());
- //Console.WriteLine("primShape.PathSkew: " + primShape.PathSkew.ToString() + " primShape.PathRadiusOffset: " + primShape.PathRadiusOffset.ToString() + " primShape.pathRevolutions: " + primShape.PathRevolutions.ToString());
- Console.WriteLine("PathScaleX: " + pathScaleX.ToString() + " pathScaleY: " + pathScaleY.ToString());
- Console.WriteLine("skew: " + skew.ToString() + " profileXComp: " + profileXComp.ToString());
-#endif
-
- foreach (Vertex v in m.vertices)
- if (v != null)
- {
- v.X *= profileXComp;
- v.Y *= pathScaleY;
- }
-
- Extruder extr = new Extruder();
-
- extr.size = size;
- extr.pathScaleX = pathScaleX;
- extr.pathScaleY = pathScaleY;
- extr.pathCutBegin = 0.00002f * primShape.PathBegin;
- extr.pathCutEnd = 0.00002f * (50000 - primShape.PathEnd);
- extr.pathBegin = primShape.PathBegin;
- extr.pathEnd = primShape.PathEnd;
- extr.skew = skew;
- extr.revolutions = 1.0f + (float)primShape.PathRevolutions * 3.0f / 200.0f;
- extr.pathTaperX = 0.01f * (float)primShape.PathTaperX;
- extr.pathTaperY = 0.01f * (float)primShape.PathTaperY;
-
- extr.radius = 0.01f * (float)primShape.PathRadiusOffset;
-
-#if SPAM
- //System.Console.WriteLine("primShape.PathBegin: " + primShape.PathBegin.ToString() + " primShape.PathEnd: " + primShape.PathEnd.ToString());
- System.Console.WriteLine("extr.pathCutBegin: " + extr.pathCutBegin.ToString() + " extr.pathCutEnd: " + extr.pathCutEnd.ToString());
- System.Console.WriteLine("extr.revolutions: " + extr.revolutions.ToString());
-
- //System.Console.WriteLine("primShape.PathTaperX: " + primShape.PathTaperX.ToString());
- //System.Console.WriteLine("primShape.PathTaperY: " + primShape.PathTaperY.ToString());
-
-
- //System.Console.WriteLine("primShape.PathRadiusOffset: " + primShape.PathRadiusOffset.ToString());
-#endif
-
-
-
-
- if (pathShearX != 0)
- {
- if (pathShearX > 50)
- {
- // Complimentary byte. Negative values wrap around the byte. Positive values go up to 50
- extr.pushX = (((float)(256 - pathShearX) / 100) * -1f);
- }
- else
- {
- extr.pushX = (float)pathShearX / 100;
- }
- }
-
- if (pathShearY != 0)
- {
- if (pathShearY > 50)
- {
- // Complimentary byte. Negative values wrap around the byte. Positive values go up to 50
- extr.pushY = (((float)(256 - pathShearY) / 100) * -1f);
- }
- else
- {
- extr.pushY = (float)pathShearY / 100;
- }
-
- }
-
- extr.twistTop = (float)primShape.PathTwist * (float)Math.PI * 0.02f;
- extr.twistBot = (float)primShape.PathTwistBegin * (float)Math.PI * 0.02f;
-
- Mesh result = extr.ExtrudeCircularPath(m);
- result.DumpRaw(baseDir, primName, "Z extruded");
-
-#if SPAM
- int vCount = 0;
-
- foreach (Vertex v in result.vertices)
- {
- if (v != null)
- vCount++;
- }
-
- System.Console.WriteLine("Mesh vertex count: " + vCount.ToString());
-#endif
-
- return result;
- }
-
- public static Vertex midUnitRadialPoint(Vertex a, Vertex b, float radius)
- {
- Vertex midpoint = new Vertex(a + b) * 0.5f;
- return (midpoint.normalize() * radius);
- }
-
- public static void SphereLODTriangle(Vertex a, Vertex b, Vertex c, float diameter, float LOD, Mesh m)
- {
- Vertex aa = a - b;
- Vertex ba = b - c;
- Vertex da = c - a;
-
- if (((aa.length() < LOD) && (ba.length() < LOD) && (da.length() < LOD)))
- {
- // We don't want duplicate verticies. Duplicates cause the scale algorithm to produce a spikeball
- // spikes are novel, but we want ellipsoids.
-
- if (!m.vertices.Contains(a))
- m.Add(a);
- if (!m.vertices.Contains(b))
- m.Add(b);
- if (!m.vertices.Contains(c))
- m.Add(c);
-
- // Add the triangle to the mesh
- Triangle t = new Triangle(a, b, c);
- m.Add(t);
- }
- else
- {
- Vertex ab = midUnitRadialPoint(a, b, diameter);
- Vertex bc = midUnitRadialPoint(b, c, diameter);
- Vertex ca = midUnitRadialPoint(c, a, diameter);
-
- // Recursive! Splits the triangle up into 4 smaller triangles
- SphereLODTriangle(a, ab, ca, diameter, LOD, m);
- SphereLODTriangle(ab, b, bc, diameter, LOD, m);
- SphereLODTriangle(ca, bc, c, diameter, LOD, m);
- SphereLODTriangle(ab, bc, ca, diameter, LOD, m);
-
- }
- }
-
private void ReportPrimError(string message, string primName, PrimMesh primMesh)
{
Console.WriteLine(message);
Console.WriteLine("\nPrim Name: " + primName);
- Console.WriteLine("****** PrimMesh Parameters (Linear) ******\n" + primMesh.ParamsToDisplayString());
+ Console.WriteLine("****** PrimMesh Parameters ******\n" + primMesh.ParamsToDisplayString());
}
public Mesh CreateMeshFromPrimMesher(string primName, PrimitiveBaseShape primShape, PhysicsVector size, float lod)
{
Mesh mesh = new Mesh();
+ PrimMesh primMesh;
+ PrimMesher.SculptMesh sculptMesh;
- float pathShearX = primShape.PathShearX < 128 ? (float)primShape.PathShearX * 0.01f : (float)(primShape.PathShearX - 256) * 0.01f;
- float pathShearY = primShape.PathShearY < 128 ? (float)primShape.PathShearY * 0.01f : (float)(primShape.PathShearY - 256) * 0.01f;
- float pathBegin = (float)primShape.PathBegin * 2.0e-5f;
- float pathEnd = 1.0f - (float)primShape.PathEnd * 2.0e-5f;
- float pathScaleX = (float)(primShape.PathScaleX - 100) * 0.01f;
- float pathScaleY = (float)(primShape.PathScaleY - 100) * 0.01f;
+ List coords;
+ List faces;
- float profileBegin = (float)primShape.ProfileBegin * 2.0e-5f;
- float profileEnd = 1.0f - (float)primShape.ProfileEnd * 2.0e-5f;
- float profileHollow = (float)primShape.ProfileHollow * 2.0e-5f;
+ Image idata = null;
- int sides = 4;
- if ((primShape.ProfileCurve & 0x07) == (byte)ProfileShape.EquilateralTriangle)
- sides = 3;
- else if ((primShape.ProfileCurve & 0x07) == (byte)ProfileShape.Circle)
- sides = 24;
- else if ((primShape.ProfileCurve & 0x07) == (byte)ProfileShape.HalfCircle)
- { // half circle, prim is a sphere
- sides = 24;
+ if (primShape.SculptEntry)
+ {
+ if (primShape.SculptData.Length == 0)
+ return null;
- profileBegin = 0.5f * profileBegin + 0.5f;
- profileEnd = 0.5f * profileEnd + 0.5f;
+ try
+ {
+ ManagedImage managedImage; // we never use this
+ OpenJPEG.DecodeToImage(primShape.SculptData, out managedImage, out idata);
+ }
+ catch (Exception)
+ {
+ System.Console.WriteLine("[PHYSICS]: Unable to generate a Sculpty physics proxy. Sculpty texture decode failed!");
+ return null;
+ }
+
+ PrimMesher.SculptMesh.SculptType sculptType;
+ switch ((OpenMetaverse.SculptType)primShape.SculptType)
+ {
+ case OpenMetaverse.SculptType.Cylinder:
+ sculptType = PrimMesher.SculptMesh.SculptType.cylinder;
+ break;
+ case OpenMetaverse.SculptType.Plane:
+ sculptType = PrimMesher.SculptMesh.SculptType.plane;
+ break;
+ case OpenMetaverse.SculptType.Torus:
+ sculptType = PrimMesher.SculptMesh.SculptType.torus;
+ break;
+ case OpenMetaverse.SculptType.Sphere:
+ default:
+ sculptType = PrimMesher.SculptMesh.SculptType.sphere;
+ break;
+ }
+ sculptMesh = new PrimMesher.SculptMesh((Bitmap)idata, sculptType, (int)lod, false);
+
+ idata.Dispose();
+
+ sculptMesh.DumpRaw(baseDir, primName, "primMesh");
+
+ sculptMesh.Scale(size.X, size.Y, size.Z);
+
+ coords = sculptMesh.coords;
+ faces = sculptMesh.faces;
}
- int hollowSides = sides;
- if (primShape.HollowShape == HollowShape.Circle)
- hollowSides = 24;
- else if (primShape.HollowShape == HollowShape.Square)
- hollowSides = 4;
- else if (primShape.HollowShape == HollowShape.Triangle)
- hollowSides = 3;
-
- PrimMesh primMesh = new PrimMesh(sides, profileBegin, profileEnd, profileHollow, hollowSides);
-
- primMesh.topShearX = pathShearX;
- primMesh.topShearY = pathShearY;
- primMesh.pathCutBegin = pathBegin;
- primMesh.pathCutEnd = pathEnd;
-
- if (primShape.PathCurve == (byte)Extrusion.Straight)
+ else
{
- primMesh.twistBegin = primShape.PathTwistBegin * 18 / 10;
- primMesh.twistEnd = primShape.PathTwist * 18 / 10;
- primMesh.taperX = pathScaleX;
- primMesh.taperY = pathScaleY;
+ float pathShearX = primShape.PathShearX < 128 ? (float)primShape.PathShearX * 0.01f : (float)(primShape.PathShearX - 256) * 0.01f;
+ float pathShearY = primShape.PathShearY < 128 ? (float)primShape.PathShearY * 0.01f : (float)(primShape.PathShearY - 256) * 0.01f;
+ float pathBegin = (float)primShape.PathBegin * 2.0e-5f;
+ float pathEnd = 1.0f - (float)primShape.PathEnd * 2.0e-5f;
+ float pathScaleX = (float)(primShape.PathScaleX - 100) * 0.01f;
+ float pathScaleY = (float)(primShape.PathScaleY - 100) * 0.01f;
+
+ float profileBegin = (float)primShape.ProfileBegin * 2.0e-5f;
+ float profileEnd = 1.0f - (float)primShape.ProfileEnd * 2.0e-5f;
+ float profileHollow = (float)primShape.ProfileHollow * 2.0e-5f;
+
+ int sides = 4;
+ if ((primShape.ProfileCurve & 0x07) == (byte)ProfileShape.EquilateralTriangle)
+ sides = 3;
+ else if ((primShape.ProfileCurve & 0x07) == (byte)ProfileShape.Circle)
+ sides = 24;
+ else if ((primShape.ProfileCurve & 0x07) == (byte)ProfileShape.HalfCircle)
+ { // half circle, prim is a sphere
+ sides = 24;
+
+ profileBegin = 0.5f * profileBegin + 0.5f;
+ profileEnd = 0.5f * profileEnd + 0.5f;
- if (profileBegin < 0.0f || profileBegin >= profileEnd || profileEnd > 1.0f)
- {
- ReportPrimError("*** CORRUPT PRIM!! ***", primName, primMesh);
- if (profileBegin < 0.0f) profileBegin = 0.0f;
- if (profileEnd > 1.0f) profileEnd = 1.0f;
}
+
+ int hollowSides = sides;
+ if (primShape.HollowShape == HollowShape.Circle)
+ hollowSides = 24;
+ else if (primShape.HollowShape == HollowShape.Square)
+ hollowSides = 4;
+ else if (primShape.HollowShape == HollowShape.Triangle)
+ hollowSides = 3;
+
+ primMesh = new PrimMesh(sides, profileBegin, profileEnd, profileHollow, hollowSides);
+
+ primMesh.topShearX = pathShearX;
+ primMesh.topShearY = pathShearY;
+ primMesh.pathCutBegin = pathBegin;
+ primMesh.pathCutEnd = pathEnd;
+
+ if (primShape.PathCurve == (byte)Extrusion.Straight)
+ {
+ primMesh.twistBegin = primShape.PathTwistBegin * 18 / 10;
+ primMesh.twistEnd = primShape.PathTwist * 18 / 10;
+ primMesh.taperX = pathScaleX;
+ primMesh.taperY = pathScaleY;
+
+ if (profileBegin < 0.0f || profileBegin >= profileEnd || profileEnd > 1.0f)
+ {
+ ReportPrimError("*** CORRUPT PRIM!! ***", primName, primMesh);
+ if (profileBegin < 0.0f) profileBegin = 0.0f;
+ if (profileEnd > 1.0f) profileEnd = 1.0f;
+ }
#if SPAM
Console.WriteLine("****** PrimMesh Parameters (Linear) ******\n" + primMesh.ParamsToDisplayString());
#endif
- try
- {
- primMesh.ExtrudeLinear();
+ try
+ {
+ primMesh.ExtrudeLinear();
+ }
+ catch (Exception ex)
+ {
+ ReportPrimError("Extrusion failure: exception: " + ex.ToString(), primName, primMesh);
+ return null;
+ }
}
- catch (Exception ex)
+ else
{
- ReportPrimError("Extrusion failure: exception: " + ex.ToString(), primName, primMesh);
- return null;
- }
- }
- else
- {
- primMesh.holeSizeX = (200 - primShape.PathScaleX) * 0.01f;
- primMesh.holeSizeY = (200 - primShape.PathScaleY) * 0.01f;
- primMesh.radius = 0.01f * primShape.PathRadiusOffset;
- primMesh.revolutions = 1.0f + 0.015f * primShape.PathRevolutions;
- primMesh.skew = 0.01f * primShape.PathSkew;
- primMesh.twistBegin = primShape.PathTwistBegin * 36 / 10;
- primMesh.twistEnd = primShape.PathTwist * 36 / 10;
- primMesh.taperX = primShape.PathTaperX * 0.01f;
- primMesh.taperY = primShape.PathTaperY * 0.01f;
+ primMesh.holeSizeX = (200 - primShape.PathScaleX) * 0.01f;
+ primMesh.holeSizeY = (200 - primShape.PathScaleY) * 0.01f;
+ primMesh.radius = 0.01f * primShape.PathRadiusOffset;
+ primMesh.revolutions = 1.0f + 0.015f * primShape.PathRevolutions;
+ primMesh.skew = 0.01f * primShape.PathSkew;
+ primMesh.twistBegin = primShape.PathTwistBegin * 36 / 10;
+ primMesh.twistEnd = primShape.PathTwist * 36 / 10;
+ primMesh.taperX = primShape.PathTaperX * 0.01f;
+ primMesh.taperY = primShape.PathTaperY * 0.01f;
- if (profileBegin < 0.0f || profileBegin >= profileEnd || profileEnd > 1.0f)
- {
- ReportPrimError("*** CORRUPT PRIM!! ***", primName, primMesh);
- if (profileBegin < 0.0f) profileBegin = 0.0f;
- if (profileEnd > 1.0f) profileEnd = 1.0f;
- }
+ if (profileBegin < 0.0f || profileBegin >= profileEnd || profileEnd > 1.0f)
+ {
+ ReportPrimError("*** CORRUPT PRIM!! ***", primName, primMesh);
+ if (profileBegin < 0.0f) profileBegin = 0.0f;
+ if (profileEnd > 1.0f) profileEnd = 1.0f;
+ }
#if SPAM
Console.WriteLine("****** PrimMesh Parameters (Circular) ******\n" + primMesh.ParamsToDisplayString());
#endif
- try
- {
- primMesh.ExtrudeCircular();
- }
- catch (Exception ex)
- {
- ReportPrimError("Extrusion failure: exception: " + ex.ToString(), primName, primMesh);
- return null;
+ try
+ {
+ primMesh.ExtrudeCircular();
+ }
+ catch (Exception ex)
+ {
+ ReportPrimError("Extrusion failure: exception: " + ex.ToString(), primName, primMesh);
+ return null;
+ }
}
+
+ primMesh.DumpRaw(baseDir, primName, "primMesh");
+
+ primMesh.Scale(size.X, size.Y, size.Z);
+
+ coords = primMesh.coords;
+ faces = primMesh.faces;
+
}
- primMesh.DumpRaw(baseDir, primName, "primMesh");
- primMesh.Scale(size.X, size.Y, size.Z);
+ int numCoords = coords.Count;
+ int numFaces = faces.Count;
- int numCoords = primMesh.coords.Count;
- int numFaces = primMesh.faces.Count;
-
- List coords = primMesh.coords;
for (int i = 0; i < numCoords; i++)
{
Coord c = coords[i];
mesh.vertices.Add(new Vertex(c.X, c.Y, c.Z));
}
- List faces = primMesh.faces;
List vertices = mesh.vertices;
-
for (int i = 0; i < numFaces; i++)
{
Face f = faces[i];
mesh.triangles.Add(new Triangle(vertices[f.v1], vertices[f.v2], vertices[f.v3]));
}
- //for (int i = 0; i < numFaces; i++)
- //{
- // Face f = primMesh.faces[i];
- // Coord vert = primMesh.coords[f.v1];
- // Vertex v1 = new Vertex(vert.X, vert.Y, vert.Z);
- // mesh.vertices.Add(v1);
- // vert = primMesh.coords[f.v2];
- // Vertex v2 = new Vertex(vert.X, vert.Y, vert.Z);
- // mesh.vertices.Add(v2);
- // vert = primMesh.coords[f.v3];
- // Vertex v3 = new Vertex(vert.X, vert.Y, vert.Z);
- // mesh.vertices.Add(v3);
- // mesh.triangles.Add(new Triangle(v1, v2, v3));
- //}
-
- //mesh.DumpRaw(baseDir, primName, "Mesh");
-
- //mesh.primMesh = primMesh;
-
return mesh;
}
@@ -1794,83 +360,16 @@ namespace OpenSim.Region.Physics.Meshing
if (size.Y < 0.01f) size.Y = 0.01f;
if (size.Z < 0.01f) size.Z = 0.01f;
-#if SPAM
- reportPrimParams(primName, primShape);
-#endif
-
- if (primShape.SculptEntry && primShape.SculptType != (byte)0 && primShape.SculptData.Length > 0)
- {
- SculptMesh smesh = CreateSculptMesh(primName, primShape, size, lod);
- mesh = (Mesh)smesh;
- }
-
- else if (usePrimMesher)
- {
- mesh = CreateMeshFromPrimMesher(primName, primShape, size, lod);
- }
- else if ((primShape.ProfileCurve & 0x07) == (byte)ProfileShape.Square)
- {
- if (primShape.PathCurve == (byte)Extrusion.Straight)
- { // its a box
- mesh = CreateBoxMesh(primName, primShape, size);
- //mesh = CreateMeshFromPrimMesher(primName, primShape, size, lod);
- }
- else if (primShape.PathCurve == (byte)Extrusion.Curve1)
- { // tube
- // do a cylinder for now
- mesh = CreateCylinderMesh(primName, primShape, size);
- //mesh = CreateMeshFromPrimMesher(primName, primShape, size, lod);
- }
- }
- else if ((primShape.ProfileCurve & 0x07) == (byte)ProfileShape.Circle)
- {
- if (primShape.PathCurve == (byte)Extrusion.Straight)
- {
- mesh = CreateCylinderMesh(primName, primShape, size);
- //mesh = CreateMeshFromPrimMesher(primName, primShape, size, lod);
- }
-
- // ProfileCurve seems to combine hole shape and profile curve so we need to only compare against the lower 3 bits
- else if (primShape.PathCurve == (byte) Extrusion.Curve1)
- { // dahlia's favorite, a torus :)
- mesh = CreateCircularPathMesh(primName, primShape, size);
- //mesh = CreateMeshFromPrimMesher(primName, primShape, size, lod);\
- }
- }
- else if ((primShape.ProfileCurve & 0x07) == (byte)ProfileShape.HalfCircle)
- {
- if (primShape.PathCurve == (byte)Extrusion.Curve1 || primShape.PathCurve == (byte) Extrusion.Curve2)
- {
- //mesh = CreateSphereMesh(primName, primShape, size);
- mesh = CreateCircularPathMesh(primName, primShape, size);
- //mesh = CreateMeshFromPrimMesher(primName, primShape, size, lod);
- }
- }
- else if ((primShape.ProfileCurve & 0x07) == (byte)ProfileShape.EquilateralTriangle)
- {
- if (primShape.PathCurve == (byte)Extrusion.Straight)
- {
- mesh = CreatePrismMesh(primName, primShape, size);
- //mesh = CreateMeshFromPrimMesher(primName, primShape, size, lod);
- }
- else if (primShape.PathCurve == (byte) Extrusion.Curve1)
- { // a ring - do a cylinder for now
- //mesh = CreateCylinderMesh(primName, primShape, size);
- mesh = CreateCircularPathMesh(primName, primShape, size);
- //mesh = CreateMeshFromPrimMesher(primName, primShape, size, lod);
- }
- }
- else // just do a box
- {
- mesh = CreateBoxMesh(primName, primShape, size);
- }
+ mesh = CreateMeshFromPrimMesher(primName, primShape, size, lod);
if (mesh != null)
{
if ((!isPhysical) && size.X < minSizeForComplexMesh && size.Y < minSizeForComplexMesh && size.Z < minSizeForComplexMesh)
{
#if SPAM
- Console.WriteLine("Meshmerizer: prim " + primName + " has a size of " + size.ToString() + " which is below threshold of " + minSizeForComplexMesh.ToString() + " - creating simple bounding box" );
+ Console.WriteLine("Meshmerizer: prim " + primName + " has a size of " + size.ToString() + " which is below threshold of " +
+
+minSizeForComplexMesh.ToString() + " - creating simple bounding box" );
#endif
mesh = CreateBoundingBoxMesh(mesh);
mesh.DumpRaw(baseDir, primName, "Z extruded");
@@ -1884,6 +383,8 @@ namespace OpenSim.Region.Physics.Meshing
return mesh;
}
+
+
#if SPAM
// please dont comment this out until I'm done with this module - dahlia
private static void reportPrimParams(string name, PrimitiveBaseShape primShape)
diff --git a/OpenSim/Region/Physics/Meshing/PrimMesher.cs b/OpenSim/Region/Physics/Meshing/PrimMesher.cs
index 282bbd5dd7..d79a480a02 100644
--- a/OpenSim/Region/Physics/Meshing/PrimMesher.cs
+++ b/OpenSim/Region/Physics/Meshing/PrimMesher.cs
@@ -1,5 +1,5 @@
/*
- * Copyright (c) Contributors, http://opensimulator.org/
+ * Copyright (c) Contributors
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
@@ -243,10 +243,11 @@ namespace PrimMesher
public int n2;
public int n3;
- //// UVs
- //public int uv1;
- //public int uv2;
- //public int uv3;
+ // uvs
+ public int uv1;
+ public int uv2;
+ public int uv3;
+
public Face(int v1, int v2, int v3)
{
@@ -260,9 +261,10 @@ namespace PrimMesher
this.n2 = 0;
this.n3 = 0;
- //this.uv1 = 0;
- //this.uv2 = 0;
- //this.uv3 = 0;
+ this.uv1 = 0;
+ this.uv2 = 0;
+ this.uv3 = 0;
+
}
public Face(int v1, int v2, int v3, int n1, int n2, int n3)
@@ -277,9 +279,21 @@ namespace PrimMesher
this.n2 = n2;
this.n3 = n3;
- //this.uv1 = 0;
- //this.uv2 = 0;
- //this.uv3 = 0;
+ this.uv1 = 0;
+ this.uv2 = 0;
+ this.uv3 = 0;
+ }
+
+ public Coord SurfaceNormal(List coordList)
+ {
+ Coord c1 = coordList[this.v1];
+ Coord c2 = coordList[this.v2];
+ Coord c3 = coordList[this.v3];
+
+ Coord edge1 = new Coord(c2.X - c1.X, c2.Y - c1.Y, c2.Z - c1.Z);
+ Coord edge2 = new Coord(c3.X - c1.X, c3.Y - c1.Y, c3.Z - c1.Z);
+
+ return Coord.Cross(edge1, edge2).Normalize();
}
}
@@ -560,7 +574,7 @@ namespace PrimMesher
///
/// generates a profile for extrusion
///
- public class Profile
+ internal class Profile
{
private const float twoPi = 2.0f * (float)Math.PI;
@@ -569,6 +583,7 @@ namespace PrimMesher
internal List vertexNormals;
internal List us;
internal List faceUVs;
+ internal List faceNumbers;
internal Coord faceNormal = new Coord(0.0f, 0.0f, 1.0f);
internal Coord cutNormal1 = new Coord();
@@ -578,6 +593,8 @@ namespace PrimMesher
internal int numHollowVerts = 0;
internal bool calcVertexNormals = false;
+ internal int bottomFaceNumber = 0;
+ internal int numPrimFaces = 0;
internal Profile()
{
@@ -586,9 +603,10 @@ namespace PrimMesher
this.vertexNormals = new List();
this.us = new List();
this.faceUVs = new List();
+ this.faceNumbers = new List();
}
- public Profile(int sides, float profileStart, float profileEnd, float hollow, int hollowSides, bool createFaces, bool calcVertexNormals)
+ internal Profile(int sides, float profileStart, float profileEnd, float hollow, int hollowSides, bool createFaces, bool calcVertexNormals)
{
this.calcVertexNormals = calcVertexNormals;
this.coords = new List();
@@ -596,6 +614,8 @@ namespace PrimMesher
this.vertexNormals = new List();
this.us = new List();
this.faceUVs = new List();
+ this.faceNumbers = new List();
+
Coord center = new Coord(0.0f, 0.0f, 0.0f);
List hollowCoords = new List();
@@ -674,7 +694,7 @@ namespace PrimMesher
hollowCoords.Add(newVert);
if (this.calcVertexNormals)
{
- if (sides < 5)
+ if (hollowSides < 5)
hollowNormals.Add(hollowAngles.normals[i].Invert());
else
hollowNormals.Add(new Coord(-angle.X, -angle.Y, 0.0f));
@@ -689,7 +709,7 @@ namespace PrimMesher
for (int i = 0; i < numAngles; i++)
{
- //int iNext = i == numAngles ? i + 1 : 0;
+ int iNext = i == numAngles ? i + 1 : 0;
angle = angles.angles[i];
newVert.X = angle.X * xScale;
newVert.Y = angle.Y * yScale;
@@ -884,21 +904,46 @@ namespace PrimMesher
hollowNormals = null;
hollowUs = null;
+ if (calcVertexNormals)
+ { // calculate prim face numbers
+ // I know it's ugly but so is the whole concept of prim face numbers
+ int faceNum = 1;
+ int startVert = hasProfileCut && !hasHollow ? 1 : 0;
+ if (startVert > 0)
+ this.faceNumbers.Add(0);
+ for (int i = 0; i < numOuterVerts; i++)
+ this.faceNumbers.Add(sides < 5 ? faceNum++ : faceNum);
+ if (sides > 4)
+ faceNum++;
+ if (hasProfileCut)
+ this.faceNumbers.Add(0);
+ for (int i = 0; i < numHollowVerts; i++)
+ this.faceNumbers.Add(faceNum++);
+ this.bottomFaceNumber = faceNum++;
+ if (hasHollow && hasProfileCut)
+ this.faceNumbers.Add(faceNum++);
+ for (int i = 0; i < this.faceNumbers.Count; i++)
+ if (this.faceNumbers[i] == 0)
+ this.faceNumbers[i] = faceNum++;
+
+ this.numPrimFaces = faceNum;
+ }
+
}
- public void MakeFaceUVs()
+ internal void MakeFaceUVs()
{
this.faceUVs = new List();
foreach (Coord c in this.coords)
this.faceUVs.Add(new UVCoord(1.0f - (0.5f + c.X), 1.0f - (0.5f - c.Y)));
}
- public Profile Clone()
+ internal Profile Clone()
{
return this.Clone(true);
}
- public Profile Clone(bool needFaces)
+ internal Profile Clone(bool needFaces)
{
Profile clone = new Profile();
@@ -914,6 +959,7 @@ namespace PrimMesher
clone.cutNormal1 = this.cutNormal1;
clone.cutNormal2 = this.cutNormal2;
clone.us.AddRange(this.us);
+ clone.faceNumbers.AddRange(this.faceNumbers);
}
clone.numOuterVerts = this.numOuterVerts;
clone.numHollowVerts = this.numHollowVerts;
@@ -921,12 +967,12 @@ namespace PrimMesher
return clone;
}
- public void AddPos(Coord v)
+ internal void AddPos(Coord v)
{
this.AddPos(v.X, v.Y, v.Z);
}
- public void AddPos(float x, float y, float z)
+ internal void AddPos(float x, float y, float z)
{
int i;
int numVerts = this.coords.Count;
@@ -942,7 +988,7 @@ namespace PrimMesher
}
}
- public void AddRot(Quat q)
+ internal void AddRot(Quat q)
{
int i;
int numVerts = this.coords.Count;
@@ -963,7 +1009,7 @@ namespace PrimMesher
}
}
- public void Scale(float x, float y)
+ internal void Scale(float x, float y)
{
int i;
int numVerts = this.coords.Count;
@@ -981,7 +1027,7 @@ namespace PrimMesher
///
/// Changes order of the vertex indices and negates the center vertex normal. Does not alter vertex normals of radial vertices
///
- public void FlipNormals()
+ internal void FlipNormals()
{
int i;
int numFaces = this.faces.Count;
@@ -1021,7 +1067,7 @@ namespace PrimMesher
}
}
- public void AddValue2FaceVertexIndices(int num)
+ internal void AddValue2FaceVertexIndices(int num)
{
int numFaces = this.faces.Count;
Face tmpFace;
@@ -1036,7 +1082,7 @@ namespace PrimMesher
}
}
- public void AddValue2FaceNormalIndices(int num)
+ internal void AddValue2FaceNormalIndices(int num)
{
if (this.calcVertexNormals)
{
@@ -1054,7 +1100,7 @@ namespace PrimMesher
}
}
- public void DumpRaw(String path, String name, String title)
+ internal void DumpRaw(String path, String name, String title)
{
if (path == null)
return;
@@ -1113,6 +1159,12 @@ namespace PrimMesher
private bool normalsProcessed = false;
public bool viewerMode = false;
+ public int numPrimFaces = 0;
+
+ ///
+ /// Human readable string representation of the parameters used to create a mesh.
+ ///
+ ///
public string ParamsToDisplayString()
{
string s = "";
@@ -1141,7 +1193,14 @@ namespace PrimMesher
return s;
}
-
+ ///
+ /// Constructs a PrimMesh object and creates the profile for extrusion.
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
public PrimMesh(int sides, float profileStart, float profileEnd, float hollow, int hollowSides)
{
this.coords = new List();
@@ -1174,6 +1233,9 @@ namespace PrimMesher
this.hasHollow = (this.hollow > 0.001f);
}
+ ///
+ /// Extrudes a profile along a straight line path. Used for prim types box, cylinder, and prism.
+ ///
public void ExtrudeLinear()
{
this.coords = new List();
@@ -1248,6 +1310,7 @@ namespace PrimMesher
hollow *= 1.414f;
Profile profile = new Profile(this.sides, this.profileStart, this.profileEnd, hollow, this.hollowSides, true, calcVertexNormals);
+ this.numPrimFaces = profile.numPrimFaces;
int cut1Vert = -1;
int cut2Vert = -1;
@@ -1398,7 +1461,7 @@ namespace PrimMesher
if (u2 < 0.1f)
u2 = 1.0f;
- newViewerFace2.primFaceNumber = newViewerFace1.primFaceNumber = whichVert + 1;
+ //newViewerFace2.primFaceNumber = newViewerFace1.primFaceNumber = whichVert + 1;
}
newViewerFace1.uv1.U = u1;
@@ -1462,6 +1525,8 @@ namespace PrimMesher
}
}
+ newViewerFace2.primFaceNumber = newViewerFace1.primFaceNumber = newLayer.faceNumbers[whichVert];
+
this.viewerFaces.Add(newViewerFace1);
this.viewerFaces.Add(newViewerFace2);
@@ -1492,7 +1557,7 @@ namespace PrimMesher
// add the top faces to the viewerFaces list here
Coord faceNormal = newLayer.faceNormal;
ViewerFace newViewerFace = new ViewerFace();
- newViewerFace.primFaceNumber = 0;
+ newViewerFace.primFaceNumber = newLayer.bottomFaceNumber;
foreach (Face face in newLayer.faces)
{
newViewerFace.v1 = newLayer.coords[face.v1 - coordsLen];
@@ -1513,6 +1578,9 @@ namespace PrimMesher
}
}
+ ///
+ /// Extrude a profile into a circular path prim mesh. Used for prim types torus, tube, and ring.
+ ///
public void ExtrudeCircular()
{
this.coords = new List();
@@ -1615,6 +1683,7 @@ namespace PrimMesher
needEndFaces = true;
Profile profile = new Profile(this.sides, this.profileStart, this.profileEnd, hollow, this.hollowSides, needEndFaces, calcVertexNormals);
+ this.numPrimFaces = profile.numPrimFaces;
int cut1Vert = -1;
int cut2Vert = -1;
@@ -1787,7 +1856,7 @@ namespace PrimMesher
if (u2 < 0.1f)
u2 = 1.0f;
- newViewerFace2.primFaceNumber = newViewerFace1.primFaceNumber = whichVert + 1;
+ //newViewerFace2.primFaceNumber = newViewerFace1.primFaceNumber = whichVert + 1;
}
newViewerFace1.uv1.U = u1;
@@ -1865,6 +1934,7 @@ namespace PrimMesher
}
}
+ newViewerFace1.primFaceNumber = newViewerFace2.primFaceNumber = newLayer.faceNumbers[whichVert];
this.viewerFaces.Add(newViewerFace1);
this.viewerFaces.Add(newViewerFace2);
@@ -1894,7 +1964,7 @@ namespace PrimMesher
// add the bottom faces to the viewerFaces list here
Coord faceNormal = newLayer.faceNormal;
ViewerFace newViewerFace = new ViewerFace();
- newViewerFace.primFaceNumber = 0;
+ newViewerFace.primFaceNumber = newLayer.bottomFaceNumber;
foreach (Face face in newLayer.faces)
{
newViewerFace.v1 = newLayer.coords[face.v1 - coordsLen];
@@ -1932,6 +2002,11 @@ namespace PrimMesher
return SurfaceNormal(this.coords[face.v1], this.coords[face.v2], this.coords[face.v3]);
}
+ ///
+ /// Calculate the surface normal for a face in the list of faces
+ ///
+ ///
+ ///
public Coord SurfaceNormal(int faceIndex)
{
int numFaces = this.faces.Count;
@@ -1941,6 +2016,9 @@ namespace PrimMesher
return SurfaceNormal(this.faces[faceIndex]);
}
+ ///
+ /// Calculate surface normals for all of the faces in the list of faces in this mesh
+ ///
public void CalcNormals()
{
if (normalsProcessed)
@@ -1968,6 +2046,12 @@ namespace PrimMesher
}
}
+ ///
+ /// Adds a value to each XYZ vertex coordinate in the mesh
+ ///
+ ///
+ ///
+ ///
public void AddPos(float x, float y, float z)
{
int i;
@@ -1984,9 +2068,12 @@ namespace PrimMesher
}
}
+ ///
+ /// Rotates the mesh
+ ///
+ ///
public void AddRot(Quat q)
{
- Console.WriteLine("AddRot(" + q.ToString() + ")");
int i;
int numVerts = this.coords.Count;
@@ -2020,6 +2107,12 @@ namespace PrimMesher
}
+ ///
+ /// Scales the mesh
+ ///
+ ///
+ ///
+ ///
public void Scale(float x, float y, float z)
{
int i;
@@ -2046,6 +2139,12 @@ namespace PrimMesher
}
+ ///
+ /// Dumps the mesh to a Blender compatible "Raw" format file
+ ///
+ ///
+ ///
+ ///
public void DumpRaw(String path, String name, String title)
{
if (path == null)
diff --git a/OpenSim/Region/Physics/Meshing/SculptMesh.cs b/OpenSim/Region/Physics/Meshing/SculptMesh.cs
index 0dc7ef2028..826030bad2 100644
--- a/OpenSim/Region/Physics/Meshing/SculptMesh.cs
+++ b/OpenSim/Region/Physics/Meshing/SculptMesh.cs
@@ -1,5 +1,5 @@
/*
- * Copyright (c) Contributors, http://opensimulator.org/
+ * Copyright (c) Contributors
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
@@ -27,314 +27,317 @@
using System;
using System.Collections.Generic;
+using System.Text;
+using System.IO;
using System.Drawing;
using System.Drawing.Imaging;
-using System.Text;
-using OpenMetaverse.Imaging;
-namespace OpenSim.Region.Physics.Meshing
+namespace PrimMesher
{
- // This functionality based on the XNA SculptPreview by John Hurliman.
- public class SculptMesh : Mesh
- {
- Image idata = null;
- Bitmap bLOD = null;
- Bitmap bBitmap = null;
- Vertex northpole = new Vertex(0, 0, 0);
- Vertex southpole = new Vertex(0, 0, 0);
+ public class SculptMesh
+ {
+ public List coords;
+ public List faces;
- private int lod = 32;
- private const float RANGE = 128.0f;
+ public List viewerFaces;
+ public List normals;
+ public List uvs;
- public SculptMesh(byte[] jpegData, float _lod)
+ public enum SculptType { sphere = 1, torus = 2, plane = 3, cylinder = 4 };
+ private const float pixScale = 0.00390625f; // 1.0 / 256
+
+ private Bitmap ScaleImage(Bitmap srcImage, float scale)
{
- if (_lod == 2f || _lod == 4f || _lod == 8f || _lod == 16f || _lod == 32f || _lod == 64f)
- lod = (int)_lod;
+ int sourceWidth = srcImage.Width;
+ int sourceHeight = srcImage.Height;
+ int sourceX = 0;
+ int sourceY = 0;
- try
- {
- ManagedImage managedImage; // we never use this
- OpenJPEG.DecodeToImage(jpegData, out managedImage, out idata);
- //int i = 0;
- //i = i / i;
- }
- catch (Exception)
- {
- System.Console.WriteLine("[PHYSICS]: Unable to generate a Sculpty physics proxy. Sculpty texture decode failed!");
- return;
- }
+ int destX = 0;
+ int destY = 0;
+ int destWidth = (int)(sourceWidth * scale);
+ int destHeight = (int)(sourceHeight * scale);
- if (idata != null)
- {
- bBitmap = new Bitmap(idata);
- if (bBitmap.Width == bBitmap.Height)
+ Bitmap scaledImage = new Bitmap(destWidth, destHeight,
+ PixelFormat.Format24bppRgb);
+ scaledImage.SetResolution(srcImage.HorizontalResolution,
+ srcImage.VerticalResolution);
+
+ Graphics grPhoto = Graphics.FromImage(scaledImage);
+ grPhoto.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.Bilinear;
+
+ grPhoto.DrawImage(srcImage,
+ new Rectangle(destX, destY, destWidth, destHeight),
+ new Rectangle(sourceX, sourceY, sourceWidth, sourceHeight),
+ GraphicsUnit.Pixel);
+
+ grPhoto.Dispose();
+ return scaledImage;
+ }
+
+ public SculptMesh SculptMeshFromFile(string fileName, SculptType sculptType, int lod, bool viewerMode)
+ {
+ Bitmap bitmap = (Bitmap)Bitmap.FromFile(fileName);
+ SculptMesh sculptMesh = new SculptMesh(bitmap, sculptType, lod, viewerMode);
+ bitmap.Dispose();
+ return sculptMesh;
+ }
+
+ public SculptMesh(Bitmap sculptBitmap, SculptType sculptType, int lod, bool viewerMode)
+ {
+ coords = new List();
+ faces = new List();
+ normals = new List();
+ uvs = new List();
+
+ float sourceScaleFactor = (float)lod / (float)Math.Max(sculptBitmap.Width, sculptBitmap.Height);
+ bool scaleSourceImage = sourceScaleFactor < 1.0f ? true : false;
+
+ Bitmap bitmap;
+ if (scaleSourceImage)
+ bitmap = ScaleImage(sculptBitmap, sourceScaleFactor);
+ else
+ bitmap = sculptBitmap;
+
+ viewerFaces = new List();
+
+ int width = bitmap.Width;
+ int height = bitmap.Height;
+
+ float widthUnit = 1.0f / width;
+ float heightUnit = 1.0f / (height - 1);
+
+ int p1, p2, p3, p4;
+ Color color;
+ float x, y, z;
+
+ int imageX, imageY;
+
+ if (sculptType == SculptType.sphere)
+ { // average the top and bottom row pixel values so the resulting vertices appear to converge
+ int lastRow = height - 1;
+ int r1 = 0, g1 = 0, b1 = 0;
+ int r2 = 0, g2 = 0, b2 = 0;
+ for (imageX = 0; imageX < width; imageX++)
{
- DoLOD();
+ Color c1 = bitmap.GetPixel(imageX, 0);
+ Color c2 = bitmap.GetPixel(imageX, lastRow);
- LoadPoles();
+ r1 += c1.R;
+ g1 += c1.G;
+ b1 += c1.B;
- processSculptTexture();
+ r2 += c2.R;
+ g2 += c2.G;
+ b2 += c2.B;
+ }
- bLOD.Dispose();
- bBitmap.Dispose();
- idata.Dispose();
+ Color newC1 = Color.FromArgb(r1 / width, g1 / width, b1 / width);
+ Color newC2 = Color.FromArgb(r2 / width, g2 / width, b2 / width);
+
+ for (imageX = 0; imageX < width; imageX++)
+ {
+ bitmap.SetPixel(imageX, 0, newC1);
+ bitmap.SetPixel(imageX, lastRow, newC2);
}
}
- }
-
- private Vertex ColorToVertex(Color input)
- {
- return new Vertex(
- ((float)input.R - 128) / RANGE,
- ((float)input.G - 128) / RANGE,
- ((float)input.B - 128) / RANGE);
- }
-
- private void LoadPoles()
- {
- northpole = new Vertex(0, 0, 0);
- for (int x = 0; x < bLOD.Width; x++)
- {
- northpole += ColorToVertex(GetPixel(0, 0));
- }
- northpole /= bLOD.Width;
- southpole = new Vertex(0, 0, 0);
- for (int x = 0; x < bLOD.Width; x++)
- {
- //System.Console.WriteLine("Height: " + bLOD.Height.ToString());
- southpole += ColorToVertex(GetPixel(bLOD.Height - 1, (bLOD.Height - 1)));
- }
- southpole /= bBitmap.Width;
- }
- private Color GetPixel(int x, int y)
- {
- return bLOD.GetPixel(x, y);
- }
+ int pixelsAcross = sculptType == SculptType.plane ? width : width + 1;
+ int pixelsDown = sculptType == SculptType.sphere || sculptType == SculptType.cylinder ? height + 1 : height;
- public int LOD
- {
- get
+ for (imageY = 0; imageY < pixelsDown; imageY++)
{
- return (int)Math.Log(Scale, 2);
- }
- set
- {
- int power = value;
- if (power == 0)
- power = 6;
- if (power < 2)
- power = 2;
- if (power > 9)
- power = 9;
- int t = (int)Math.Pow(2, power);
- if (t != Scale)
+ int rowOffset = imageY * width;
+
+ for (imageX = 0; imageX < pixelsAcross; imageX++)
{
- lod = t;
- }
- }
- }
+ /*
+ * p1-----p2
+ * | \ f2 |
+ * | \ |
+ * | f1 \|
+ * p3-----p4
+ */
- public int Scale
- {
- get
- {
- return lod;
- }
- }
-
- private void DoLOD()
- {
- int x_max = Math.Min(Scale, bBitmap.Width);
- int y_max = Math.Min(Scale, bBitmap.Height);
- if (bBitmap.Width == x_max && bBitmap.Height == y_max)
- bLOD = bBitmap;
-
- else if (bLOD == null || x_max != bLOD.Width || y_max != bLOD.Height)//don't resize if you don't need to.
- {
- System.Drawing.Bitmap tile = new System.Drawing.Bitmap(bBitmap.Width * 2, bBitmap.Height, PixelFormat.Format24bppRgb);
- System.Drawing.Bitmap tile_LOD = new System.Drawing.Bitmap(x_max * 2, y_max, PixelFormat.Format24bppRgb);
-
- bLOD = new System.Drawing.Bitmap(x_max, y_max, PixelFormat.Format24bppRgb);
- bLOD.SetResolution(bBitmap.HorizontalResolution, bBitmap.VerticalResolution);
-
- System.Drawing.Graphics grPhoto = System.Drawing.Graphics.FromImage(tile);
- grPhoto.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor;
-
- grPhoto.DrawImage(bBitmap,
- new System.Drawing.Rectangle(0, 0, bBitmap.Width / 2, bBitmap.Height),
- new System.Drawing.Rectangle(bBitmap.Width / 2, 0, bBitmap.Width / 2, bBitmap.Height),
- System.Drawing.GraphicsUnit.Pixel);
-
- grPhoto.DrawImage(bBitmap,
- new System.Drawing.Rectangle((3 * bBitmap.Width) / 2, 0, bBitmap.Width / 2, bBitmap.Height),
- new System.Drawing.Rectangle(0, 0, bBitmap.Width / 2, bBitmap.Height),
- System.Drawing.GraphicsUnit.Pixel);
-
- grPhoto.DrawImage(bBitmap,
- new System.Drawing.Rectangle(bBitmap.Width / 2, 0, bBitmap.Width, bBitmap.Height),
- new System.Drawing.Rectangle(0, 0, bBitmap.Width, bBitmap.Height),
- System.Drawing.GraphicsUnit.Pixel);
-
- grPhoto = System.Drawing.Graphics.FromImage(tile_LOD);
- //grPhoto.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBilinear;
- grPhoto.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.Bilinear;
-
- grPhoto.DrawImage(tile,
- new System.Drawing.Rectangle(0, 0, tile_LOD.Width, tile_LOD.Height),
- new System.Drawing.Rectangle(0, 0, tile.Width, tile.Height),
- System.Drawing.GraphicsUnit.Pixel);
-
- grPhoto = System.Drawing.Graphics.FromImage(bLOD);
- grPhoto.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor;
-
- grPhoto.DrawImage(tile_LOD,
- new System.Drawing.Rectangle(0, 0, bLOD.Width, bLOD.Height),
- new System.Drawing.Rectangle(tile_LOD.Width / 4, 0, tile_LOD.Width / 2, tile_LOD.Height),
- System.Drawing.GraphicsUnit.Pixel);
-
- grPhoto.Dispose();
- tile_LOD.Dispose();
- tile.Dispose();
- }
-
- }
-
- public void clearStuff()
- {
- this.triangles.Clear();
- this.vertices.Clear();
- //normals = new float[0];
- }
-
- public void processSculptTexture()
- {
- int x_max = Math.Min(Scale, bBitmap.Width);
- int y_max = Math.Min(Scale, bBitmap.Height);
-
- int COLUMNS = x_max + 1;
-
- Vertex[] sVertices = new Vertex[COLUMNS * y_max];
- //float[] indices = new float[COLUMNS * (y_max - 1) * 6];
-
- for (int y = 0; y < y_max; y++)
- {
- for (int x = 0; x < x_max; x++)
- {
- // Create the vertex
- Vertex v1 = new Vertex(0,0,0);
-
- // Create a vertex position from the RGB channels in the current pixel
- // int ypos = y * bLOD.Width;
-
-
- if (y == 0)
+ if (imageX < width)
{
- v1 = northpole;
- }
- else if (y == y_max - 1)
- {
- v1 = southpole;
+ p4 = rowOffset + imageX;
+ p3 = p4 - 1;
}
else
{
- v1 = ColorToVertex(GetPixel(x, y));
+ p4 = rowOffset; // wrap around to beginning
+ p3 = rowOffset + imageX - 1;
}
- // Add the vertex for use later
- if (!vertices.Contains(v1))
- Add(v1);
+ p2 = p4 - width;
+ p1 = p3 - width;
- sVertices[y * COLUMNS + x] = v1;
- //System.Console.WriteLine("adding: " + v1.ToString());
- }
- //Vertex tempVertex = vertices[y * COLUMNS];
- // sVertices[y * COLUMNS + x_max] = tempVertex;
- }
+ color = bitmap.GetPixel(imageX == width ? 0 : imageX, imageY == height ? height - 1 : imageY);
- // Create the Triangles
- //int i = 0;
+ x = (color.R - 128) * pixScale;
+ y = (color.G - 128) * pixScale;
+ z = (color.B - 128) * pixScale;
- for (int y = 0; y < y_max - 1; y++)
- {
- int x;
-
- for (x = 0; x < x_max; x++)
- {
- Vertex vt11 = sVertices[(y * COLUMNS + x)];
- Vertex vt12 = sVertices[(y * COLUMNS + (x + 1))];
- Vertex vt13 = sVertices[((y + 1) * COLUMNS + (x + 1))];
- if (vt11 != null && vt12 != null && vt13 != null)
+ Coord c = new Coord(x, y, z);
+ this.coords.Add(c);
+ if (viewerMode)
{
- if (vt11 != vt12 && vt11 != vt13 && vt12 != vt13)
- {
- Triangle tri1 = new Triangle(vt11, vt12, vt13);
- //indices[i++] = (ushort)(y * COLUMNS + x);
- //indices[i++] = (ushort)(y * COLUMNS + (x + 1));
- //indices[i++] = (ushort)((y + 1) * COLUMNS + (x + 1));
- Add(tri1);
- }
+ this.normals.Add(new Coord());
+ this.uvs.Add(new UVCoord(widthUnit * imageX, heightUnit * imageY));
}
- Vertex vt21 = sVertices[(y * COLUMNS + x)];
- Vertex vt22 = sVertices[((y + 1) * COLUMNS + (x + 1))];
- Vertex vt23 = sVertices[((y + 1) * COLUMNS + x)];
- if (vt21 != null && vt22 != null && vt23 != null)
+ if (imageY > 0 && imageX > 0)
{
- if (vt21.Equals(vt22, 0.022f) || vt21.Equals(vt23, 0.022f) || vt22.Equals(vt23, 0.022f))
+ Face f1, f2;
+
+ if (viewerMode)
{
+ f1 = new Face(p1, p3, p4, p1, p3, p4);
+ f1.uv1 = p1;
+ f1.uv2 = p3;
+ f1.uv3 = p4;
+
+ f2 = new Face(p1, p4, p2, p1, p4, p2);
+ f2.uv1 = p1;
+ f2.uv2 = p4;
+ f2.uv3 = p2;
}
else
{
- Triangle tri2 = new Triangle(vt21, vt22, vt23);
- //indices[i++] = (ushort)(y * COLUMNS + x);
- //indices[i++] = (ushort)((y + 1) * COLUMNS + (x + 1));
- //indices[i++] = (ushort)((y + 1) * COLUMNS + x);
- Add(tri2);
+ f1 = new Face(p1, p3, p4);
+ f2 = new Face(p1, p4, p2);
}
+
+ this.faces.Add(f1);
+ this.faces.Add(f2);
}
-
}
- //Vertex vt31 = sVertices[(y * x_max + x)];
- //Vertex vt32 = sVertices[(y * x_max + 0)];
- //Vertex vt33 = sVertices[((y + 1) * x_max + 0)];
- //if (vt31 != null && vt32 != null && vt33 != null)
- //{
- //if (vt31.Equals(vt32, 0.022f) || vt31.Equals(vt33, 0.022f) || vt32.Equals(vt33, 0.022f))
- //{
- //}
- //else
- //{
- //Triangle tri3 = new Triangle(vt31, vt32, vt33);
- // Wrap the last cell in the row around
- //indices[i++] = (ushort)(y * x_max + x); //a
- //indices[i++] = (ushort)(y * x_max + 0); //b
- //indices[i++] = (ushort)((y + 1) * x_max + 0); //c
- //Add(tri3);
- // }
- //}
-
- //Vertex vt41 = sVertices[(y * x_max + x)];
- //Vertex vt42 = sVertices[((y + 1) * x_max + 0)];
- //Vertex vt43 = sVertices[((y + 1) * x_max + x)];
- //if (vt41 != null && vt42 != null && vt43 != null)
- //{
- //if (vt41.Equals(vt42, 0.022f) || vt31.Equals(vt43, 0.022f) || vt32.Equals(vt43, 0.022f))
- //{
- //}
- // else
- // {
- //Triangle tri4 = new Triangle(vt41, vt42, vt43);
- //indices[i++] = (ushort)(y * x_max + x); //a
- //indices[i++] = (ushort)((y + 1) * x_max + 0); //b
- //indices[i++] = (ushort)((y + 1) * x_max + x); //c
- //Add(tri4);
- //}
- //}
-
}
+
+ if (scaleSourceImage)
+ bitmap.Dispose();
+
+ if (viewerMode)
+ { // compute vertex normals by summing all the surface normals of all the triangles sharing
+ // each vertex and then normalizing
+ int numFaces = this.faces.Count;
+ for (int i = 0; i < numFaces; i++)
+ {
+ Face face = this.faces[i];
+ Coord surfaceNormal = face.SurfaceNormal(this.coords);
+ this.normals[face.v1] += surfaceNormal;
+ this.normals[face.v2] += surfaceNormal;
+ this.normals[face.v3] += surfaceNormal;
+ }
+
+ int numCoords = this.coords.Count;
+ for (int i = 0; i < numCoords; i++)
+ this.coords[i].Normalize();
+
+ if (sculptType != SculptType.plane)
+ { // blend the vertex normals at the cylinder seam
+ pixelsAcross = width + 1;
+ for (imageY = 0; imageY < height; imageY++)
+ {
+ int rowOffset = imageY * pixelsAcross;
+
+ this.normals[rowOffset] = this.normals[rowOffset + width - 1] = (this.normals[rowOffset] + this.normals[rowOffset + width - 1]).Normalize();
+ }
+ }
+
+ foreach (Face face in this.faces)
+ {
+ ViewerFace vf = new ViewerFace(0);
+ vf.v1 = this.coords[face.v1];
+ vf.v2 = this.coords[face.v2];
+ vf.v3 = this.coords[face.v3];
+
+ vf.n1 = this.normals[face.n1];
+ vf.n2 = this.normals[face.n2];
+ vf.n3 = this.normals[face.n3];
+
+ vf.uv1 = this.uvs[face.uv1];
+ vf.uv2 = this.uvs[face.uv2];
+ vf.uv3 = this.uvs[face.uv3];
+
+ this.viewerFaces.Add(vf);
+ }
+ }
+ }
+
+ public void AddRot(Quat q)
+ {
+ int i;
+ int numVerts = this.coords.Count;
+
+ for (i = 0; i < numVerts; i++)
+ this.coords[i] *= q;
+
+ if (this.viewerFaces != null)
+ {
+ int numViewerFaces = this.viewerFaces.Count;
+
+ for (i = 0; i < numViewerFaces; i++)
+ {
+ ViewerFace v = this.viewerFaces[i];
+ v.v1 *= q;
+ v.v2 *= q;
+ v.v3 *= q;
+
+ v.n1 *= q;
+ v.n2 *= q;
+ v.n3 *= q;
+
+ this.viewerFaces[i] = v;
+ }
+ }
+ }
+
+ public void Scale(float x, float y, float z)
+ {
+ int i;
+ int numVerts = this.coords.Count;
+ //Coord vert;
+
+ Coord m = new Coord(x, y, z);
+ for (i = 0; i < numVerts; i++)
+ this.coords[i] *= m;
+
+ if (this.viewerFaces != null)
+ {
+ int numViewerFaces = this.viewerFaces.Count;
+ for (i = 0; i < numViewerFaces; i++)
+ {
+ ViewerFace v = this.viewerFaces[i];
+ v.v1 *= m;
+ v.v2 *= m;
+ v.v3 *= m;
+ this.viewerFaces[i] = v;
+ }
+ }
+ }
+
+ 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);
+
+ for (int i = 0; i < this.faces.Count; i++)
+ {
+ string s = this.coords[this.faces[i].v1].ToString();
+ s += " " + this.coords[this.faces[i].v2].ToString();
+ s += " " + this.coords[this.faces[i].v3].ToString();
+
+ sw.WriteLine(s);
+ }
+
+ sw.Close();
}
}
}
diff --git a/OpenSim/Region/Physics/Meshing/SimpleHull.cs b/OpenSim/Region/Physics/Meshing/SimpleHull.cs
deleted file mode 100644
index 5eeadae132..0000000000
--- a/OpenSim/Region/Physics/Meshing/SimpleHull.cs
+++ /dev/null
@@ -1,394 +0,0 @@
-/*
- * 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 OpenSim.Region.Physics.Manager;
-
-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
- {
- //private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
-
- private List vertices = new List();
- private 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);
- }
-
- public override String ToString()
- {
- String result = String.Empty;
- 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 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
- PhysicsVector intersection = s.RayIntersect(v1, new 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 < v1.Y)
- continue;
- }
- iCounter++;
- }
-
- return iCounter%2 == 1; // Point is inside if the number of intersections is odd
- }
-
- public bool containsPointsFrom(SimpleHull otherHull)
- {
- foreach (Vertex v in otherHull.vertices)
- {
- if (IsPointIn(v))
- return true;
- }
-
- return false;
- }
-
-
- private List buildSimplexList()
- {
- List result = new List();
-
- // Not asserted but assumed: at least three vertices
- for (int i = 0; i < vertices.Count - 1; i++)
- {
- Simplex s = new Simplex(vertices[i], vertices[i + 1]);
- result.Add(s);
- }
- Simplex s1 = new Simplex(vertices[vertices.Count - 1], vertices[0]);
- result.Add(s1);
-
- if (holeVertices.Count == 0)
- return result;
-
- // Same here. At least three vertices in hole assumed
- for (int i = 0; i < holeVertices.Count - 1; i++)
- {
- Simplex s = new Simplex(holeVertices[i], holeVertices[i + 1]);
- result.Add(s);
- }
-
- s1 = new Simplex(holeVertices[holeVertices.Count - 1], holeVertices[0]);
- result.Add(s1);
- return result;
- }
-
-// TODO: unused
-// private bool InsertVertex(Vertex v, int iAfter)
-// {
-// vertices.Insert(iAfter + 1, v);
-// return true;
-// }
-
- private Vertex getNextVertex(Vertex currentVertex)
- {
- int iCurrentIndex;
- iCurrentIndex = vertices.IndexOf(currentVertex);
-
- // Error handling for iCurrentIndex==-1 should go here (and probably never will)
-
- iCurrentIndex++;
- if (iCurrentIndex == vertices.Count)
- iCurrentIndex = 0;
-
- return vertices[iCurrentIndex];
- }
-
- public Vertex FindVertex(Vertex vBase, float tolerance)
- {
- foreach (Vertex v in vertices)
- {
- if (v.IsIdentical(vBase, tolerance))
- return v;
- }
-
- return null;
- }
-
- public void FindIntersection(Simplex s, ref Vertex Intersection, ref Vertex nextVertex)
- {
- Vertex bestIntersection = null;
- float distToV1 = Single.PositiveInfinity;
- Simplex bestIntersectingSimplex = null;
-
- List simple = buildSimplexList();
- foreach (Simplex sTest in simple)
- {
- PhysicsVector vvTemp = Simplex.Intersect(sTest, s, -.001f, -.001f, 0.999f, .999f);
-
- Vertex vTemp = null;
- if (vvTemp != null)
- vTemp = new Vertex(vvTemp);
-
- if (vTemp != null)
- {
- PhysicsVector diff = (s.v1 - vTemp);
- float distTemp = diff.length();
-
- if (bestIntersection == null || distTemp < distToV1)
- {
- bestIntersection = vTemp;
- distToV1 = distTemp;
- bestIntersectingSimplex = sTest;
- }
- }
- }
-
- Intersection = bestIntersection;
- if (bestIntersectingSimplex != null)
- nextVertex = bestIntersectingSimplex.v2;
- else
- nextVertex = null;
- }
-
-
- public static SimpleHull SubtractHull(SimpleHull baseHull, SimpleHull otherHull)
- {
- SimpleHull baseHullClone = baseHull.Clone();
- SimpleHull otherHullClone = otherHull.Clone();
- bool intersects = false;
-
- //m_log.Debug("State before intersection detection");
- //m_log.DebugFormat("The baseHull is:\n{1}", 0, baseHullClone.ToString());
- //m_log.DebugFormat("The otherHull is:\n{1}", 0, otherHullClone.ToString());
-
- {
- int iBase, iOther;
-
- // Insert into baseHull
- for (iBase = 0; iBase < baseHullClone.vertices.Count; iBase++)
- {
- int iBaseNext = (iBase + 1)%baseHullClone.vertices.Count;
- Simplex sBase = new Simplex(baseHullClone.vertices[iBase], baseHullClone.vertices[iBaseNext]);
-
- for (iOther = 0; iOther < otherHullClone.vertices.Count; iOther++)
- {
- int iOtherNext = (iOther + 1)%otherHullClone.vertices.Count;
- Simplex sOther =
- new Simplex(otherHullClone.vertices[iOther], otherHullClone.vertices[iOtherNext]);
-
- PhysicsVector intersect = Simplex.Intersect(sBase, sOther, 0.001f, -.001f, 0.999f, 1.001f);
- if (intersect != null)
- {
- Vertex vIntersect = new Vertex(intersect);
- baseHullClone.vertices.Insert(iBase + 1, vIntersect);
- sBase.v2 = vIntersect;
- intersects = true;
- }
- }
- }
- }
-
- //m_log.Debug("State after intersection detection for the base hull");
- //m_log.DebugFormat("The baseHull is:\n{1}", 0, baseHullClone.ToString());
-
- {
- int iOther, iBase;
-
- // Insert into otherHull
- for (iOther = 0; iOther < otherHullClone.vertices.Count; iOther++)
- {
- int iOtherNext = (iOther + 1)%otherHullClone.vertices.Count;
- Simplex sOther = new Simplex(otherHullClone.vertices[iOther], otherHullClone.vertices[iOtherNext]);
-
- for (iBase = 0; iBase < baseHullClone.vertices.Count; iBase++)
- {
- int iBaseNext = (iBase + 1)%baseHullClone.vertices.Count;
- Simplex sBase = new Simplex(baseHullClone.vertices[iBase], baseHullClone.vertices[iBaseNext]);
-
- PhysicsVector intersect = Simplex.Intersect(sBase, sOther, -.001f, 0.001f, 1.001f, 0.999f);
- if (intersect != null)
- {
- Vertex vIntersect = new Vertex(intersect);
- otherHullClone.vertices.Insert(iOther + 1, vIntersect);
- sOther.v2 = vIntersect;
- intersects = true;
- }
- }
- }
- }
-
- //m_log.Debug("State after intersection detection for the base hull");
- //m_log.DebugFormat("The otherHull is:\n{1}", 0, otherHullClone.ToString());
-
- bool otherIsInBase = baseHullClone.containsPointsFrom(otherHullClone);
- if (!intersects && otherIsInBase)
- {
- // We have a hole here
- baseHullClone.holeVertices = otherHullClone.vertices;
- return baseHullClone;
- }
-
- SimpleHull result = new SimpleHull();
-
- // Find a good starting Simplex from baseHull
- // A good starting simplex is one that is outside otherHull
- // Such a simplex must exist, otherwise the result will be empty
- Vertex baseStartVertex = null;
- {
- int iBase;
- for (iBase = 0; iBase < baseHullClone.vertices.Count; iBase++)
- {
- int iBaseNext = (iBase + 1)%baseHullClone.vertices.Count;
- Vertex center = new Vertex((baseHullClone.vertices[iBase] + baseHullClone.vertices[iBaseNext])/2.0f);
- bool isOutside = !otherHullClone.IsPointIn(center);
- if (isOutside)
- {
- baseStartVertex = baseHullClone.vertices[iBaseNext];
- break;
- }
- }
- }
-
-
- if (baseStartVertex == null) // i.e. no simplex fulfilled the "outside" condition.
- // In otherwords, subtractHull completely embraces baseHull
- {
- return result;
- }
-
- // The simplex that *starts* with baseStartVertex is outside the cutting hull,
- // so we can start our walk with the next vertex without loosing a branch
- Vertex V1 = baseStartVertex;
- bool onBase = true;
-
- // And here is how we do the magic :-)
- // Start on the base hull.
- // Walk the vertices in the positive direction
- // For each vertex check, whether it is a vertex shared with the other hull
- // if this is the case, switch over to walking the other vertex list.
- // Note: The other hull *must* go backwards to our starting point (via several orther vertices)
- // Thus it is important that the cutting hull has the inverse directional sense than the
- // base hull!!!!!!!!! (means if base goes CW around it's center cutting hull must go CCW)
-
- bool done = false;
- while (!done)
- {
- result.AddVertex(V1);
- Vertex nextVertex = null;
- if (onBase)
- {
- nextVertex = otherHullClone.FindVertex(V1, 0.001f);
- }
- else
- {
- nextVertex = baseHullClone.FindVertex(V1, 0.001f);
- }
-
- if (nextVertex != null) // A node that represents an intersection
- {
- V1 = nextVertex; // Needed to find the next vertex on the other hull
- onBase = !onBase;
- }
-
- if (onBase)
- V1 = baseHullClone.getNextVertex(V1);
- else
- V1 = otherHullClone.getNextVertex(V1);
-
- if (V1 == baseStartVertex)
- done = true;
- }
-
- //m_log.DebugFormat("The resulting Hull is:\n{1}", 0, result.ToString());
-
- return result;
- }
- }
-}
diff --git a/OpenSim/Region/Physics/Meshing/Simplex.cs b/OpenSim/Region/Physics/Meshing/Simplex.cs
deleted file mode 100644
index aeeef11b46..0000000000
--- a/OpenSim/Region/Physics/Meshing/Simplex.cs
+++ /dev/null
@@ -1,220 +0,0 @@
-/*
- * 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 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 v1 + lambda*simplexDirection;
- }
- }
-}