* 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
parent
3d8d713128
commit
11d68ce0f5
|
@ -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();
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue