From 11d68ce0f5d84188d468004b918824feb6c57f0b Mon Sep 17 00:00:00 2001
From: Teravus Ovares
Date: Sun, 15 Jun 2008 19:34:48 +0000
Subject: * 0001558: [PATCH] Add support for full collision geometry feature
set for linear path prims (patch attached) By Dahlia. Thanks Dahlia! * This
update re-does the cube/cylinder/prism prims to dynamically add faces as
twist is used.
---
OpenSim/Region/Physics/Meshing/Extruder.cs | 192 ++++++++++++++++++++++++++
OpenSim/Region/Physics/Meshing/Meshmerizer.cs | 192 ++++++++++++++------------
2 files changed, 296 insertions(+), 88 deletions(-)
(limited to 'OpenSim/Region/Physics')
diff --git a/OpenSim/Region/Physics/Meshing/Extruder.cs b/OpenSim/Region/Physics/Meshing/Extruder.cs
index 880a23a..baa2d9b 100644
--- a/OpenSim/Region/Physics/Meshing/Extruder.cs
+++ b/OpenSim/Region/Physics/Meshing/Extruder.cs
@@ -63,6 +63,11 @@ namespace OpenSim.Region.Physics.Meshing
public float pathTaperX = 0.0f;
public float pathTaperY = 0.0f;
+ ///
+ /// (deprecated) creates a 3 layer extruded mesh of a profile hull
+ ///
+ ///
+ ///
public Mesh Extrude(Mesh m)
{
startParameter = float.MinValue;
@@ -245,6 +250,193 @@ namespace OpenSim.Region.Physics.Meshing
return result;
}
+ ///
+ /// 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();
+
+ Quaternion tt = new Quaternion();
+ Vertex v2 = new Vertex(0, 0, 0);
+
+ 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;
+ 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 = new Quaternion(new Vertex(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;
+ }
+ 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();
diff --git a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs
index 0c62447..9afc7ae 100644
--- a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs
+++ b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs
@@ -57,8 +57,11 @@ namespace OpenSim.Region.Physics.Meshing
// Setting baseDir to a path will enable the dumping of raw files
// raw files can be imported by blender so a visual inspection of the results can be done
- // const string baseDir = "rawFiles";
+#if SPAM
+ const string baseDir = "rawFiles";
+#else
private const string baseDir = null; //"rawFiles";
+#endif
private const float DEG_TO_RAD = 0.01745329238f;
// TODO: unused
@@ -613,42 +616,46 @@ namespace OpenSim.Region.Physics.Meshing
}
}
- if (twistTop != 0)
- {
- extr.twistTop = 180 * ((float)twistTop / 100);
- if (extr.twistTop > 0)
- {
- extr.twistTop = 360 - (-1 * extr.twistTop);
+ //if (twistTop != 0)
+ //{
+ // extr.twistTop = 180 * ((float)twistTop / 100);
+ // if (extr.twistTop > 0)
+ // {
+ // extr.twistTop = 360 - (-1 * extr.twistTop);
- }
+ // }
- extr.twistTop = (float)(extr.twistTop * DEG_TO_RAD);
- }
+ // extr.twistTop = (float)(extr.twistTop * DEG_TO_RAD);
+ //}
- float twistMid = ((twistTop + twistBot) * 0.5f);
+ //float twistMid = ((twistTop + twistBot) * 0.5f);
- if (twistMid != 0)
- {
- extr.twistMid = 180 * ((float)twistMid / 100);
- if (extr.twistMid > 0)
- {
- extr.twistMid = 360 - (-1 * extr.twistMid);
- }
- extr.twistMid = (float)(extr.twistMid * DEG_TO_RAD);
- }
+ //if (twistMid != 0)
+ //{
+ // extr.twistMid = 180 * ((float)twistMid / 100);
+ // if (extr.twistMid > 0)
+ // {
+ // extr.twistMid = 360 - (-1 * extr.twistMid);
+ // }
+ // extr.twistMid = (float)(extr.twistMid * DEG_TO_RAD);
+ //}
- if (twistBot != 0)
- {
- extr.twistBot = 180 * ((float)twistBot / 100);
- if (extr.twistBot > 0)
- {
- extr.twistBot = 360 - (-1 * extr.twistBot);
- }
- extr.twistBot = (float)(extr.twistBot * DEG_TO_RAD);
- }
+ //if (twistBot != 0)
+ //{
+ // extr.twistBot = 180 * ((float)twistBot / 100);
+ // if (extr.twistBot > 0)
+ // {
+ // extr.twistBot = 360 - (-1 * extr.twistBot);
+ // }
+ // extr.twistBot = (float)(extr.twistBot * DEG_TO_RAD);
+ //}
+
+ extr.twistTop = (float)primShape.PathTwist * (float)Math.PI * 0.01f;
+ extr.twistBot = (float)primShape.PathTwistBegin * (float)Math.PI * 0.01f;
- Mesh result = extr.Extrude(m);
+ //Mesh result = extr.Extrude(m);
+ Mesh result = extr.ExtrudeLinearPath(m);
result.DumpRaw(baseDir, primName, "Z extruded");
return result;
}
@@ -953,43 +960,47 @@ namespace OpenSim.Region.Physics.Meshing
}
- if (twistTop != 0)
- {
- extr.twistTop = 180 * ((float)twistTop / 100);
- if (extr.twistTop > 0)
- {
- extr.twistTop = 360 - (-1 * extr.twistTop);
+ //if (twistTop != 0)
+ //{
+ // extr.twistTop = 180 * ((float)twistTop / 100);
+ // if (extr.twistTop > 0)
+ // {
+ // extr.twistTop = 360 - (-1 * extr.twistTop);
- }
+ // }
- extr.twistTop = (float)(extr.twistTop * DEG_TO_RAD);
- }
+ // extr.twistTop = (float)(extr.twistTop * DEG_TO_RAD);
+ //}
- float twistMid = ((twistTop + twistBot) * 0.5f);
+ //float twistMid = ((twistTop + twistBot) * 0.5f);
- if (twistMid != 0)
- {
- extr.twistMid = 180 * ((float)twistMid / 100);
- if (extr.twistMid > 0)
- {
- extr.twistMid = 360 - (-1 * extr.twistMid);
- }
- extr.twistMid = (float)(extr.twistMid * DEG_TO_RAD);
- }
+ //if (twistMid != 0)
+ //{
+ // extr.twistMid = 180 * ((float)twistMid / 100);
+ // if (extr.twistMid > 0)
+ // {
+ // extr.twistMid = 360 - (-1 * extr.twistMid);
+ // }
+ // extr.twistMid = (float)(extr.twistMid * DEG_TO_RAD);
+ //}
- if (twistBot != 0)
- {
- extr.twistBot = 180 * ((float)twistBot / 100);
- if (extr.twistBot > 0)
- {
- extr.twistBot = 360 - (-1 * extr.twistBot);
- }
- extr.twistBot = (float)(extr.twistBot * DEG_TO_RAD);
- }
+ //if (twistBot != 0)
+ //{
+ // extr.twistBot = 180 * ((float)twistBot / 100);
+ // if (extr.twistBot > 0)
+ // {
+ // extr.twistBot = 360 - (-1 * extr.twistBot);
+ // }
+ // extr.twistBot = (float)(extr.twistBot * DEG_TO_RAD);
+ //}
+ extr.twistTop = (float)primShape.PathTwist * (float)Math.PI * 0.01f;
+ extr.twistBot = (float)primShape.PathTwistBegin * (float)Math.PI * 0.01f;
+
//System.Console.WriteLine("[MESH]: twistTop = " + twistTop.ToString() + "|" + extr.twistTop.ToString() + ", twistMid = " + twistMid.ToString() + "|" + extr.twistMid.ToString() + ", twistbot = " + twistBot.ToString() + "|" + extr.twistBot.ToString());
- Mesh result = extr.Extrude(m);
+ //Mesh result = extr.Extrude(m);
+ Mesh result = extr.ExtrudeLinearPath(m);
result.DumpRaw(baseDir, primName, "Z extruded");
return result;
}
@@ -1185,42 +1196,47 @@ namespace OpenSim.Region.Physics.Meshing
}
}
- if (twistTop != 0)
- {
- extr.twistTop = 180 * ((float)twistTop / 100);
- if (extr.twistTop > 0)
- {
- extr.twistTop = 360 - (-1 * extr.twistTop);
+ //if (twistTop != 0)
+ //{
+ // extr.twistTop = 180 * ((float)twistTop / 100);
+ // if (extr.twistTop > 0)
+ // {
+ // extr.twistTop = 360 - (-1 * extr.twistTop);
- }
+ // }
- extr.twistTop = (float)(extr.twistTop * DEG_TO_RAD);
- }
+ // extr.twistTop = (float)(extr.twistTop * DEG_TO_RAD);
+ //}
- float twistMid = ((twistTop + twistBot) * 0.5f);
+ //float twistMid = ((twistTop + twistBot) * 0.5f);
- if (twistMid != 0)
- {
- extr.twistMid = 180 * ((float)twistMid / 100);
- if (extr.twistMid > 0)
- {
- extr.twistMid = 360 - (-1 * extr.twistMid);
- }
- extr.twistMid = (float)(extr.twistMid * DEG_TO_RAD);
- }
+ //if (twistMid != 0)
+ //{
+ // extr.twistMid = 180 * ((float)twistMid / 100);
+ // if (extr.twistMid > 0)
+ // {
+ // extr.twistMid = 360 - (-1 * extr.twistMid);
+ // }
+ // extr.twistMid = (float)(extr.twistMid * DEG_TO_RAD);
+ //}
- if (twistBot != 0)
- {
- extr.twistBot = 180 * ((float)twistBot / 100);
- if (extr.twistBot > 0)
- {
- extr.twistBot = 360 - (-1 * extr.twistBot);
- }
- extr.twistBot = (float)(extr.twistBot * DEG_TO_RAD);
- }
+ //if (twistBot != 0)
+ //{
+ // extr.twistBot = 180 * ((float)twistBot / 100);
+ // if (extr.twistBot > 0)
+ // {
+ // extr.twistBot = 360 - (-1 * extr.twistBot);
+ // }
+ // extr.twistBot = (float)(extr.twistBot * DEG_TO_RAD);
+ //}
- Mesh result = extr.Extrude(m);
+ extr.twistTop = (float)primShape.PathTwist * (float)Math.PI * 0.01f;
+ extr.twistBot = (float)primShape.PathTwistBegin * (float)Math.PI * 0.01f;
+
+ //System.Console.WriteLine("[MESH]: twistTop = " + twistTop.ToString() + "|" + extr.twistTop.ToString() + ", twistMid = " + twistMid.ToString() + "|" + extr.twistMid.ToString() + ", twistbot = " + twistBot.ToString() + "|" + extr.twistBot.ToString());
+ //Mesh result = extr.Extrude(m);
+ Mesh result = extr.ExtrudeLinearPath(m);
result.DumpRaw(baseDir, primName, "Z extruded");
return result;
}
--
cgit v1.1