* 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.
0.6.0-stable
Teravus Ovares 2008-06-15 19:34:48 +00:00
parent 3d8d713128
commit 11d68ce0f5
2 changed files with 296 additions and 88 deletions

View File

@ -63,6 +63,11 @@ namespace OpenSim.Region.Physics.Meshing
public float pathTaperX = 0.0f; public float pathTaperX = 0.0f;
public float pathTaperY = 0.0f; public float pathTaperY = 0.0f;
/// <summary>
/// (deprecated) creates a 3 layer extruded mesh of a profile hull
/// </summary>
/// <param name="m"></param>
/// <returns></returns>
public Mesh Extrude(Mesh m) public Mesh Extrude(Mesh m)
{ {
startParameter = float.MinValue; startParameter = float.MinValue;
@ -245,6 +250,193 @@ namespace OpenSim.Region.Physics.Meshing
return result; return result;
} }
/// <summary>
/// Creates an extrusion of a profile along a linear path. Used to create prim types box, cylinder, and prism.
/// </summary>
/// <param name="m"></param>
/// <returns>A mesh of the extruded shape</returns>
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;
}
/// <summary>
/// Extrudes a shape around a circular path. Used to create prim types torus, ring, and tube.
/// </summary>
/// <param name="m"></param>
/// <returns>a mesh of the extruded shape</returns>
public Mesh ExtrudeCircularPath(Mesh m) public Mesh ExtrudeCircularPath(Mesh m)
{ {
Mesh result = new Mesh(); Mesh result = new Mesh();

View File

@ -57,8 +57,11 @@ namespace OpenSim.Region.Physics.Meshing
// Setting baseDir to a path will enable the dumping of raw files // 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 // 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"; private const string baseDir = null; //"rawFiles";
#endif
private const float DEG_TO_RAD = 0.01745329238f; private const float DEG_TO_RAD = 0.01745329238f;
// TODO: unused // TODO: unused
@ -613,42 +616,46 @@ namespace OpenSim.Region.Physics.Meshing
} }
} }
if (twistTop != 0) //if (twistTop != 0)
{ //{
extr.twistTop = 180 * ((float)twistTop / 100); // extr.twistTop = 180 * ((float)twistTop / 100);
if (extr.twistTop > 0) // if (extr.twistTop > 0)
{ // {
extr.twistTop = 360 - (-1 * extr.twistTop); // 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) //if (twistMid != 0)
{ //{
extr.twistMid = 180 * ((float)twistMid / 100); // extr.twistMid = 180 * ((float)twistMid / 100);
if (extr.twistMid > 0) // if (extr.twistMid > 0)
{ // {
extr.twistMid = 360 - (-1 * extr.twistMid); // extr.twistMid = 360 - (-1 * extr.twistMid);
} // }
extr.twistMid = (float)(extr.twistMid * DEG_TO_RAD); // extr.twistMid = (float)(extr.twistMid * DEG_TO_RAD);
} //}
if (twistBot != 0) //if (twistBot != 0)
{ //{
extr.twistBot = 180 * ((float)twistBot / 100); // extr.twistBot = 180 * ((float)twistBot / 100);
if (extr.twistBot > 0) // if (extr.twistBot > 0)
{ // {
extr.twistBot = 360 - (-1 * extr.twistBot); // extr.twistBot = 360 - (-1 * extr.twistBot);
} // }
extr.twistBot = (float)(extr.twistBot * DEG_TO_RAD); // 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;
//Mesh result = extr.Extrude(m);
Mesh result = extr.ExtrudeLinearPath(m);
result.DumpRaw(baseDir, primName, "Z extruded"); result.DumpRaw(baseDir, primName, "Z extruded");
return result; return result;
} }
@ -953,43 +960,47 @@ namespace OpenSim.Region.Physics.Meshing
} }
if (twistTop != 0) //if (twistTop != 0)
{ //{
extr.twistTop = 180 * ((float)twistTop / 100); // extr.twistTop = 180 * ((float)twistTop / 100);
if (extr.twistTop > 0) // if (extr.twistTop > 0)
{ // {
extr.twistTop = 360 - (-1 * extr.twistTop); // 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) //if (twistMid != 0)
{ //{
extr.twistMid = 180 * ((float)twistMid / 100); // extr.twistMid = 180 * ((float)twistMid / 100);
if (extr.twistMid > 0) // if (extr.twistMid > 0)
{ // {
extr.twistMid = 360 - (-1 * extr.twistMid); // extr.twistMid = 360 - (-1 * extr.twistMid);
} // }
extr.twistMid = (float)(extr.twistMid * DEG_TO_RAD); // extr.twistMid = (float)(extr.twistMid * DEG_TO_RAD);
} //}
if (twistBot != 0) //if (twistBot != 0)
{ //{
extr.twistBot = 180 * ((float)twistBot / 100); // extr.twistBot = 180 * ((float)twistBot / 100);
if (extr.twistBot > 0) // if (extr.twistBot > 0)
{ // {
extr.twistBot = 360 - (-1 * extr.twistBot); // extr.twistBot = 360 - (-1 * extr.twistBot);
} // }
extr.twistBot = (float)(extr.twistBot * DEG_TO_RAD); // 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()); //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"); result.DumpRaw(baseDir, primName, "Z extruded");
return result; return result;
} }
@ -1185,42 +1196,47 @@ namespace OpenSim.Region.Physics.Meshing
} }
} }
if (twistTop != 0) //if (twistTop != 0)
{ //{
extr.twistTop = 180 * ((float)twistTop / 100); // extr.twistTop = 180 * ((float)twistTop / 100);
if (extr.twistTop > 0) // if (extr.twistTop > 0)
{ // {
extr.twistTop = 360 - (-1 * extr.twistTop); // 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) //if (twistMid != 0)
{ //{
extr.twistMid = 180 * ((float)twistMid / 100); // extr.twistMid = 180 * ((float)twistMid / 100);
if (extr.twistMid > 0) // if (extr.twistMid > 0)
{ // {
extr.twistMid = 360 - (-1 * extr.twistMid); // extr.twistMid = 360 - (-1 * extr.twistMid);
} // }
extr.twistMid = (float)(extr.twistMid * DEG_TO_RAD); // extr.twistMid = (float)(extr.twistMid * DEG_TO_RAD);
} //}
if (twistBot != 0) //if (twistBot != 0)
{ //{
extr.twistBot = 180 * ((float)twistBot / 100); // extr.twistBot = 180 * ((float)twistBot / 100);
if (extr.twistBot > 0) // if (extr.twistBot > 0)
{ // {
extr.twistBot = 360 - (-1 * extr.twistBot); // extr.twistBot = 360 - (-1 * extr.twistBot);
} // }
extr.twistBot = (float)(extr.twistBot * DEG_TO_RAD); // 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"); result.DumpRaw(baseDir, primName, "Z extruded");
return result; return result;
} }