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/Meshing') 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